sigma_rb 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +68 -6
- data/lib/sigma/address.rb +64 -2
- data/lib/sigma/block_header.rb +49 -1
- data/lib/sigma/box_selection.rb +29 -0
- data/lib/sigma/byte_array.rb +22 -0
- data/lib/sigma/constant.rb +43 -14
- data/lib/sigma/context_extension.rb +10 -0
- data/lib/sigma/contract.rb +21 -2
- data/lib/sigma/data_input.rb +24 -0
- data/lib/sigma/enums.rb +8 -0
- data/lib/sigma/ergo_box.rb +171 -2
- data/lib/sigma/ergo_box_candidate_builder.rb +45 -1
- data/lib/sigma/ergo_state_context.rb +8 -0
- data/lib/sigma/ergo_tree.rb +38 -2
- data/lib/sigma/input.rb +57 -1
- data/lib/sigma/merkle_proof.rb +7 -1
- data/lib/sigma/nipopow.rb +29 -0
- data/lib/sigma/pre_header.rb +7 -0
- data/lib/sigma/reduced_transaction.rb +25 -0
- data/lib/sigma/secret_key.rb +29 -1
- data/lib/sigma/structs.rb +10 -0
- data/lib/sigma/token.rb +61 -1
- data/lib/sigma/transaction.rb +105 -0
- data/lib/sigma/tx_builder.rb +32 -0
- data/lib/sigma/wallet.rb +39 -0
- data/sigma.gemspec +3 -2
- data/tests/sigma/ergo_tree_test.rb +3 -1
- data/tests/sigma/merkle_proof_test.rb +1 -1
- data/tests/sigma/nipopow_test.rb +1 -0
- data/tests/test_seeds.rb +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3900571641a51eca478e3ab63bad7ff89be2f71b9dcbd29718a969203f4edec
|
4
|
+
data.tar.gz: 269840887d7914e8a22ea0127a70456956851d9afc7078d7a38c6a33e712d40d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6d5b264166b3fdff4d72560ddc80c2908e33de7d27b2780b7d07943eea78ac11c434914aa5ab5001fbe781bfc85cce45e37bac9824405c957a52bca836b485e
|
7
|
+
data.tar.gz: 421c9a38cc1bcf2852e99d7d4e4f0c0a6c5886c5a6c101fc8e7779bc965f8d210c940e29a1fa9c801df963cd56962acc54f32577e8e009fc459f9f28e43830b5
|
data/README.md
CHANGED
@@ -1,9 +1,71 @@
|
|
1
1
|
# sigma_rb
|
2
|
-
Ruby bindings for https://github.com/ergoplatform/sigma-rust
|
2
|
+
Ruby wrapper around C bindings for ErgoLib from [Sigma-Rust](https://github.com/ergoplatform/sigma-rust)
|
3
3
|
|
4
|
+
# Installation
|
5
|
+
This project wraps the C bindings of Sigma-Rust and so they are required for using this gem. As the Sigma-Rust API changes over time, gem versions are tied to specific Sigma-Rust versions.
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
| Sigma_rb Version | Sigma-Rust Version |
|
8
|
+
| ---------------- | -------------------|
|
9
|
+
| 0.1.3 | 0.16.0 |
|
10
|
+
|
11
|
+
|
12
|
+
## Build ErgoLib Dependencies
|
13
|
+
Checkout the supported Sigma-Rust version on the [releases](https://github.com/ergoplatform/sigma-rust/releases) page .
|
14
|
+
|
15
|
+
### Build the ergo-lib-c bindings
|
16
|
+
I will provide instructions below but it may be worth reading over the [directions in Sigma-Rust too](https://github.com/ergoplatform/sigma-rust/tree/develop/bindings/ergo-lib-c)
|
17
|
+
|
18
|
+
Sigma-Rust uses Rust to generate these C bindings and so you will need Rust. I recommend downloading the nightly version of Rust as you will need nightly Rust for the next step.
|
19
|
+
|
20
|
+
After checking out the proper Sigma-Rust and starting at it's root directory:
|
21
|
+
```
|
22
|
+
cd bindings/ergo-lib-c
|
23
|
+
cargo build --release -p ergo-lib-c
|
24
|
+
```
|
25
|
+
|
26
|
+
This will build a release version of `libergo.a` located at `target/release/libergo.a` from the root directory. You will need to copy/move this to a C LIBRARY search path on your system. For my system I can use `/usr/local/lib` . This usually depends on OS.
|
27
|
+
|
28
|
+
So I did this to copy `libergo.a` to `/usr/local/lib` :
|
29
|
+
```
|
30
|
+
sudo cp ../../target/release/libergo.a /usr/local/lib/
|
31
|
+
```
|
32
|
+
|
33
|
+
### Build ergo-lib-c header file
|
34
|
+
While still in the `bindings/ergo-lib_c` directory you can generate the header file with:
|
35
|
+
```
|
36
|
+
cbindgen --config cbindgen.toml --crate ergo-lib-c --output h/ergo_lib.h
|
37
|
+
```
|
38
|
+
|
39
|
+
You will need to copy/move this header to a C INCLUDE search path. On my system I can use `/usr/local/include` . So I ran the following command to copy the header:
|
40
|
+
```
|
41
|
+
sudo cp h/ergo_lib.h /usr/local/include/
|
42
|
+
```
|
43
|
+
|
44
|
+
## Add to Gemfile
|
45
|
+
Once you have `libergo.a` and `ergo_lib.h` downloaded and placed in locations your C compiler can find you should be able to to install the gem.
|
46
|
+
|
47
|
+
In Gemfile
|
48
|
+
```
|
49
|
+
gem 'sigma_rb', '0.1.3'
|
50
|
+
```
|
51
|
+
|
52
|
+
Run bundle to install
|
53
|
+
```
|
54
|
+
bundle
|
55
|
+
```
|
56
|
+
|
57
|
+
After a successful install you can use it by requiring `sigma`
|
58
|
+
```
|
59
|
+
require 'sigma'
|
60
|
+
|
61
|
+
puts Sigma::BoxValue.units_per_ergo
|
62
|
+
```
|
63
|
+
|
64
|
+
# Examples
|
65
|
+
Check out `tests/sigma` for usage examples. The transaction tests are probably the most involved, located at [tests/sigma/transaction_test.rb](https://github.com/thedlop/sigma_rb/blob/master/tests/sigma/transaction_test.rb).
|
66
|
+
|
67
|
+
# Documentation
|
68
|
+
Generated documentation can be viewed on [RubyDoc](https://www.rubydoc.info/gems/sigma_rb).
|
69
|
+
|
70
|
+
# Thank You
|
71
|
+
Thank you to the Ergo Development community for consistent words of encouragement. Big thanks to Sigma-Rust maintainers for providing the C bindings which made this possible. Thank you to the iOS bindings developers as it was a constant reference for this work.
|
data/lib/sigma/address.rb
CHANGED
@@ -3,6 +3,48 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
#
|
7
|
+
# An address is a short string corresponding to some script used to protect a box. Unlike (string-encoded) binary
|
8
|
+
# representation of a script, an address has some useful characteristics:
|
9
|
+
#
|
10
|
+
# - Integrity of an address could be checked., as it is incorporating a checksum.
|
11
|
+
# - A prefix of address is showing network and an address type.
|
12
|
+
# - An address is using an encoding (namely, Base58) which is avoiding similarly l0Oking characters, friendly to
|
13
|
+
# double-clicking and line-breaking in emails.
|
14
|
+
#
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# An address is encoding network type, address type, checksum, and enough information to watch for a particular scripts.
|
18
|
+
#
|
19
|
+
# Possible network types are:
|
20
|
+
# Mainnet - 0x00
|
21
|
+
# Testnet - 0x10
|
22
|
+
#
|
23
|
+
# For an address type, we form content bytes as follows:
|
24
|
+
#
|
25
|
+
# P2PK - serialized (compressed) public key
|
26
|
+
# P2SH - first 192 bits of the Blake2b256 hash of serialized script bytes
|
27
|
+
# P2S - serialized script
|
28
|
+
#
|
29
|
+
# Address examples for testnet:
|
30
|
+
# 3 - P2PK (3WvsT2Gm4EpsM9Pg18PdY6XyhNNMqXDsvJTbbf6ihLvAmSb7u5RN)
|
31
|
+
# ? - P2SH (rbcrmKEYduUvADj9Ts3dSVSG27h54pgrq5fPuwB)
|
32
|
+
# ? - P2S (Ms7smJwLGbUAjuWQ)
|
33
|
+
#
|
34
|
+
# for mainnet:
|
35
|
+
#
|
36
|
+
# 9 - P2PK (9fRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vA)
|
37
|
+
# ? - P2SH (8UApt8czfFVuTgQmMwtsRBZ4nfWquNiSwCWUjMg)
|
38
|
+
# ? - P2S (4MQyML64GnzMxZgm, BxKBaHkvrTvLZrDcZjcsxsF7aSsrN73ijeFZXtbj4CXZHHcvBtqSxQ)
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# Prefix byte = network type + address type
|
42
|
+
#
|
43
|
+
# checksum = blake2b256(prefix byte ++ content bytes)
|
44
|
+
#
|
45
|
+
# address = prefix byte ++ content bytes ++ checksum
|
46
|
+
#
|
47
|
+
#
|
6
48
|
class Address
|
7
49
|
extend FFI::Library
|
8
50
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -15,10 +57,17 @@ module Sigma
|
|
15
57
|
attach_function :ergo_lib_address_type_prefix, [:pointer], :uint8
|
16
58
|
attr_accessor :pointer
|
17
59
|
|
18
|
-
|
19
|
-
|
60
|
+
# Takes ownership of an existing Address Pointer.
|
61
|
+
# @note A user of sigma_rb generally does not need to call this function
|
62
|
+
# @param pointer [FFI::MemoryPointer]
|
63
|
+
# @return [Address]
|
64
|
+
def self.with_raw_pointer(pointer)
|
65
|
+
init(pointer)
|
20
66
|
end
|
21
67
|
|
68
|
+
# Decode (base58) testnet address from string and create Address, checking that address is from the testnet
|
69
|
+
# @param address_str [String]
|
70
|
+
# @return [Address]
|
22
71
|
def self.with_testnet_address(address_str)
|
23
72
|
pointer = FFI::MemoryPointer.new(:pointer)
|
24
73
|
error = ergo_lib_address_from_testnet(address_str, pointer)
|
@@ -27,6 +76,9 @@ module Sigma
|
|
27
76
|
init(pointer)
|
28
77
|
end
|
29
78
|
|
79
|
+
# Decode (base58) mainnet address from string and create Address, checking that address is from the testnet
|
80
|
+
# @param address_str [String]
|
81
|
+
# @return [Address]
|
30
82
|
def self.with_mainnet_address(address_str)
|
31
83
|
pointer = FFI::MemoryPointer.new(:pointer)
|
32
84
|
error = ergo_lib_address_from_mainnet(address_str, pointer)
|
@@ -35,6 +87,9 @@ module Sigma
|
|
35
87
|
init(pointer)
|
36
88
|
end
|
37
89
|
|
90
|
+
# Decode (base58) address from string and create Address, no checking of network prefix
|
91
|
+
# @param address_str [String]
|
92
|
+
# @return [Address]
|
38
93
|
def self.with_base58_address(address_str)
|
39
94
|
pointer = FFI::MemoryPointer.new(:pointer)
|
40
95
|
error = ergo_lib_address_from_base58(address_str, pointer)
|
@@ -43,6 +98,10 @@ module Sigma
|
|
43
98
|
init(pointer)
|
44
99
|
end
|
45
100
|
|
101
|
+
# Encode Address to a base58 string
|
102
|
+
# @see Sigma::NETWORK_PREFIX_ENUM
|
103
|
+
# @param network_prefix [Integer]
|
104
|
+
# @return [String]
|
46
105
|
def to_base58(network_prefix)
|
47
106
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
48
107
|
pointer = FFI::MemoryPointer.new(:pointer)
|
@@ -53,6 +112,9 @@ module Sigma
|
|
53
112
|
str
|
54
113
|
end
|
55
114
|
|
115
|
+
# Get the Network Prefix type of Address
|
116
|
+
# @see Sigma::NETWORK_PREFIX_ENUM
|
117
|
+
# @return [Integer]
|
56
118
|
def type_prefix
|
57
119
|
ergo_lib_address_type_prefix(self.pointer)
|
58
120
|
end
|
data/lib/sigma/block_header.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Represents data available of the Block Header in Sigma propositions.
|
6
7
|
class BlockHeader
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -12,6 +13,9 @@ module Sigma
|
|
12
13
|
attach_function :ergo_lib_block_header_eq, [:pointer, :pointer], :bool
|
13
14
|
attr_accessor :pointer
|
14
15
|
|
16
|
+
# Parse BlockHeader array from json (NODE API)
|
17
|
+
# @param json [String]
|
18
|
+
# @return [BlockHeader]
|
15
19
|
def self.with_json(json)
|
16
20
|
pointer = FFI::MemoryPointer.new(:pointer)
|
17
21
|
error = ergo_lib_block_header_from_json(json, pointer)
|
@@ -19,16 +23,25 @@ module Sigma
|
|
19
23
|
init(pointer)
|
20
24
|
end
|
21
25
|
|
26
|
+
# Takes ownership of an existing BlockHeader Pointer.
|
27
|
+
# @note A user of sigma_rb generally does not need to call this function
|
28
|
+
# @param pointer [FFI::MemoryPointer]
|
29
|
+
# @return [BlockHeader]
|
22
30
|
def self.with_raw_pointer(pointer)
|
23
31
|
init(pointer)
|
24
32
|
end
|
25
33
|
|
34
|
+
# Get BlockId of BlockHeader
|
35
|
+
# @return [BlockId]
|
26
36
|
def get_block_id
|
27
37
|
pointer = FFI::MemoryPointer.new(:pointer)
|
28
38
|
ergo_lib_block_header_id(self.pointer, pointer)
|
29
39
|
Sigma::BlockId.with_raw_pointer(:pointer)
|
30
40
|
end
|
31
41
|
|
42
|
+
# Equality check between two BlockHeaders
|
43
|
+
# @param bh_two [BlockHeader]
|
44
|
+
# @return [bool]
|
32
45
|
def ==(bh_two)
|
33
46
|
ergo_lib_block_header_eq(self.pointer, bh_two.pointer)
|
34
47
|
end
|
@@ -47,6 +60,7 @@ module Sigma
|
|
47
60
|
end
|
48
61
|
end
|
49
62
|
|
63
|
+
# An ordered collection of BlockHeader
|
50
64
|
class BlockHeaders
|
51
65
|
extend FFI::Library
|
52
66
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -58,10 +72,16 @@ module Sigma
|
|
58
72
|
attach_function :ergo_lib_block_headers_get, [:pointer, :uint8, :pointer], ReturnOption.by_value
|
59
73
|
attr_accessor :pointer
|
60
74
|
|
75
|
+
# Takes ownership of an existing BlockHeaders Pointer.
|
76
|
+
# @note A user of sigma_rb generally does not need to call this function
|
77
|
+
# @param pointer [FFI::MemoryPointer]
|
78
|
+
# @return [BlockHeaders]
|
61
79
|
def self.with_raw_pointer(unread_pointer)
|
62
80
|
init(unread_pointer)
|
63
81
|
end
|
64
82
|
|
83
|
+
# Create an empty collection
|
84
|
+
# @return [BlockHeaders]
|
65
85
|
def self.create
|
66
86
|
pointer = FFI::MemoryPointer.new(:pointer)
|
67
87
|
ergo_lib_block_headers_new(pointer)
|
@@ -69,7 +89,9 @@ module Sigma
|
|
69
89
|
init(pointer)
|
70
90
|
end
|
71
91
|
|
72
|
-
#
|
92
|
+
# Parse BlockHeaders from array of JSON
|
93
|
+
# @param array_of_json_elements [Array<String>]
|
94
|
+
# @return [BlockHeaders]
|
73
95
|
def self.from_json(array_of_json_elements)
|
74
96
|
headers = array_of_json_elements.map do |json|
|
75
97
|
Sigma::BlockHeader.with_json(json)
|
@@ -81,14 +103,21 @@ module Sigma
|
|
81
103
|
container
|
82
104
|
end
|
83
105
|
|
106
|
+
# Get length of BlockHeaders
|
107
|
+
# @return [Integer]
|
84
108
|
def len
|
85
109
|
ergo_lib_block_headers_len(self.pointer)
|
86
110
|
end
|
87
111
|
|
112
|
+
# Add a BlockHeader
|
113
|
+
# @param block_header [BlockHeader]
|
88
114
|
def add(block_header)
|
89
115
|
ergo_lib_block_headers_add(block_header.pointer, self.pointer)
|
90
116
|
end
|
91
117
|
|
118
|
+
# Get item at specified index or return nil if no item exists
|
119
|
+
# @params index [Integer]
|
120
|
+
# @return [BlockHeader, nil]
|
92
121
|
def get(index)
|
93
122
|
pointer = FFI::MemoryPointer.new(:pointer)
|
94
123
|
res = ergo_lib_block_headers_get(self.pointer, index, pointer)
|
@@ -114,6 +143,7 @@ module Sigma
|
|
114
143
|
end
|
115
144
|
end
|
116
145
|
|
146
|
+
# Represents the Id of a BlockHeader
|
117
147
|
class BlockId
|
118
148
|
extend FFI::Library
|
119
149
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -121,6 +151,10 @@ module Sigma
|
|
121
151
|
attach_function :ergo_lib_block_id_delete, [:pointer], :void
|
122
152
|
attr_accessor :pointer
|
123
153
|
|
154
|
+
# Takes ownership of an existing BlockId Pointer.
|
155
|
+
# @note A user of sigma_rb generally does not need to call this function
|
156
|
+
# @param pointer [FFI::MemoryPointer]
|
157
|
+
# @return [BlockId]
|
124
158
|
def self.with_raw_pointer(pointer)
|
125
159
|
init(pointer)
|
126
160
|
end
|
@@ -139,6 +173,7 @@ module Sigma
|
|
139
173
|
end
|
140
174
|
end
|
141
175
|
|
176
|
+
# An ordered collection of BlockId
|
142
177
|
class BlockIds
|
143
178
|
extend FFI::Library
|
144
179
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -150,10 +185,16 @@ module Sigma
|
|
150
185
|
attach_function :ergo_lib_block_ids_get, [:pointer, :uint8, :pointer], ReturnOption.by_value
|
151
186
|
attr_accessor :pointer
|
152
187
|
|
188
|
+
# Takes ownership of an existing BlockIds Pointer.
|
189
|
+
# @note A user of sigma_rb generally does not need to call this function
|
190
|
+
# @param pointer [FFI::MemoryPointer]
|
191
|
+
# @return [BlockIds]
|
153
192
|
def self.with_raw_pointer(unread_pointer)
|
154
193
|
init(unread_pointer)
|
155
194
|
end
|
156
195
|
|
196
|
+
# Create an empty collection
|
197
|
+
# @return [BlockIds]
|
157
198
|
def self.create
|
158
199
|
pointer = FFI::MemoryPointer.new(:pointer)
|
159
200
|
ergo_lib_block_ids_new(pointer)
|
@@ -161,14 +202,21 @@ module Sigma
|
|
161
202
|
init(pointer)
|
162
203
|
end
|
163
204
|
|
205
|
+
# Get length of collection
|
206
|
+
# @return [Integer]
|
164
207
|
def len
|
165
208
|
ergo_lib_block_ids_len(self.pointer)
|
166
209
|
end
|
167
210
|
|
211
|
+
# Add to collection
|
212
|
+
# @param block_id [BlockId]
|
168
213
|
def add(block_id)
|
169
214
|
ergo_lib_block_ids_add(block_id.pointer, self.pointer)
|
170
215
|
end
|
171
216
|
|
217
|
+
# Get item at specified index or return nil if no item exists
|
218
|
+
# @param index [Integer]
|
219
|
+
# @return [BlockId, nil]
|
172
220
|
def get(index)
|
173
221
|
pointer = FFI::MemoryPointer.new(:pointer)
|
174
222
|
res = ergo_lib_block_ids_get(self.pointer, index, pointer)
|
data/lib/sigma/box_selection.rb
CHANGED
@@ -3,6 +3,8 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Selected boxes with change boxes. Instances of this class are created by SimpleBoxSelector.
|
7
|
+
# @see SimpleBoxSelector
|
6
8
|
class BoxSelection
|
7
9
|
extend FFI::Library
|
8
10
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -15,28 +17,43 @@ module Sigma
|
|
15
17
|
|
16
18
|
attr_accessor :pointer
|
17
19
|
|
20
|
+
# Create a selection to inject custom select algorithms
|
21
|
+
# @param ergo_boxes [ErgoBoxes]
|
22
|
+
# @param change_ergo_boxes [ErgoBoxAssetsDataList]
|
23
|
+
# @return [BoxSelection]
|
18
24
|
def self.create(ergo_boxes:, change_ergo_boxes:)
|
19
25
|
pointer = FFI::MemoryPointer.new(:pointer)
|
20
26
|
ergo_lib_box_selection_new(ergo_boxes.pointer, change_ergo_boxes.pointer, pointer)
|
21
27
|
init(pointer)
|
22
28
|
end
|
23
29
|
|
30
|
+
# Takes ownership of an existing BoxSelection Pointer.
|
31
|
+
# @note A user of sigma_rb generally does not need to call this function
|
32
|
+
# @param pointer [FFI::MemoryPointer]
|
33
|
+
# @return [BoxSelection]
|
24
34
|
def self.with_raw_pointer(pointer)
|
25
35
|
init(pointer)
|
26
36
|
end
|
27
37
|
|
38
|
+
# Selected Boxes to spend as transaction inputs
|
39
|
+
# @return [ErgoBoxes]
|
28
40
|
def get_boxes
|
29
41
|
pointer = FFI::MemoryPointer.new(:pointer)
|
30
42
|
ergo_lib_box_selection_boxes(self.pointer, pointer)
|
31
43
|
Sigma::ErgoBoxes.with_raw_pointer(pointer)
|
32
44
|
end
|
33
45
|
|
46
|
+
# Selected Boxes to use as change
|
47
|
+
# @return [ErgoBoxAssetsDataList]
|
34
48
|
def get_change_boxes
|
35
49
|
pointer = FFI::MemoryPointer.new(:pointer)
|
36
50
|
ergo_lib_box_selection_change(self.pointer, pointer)
|
37
51
|
Sigma::ErgoBoxAssetsDataList.with_raw_pointer(pointer)
|
38
52
|
end
|
39
53
|
|
54
|
+
# Equality check between two BoxSelections
|
55
|
+
# @param bs_two [BoxSelection]
|
56
|
+
# @return [bool]
|
40
57
|
def ==(bs_two)
|
41
58
|
ergo_lib_box_selection_eq(self.pointer, bs_two.pointer)
|
42
59
|
end
|
@@ -55,6 +72,7 @@ module Sigma
|
|
55
72
|
end
|
56
73
|
end
|
57
74
|
|
75
|
+
# Naive box selector, collects inputs until target balace is reached
|
58
76
|
class SimpleBoxSelector
|
59
77
|
extend FFI::Library
|
60
78
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -65,12 +83,19 @@ module Sigma
|
|
65
83
|
|
66
84
|
attr_accessor :pointer
|
67
85
|
|
86
|
+
# Create an empty SimpleBoxSelector
|
87
|
+
# @return [SimpleBoxSelector]
|
68
88
|
def self.create
|
69
89
|
pointer = FFI::MemoryPointer.new(:pointer)
|
70
90
|
ergo_lib_simple_box_selector_new(pointer)
|
71
91
|
init(pointer)
|
72
92
|
end
|
73
93
|
|
94
|
+
# Selects inputs to satisfy target balance and tokens
|
95
|
+
# @param inputs [ErgoBoxes] Available inputs (returns error if empty)
|
96
|
+
# @param target_balance [BoxValue] coins (in nanoERGs) needed
|
97
|
+
# @param target_tokens [Tokens] amount of tokens needed
|
98
|
+
# @return [BoxSelection] selected inputs and box assets(value + tokens) with change
|
74
99
|
def select(inputs:, target_balance:, target_tokens:)
|
75
100
|
pointer = FFI::MemoryPointer.new(:pointer)
|
76
101
|
error = ergo_lib_simple_box_selector_select(
|
@@ -84,6 +109,10 @@ module Sigma
|
|
84
109
|
Sigma::BoxSelection.with_raw_pointer(pointer)
|
85
110
|
end
|
86
111
|
|
112
|
+
# Takes ownership of an existing SimpleBoxSelector Pointer.
|
113
|
+
# @note A user of sigma_rb generally does not need to call this function
|
114
|
+
# @param pointer [FFI::MemoryPointer]
|
115
|
+
# @return [SimpleBoxSelector]
|
87
116
|
def self.with_raw_pointer(pointer)
|
88
117
|
init(pointer)
|
89
118
|
end
|
data/lib/sigma/byte_array.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Array of Bytes
|
6
7
|
class ByteArray
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -11,6 +12,9 @@ module Sigma
|
|
11
12
|
attach_function :ergo_lib_byte_array_from_raw_parts, [:pointer, :uint, :pointer], :error_pointer
|
12
13
|
attr_accessor :pointer
|
13
14
|
|
15
|
+
# Create ByteArray of Array of unsigned 8-bit ints (bytes)
|
16
|
+
# @param bytes [Array<uint8>] Array of 8-bit integers (0-255)
|
17
|
+
# @return [ByteArray]
|
14
18
|
def self.from_bytes(bytes)
|
15
19
|
pointer = FFI::MemoryPointer.new(:pointer)
|
16
20
|
b_ptr = FFI::MemoryPointer.new(:uint8, bytes.size)
|
@@ -20,6 +24,10 @@ module Sigma
|
|
20
24
|
init(pointer)
|
21
25
|
end
|
22
26
|
|
27
|
+
# Takes ownership of an existing ByteArray Pointer.
|
28
|
+
# @note A user of sigma_rb generally does not need to call this function
|
29
|
+
# @param pointer [FFI::MemoryPointer]
|
30
|
+
# @return [ByteArray]
|
23
31
|
def self.with_raw_pointer(pointer)
|
24
32
|
init(pointer)
|
25
33
|
end
|
@@ -38,6 +46,7 @@ module Sigma
|
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
49
|
+
# An ordered collection of ByteArray
|
41
50
|
class ByteArrays
|
42
51
|
extend FFI::Library
|
43
52
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -50,10 +59,16 @@ module Sigma
|
|
50
59
|
|
51
60
|
attr_accessor :pointer
|
52
61
|
|
62
|
+
# Takes ownership of an existing ByteArrays Pointer.
|
63
|
+
# @note A user of sigma_rb generally does not need to call this function
|
64
|
+
# @param pointer [FFI::MemoryPointer]
|
65
|
+
# @return [ByteArrays]
|
53
66
|
def self.with_raw_pointer(unread_pointer)
|
54
67
|
init(unread_pointer)
|
55
68
|
end
|
56
69
|
|
70
|
+
# Create an empty collection
|
71
|
+
# @return [ByteArrays]
|
57
72
|
def self.create
|
58
73
|
pointer = FFI::MemoryPointer.new(:pointer)
|
59
74
|
ergo_lib_byte_arrays_new(pointer)
|
@@ -61,14 +76,21 @@ module Sigma
|
|
61
76
|
init(pointer)
|
62
77
|
end
|
63
78
|
|
79
|
+
# Get length of collection
|
80
|
+
# @return [Integer]
|
64
81
|
def len
|
65
82
|
ergo_lib_byte_arrays_len(self.pointer)
|
66
83
|
end
|
67
84
|
|
85
|
+
# Add an item to collection
|
86
|
+
# @param byte_array [ByteArray]
|
68
87
|
def add(byte_array)
|
69
88
|
ergo_lib_byte_arrays_add(byte_array.pointer, self.pointer)
|
70
89
|
end
|
71
90
|
|
91
|
+
# Get item at specified index or return nil if no item exists
|
92
|
+
# @params index [Integer]
|
93
|
+
# @return [ByteArray, nil]
|
72
94
|
def get(index)
|
73
95
|
pointer = FFI::MemoryPointer.new(:pointer)
|
74
96
|
res = ergo_lib_byte_arrays_get(self.pointer, index, pointer)
|
data/lib/sigma/constant.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Ergo constant (evaluated) values
|
6
7
|
class Constant
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -20,6 +21,9 @@ module Sigma
|
|
20
21
|
attach_function :ergo_lib_constant_delete, [:pointer], :void
|
21
22
|
attr_accessor :pointer
|
22
23
|
|
24
|
+
# Create from ergo_box value
|
25
|
+
# @param ergo_box [ErgoBox]
|
26
|
+
# @return [Constant]
|
23
27
|
def self.with_ergo_box(ergo_box)
|
24
28
|
c_ptr = FFI::MemoryPointer.new(:pointer)
|
25
29
|
ergo_lib_constant_from_ergo_box(ergo_box.pointer, c_ptr)
|
@@ -27,6 +31,9 @@ module Sigma
|
|
27
31
|
init(c_ptr)
|
28
32
|
end
|
29
33
|
|
34
|
+
# Create from byte array
|
35
|
+
# @param bytes [Array<uint8>] Array of unsigned 8-bit (0-255) integers
|
36
|
+
# @return [Constant]
|
30
37
|
def self.with_bytes(bytes)
|
31
38
|
c_ptr = FFI::MemoryPointer.new(:pointer)
|
32
39
|
b_ptr = FFI::MemoryPointer.new(:uint8, bytes.size)
|
@@ -37,6 +44,9 @@ module Sigma
|
|
37
44
|
init(c_ptr)
|
38
45
|
end
|
39
46
|
|
47
|
+
# Parse raw EcPoint value from bytes and make ProveDlog constant
|
48
|
+
# @param bytes [Array<uint8>] Array of unsigned 8-bit (0-255) integers
|
49
|
+
# @return [Constant]
|
40
50
|
def self.with_ecpoint_bytes(bytes)
|
41
51
|
c_ptr = FFI::MemoryPointer.new(:pointer)
|
42
52
|
b_ptr = FFI::MemoryPointer.new(:uint8, bytes.size)
|
@@ -47,20 +57,9 @@ module Sigma
|
|
47
57
|
init(c_ptr)
|
48
58
|
end
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
def to_base16_string
|
55
|
-
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
56
|
-
error = ergo_lib_constant_to_base16(self.pointer, s_ptr)
|
57
|
-
Util.check_error!(error)
|
58
|
-
s_ptr = s_ptr.read_pointer()
|
59
|
-
str = s_ptr.read_string().force_encoding('UTF-8')
|
60
|
-
Util.ergo_lib_delete_string(s_ptr)
|
61
|
-
str
|
62
|
-
end
|
63
|
-
|
60
|
+
# Create from 32-bit integer
|
61
|
+
# @param int [Integer]
|
62
|
+
# @return [Constant]
|
64
63
|
def self.with_i32(int)
|
65
64
|
pointer = FFI::MemoryPointer.new(:pointer)
|
66
65
|
error = ergo_lib_constant_from_i32(int, pointer)
|
@@ -69,6 +68,9 @@ module Sigma
|
|
69
68
|
init(pointer)
|
70
69
|
end
|
71
70
|
|
71
|
+
# Create from 64-bit integer
|
72
|
+
# @param int [Integer]
|
73
|
+
# @return [Constant]
|
72
74
|
def self.with_i64(int)
|
73
75
|
pointer = FFI::MemoryPointer.new(:pointer)
|
74
76
|
error = ergo_lib_constant_from_i64(int, pointer)
|
@@ -85,18 +87,45 @@ module Sigma
|
|
85
87
|
init(c_ptr)
|
86
88
|
end
|
87
89
|
|
90
|
+
# Takes ownership of an existing Constant Pointer.
|
91
|
+
# @note A user of sigma_rb generally does not need to call this function
|
92
|
+
# @param pointer [FFI::MemoryPointer]
|
93
|
+
# @return [Constant]
|
94
|
+
def self.with_raw_pointer(constant_pointer)
|
95
|
+
init(constant_pointer)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Encode as Base16-encoded ErgoTree serialized value or throw an error if serialization failed
|
99
|
+
# @return [String] Base-16 encoded ErgoTree serialized value
|
100
|
+
def to_base16_string
|
101
|
+
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
102
|
+
error = ergo_lib_constant_to_base16(self.pointer, s_ptr)
|
103
|
+
Util.check_error!(error)
|
104
|
+
s_ptr = s_ptr.read_pointer()
|
105
|
+
str = s_ptr.read_string().force_encoding('UTF-8')
|
106
|
+
Util.ergo_lib_delete_string(s_ptr)
|
107
|
+
str
|
108
|
+
end
|
109
|
+
|
110
|
+
# Extract 32-bit integer value, throw error if wrong type
|
111
|
+
# @return [Integer]
|
88
112
|
def to_i32
|
89
113
|
res = ergo_lib_constant_to_i32(self.pointer)
|
90
114
|
Util.check_error!(res[:error])
|
91
115
|
res[:value]
|
92
116
|
end
|
93
117
|
|
118
|
+
# Extract 64-bit integer value, throw error if wrong type
|
119
|
+
# @return [Integer]
|
94
120
|
def to_i64
|
95
121
|
res = ergo_lib_constant_to_i64(self.pointer)
|
96
122
|
Util.check_error!(res[:error])
|
97
123
|
res[:value]
|
98
124
|
end
|
99
125
|
|
126
|
+
# Equality check for two Constants
|
127
|
+
# @param constant_two [Constant]
|
128
|
+
# @return [bool]
|
100
129
|
def ==(constant_two)
|
101
130
|
ergo_lib_constant_eq(self.pointer, constant_two.pointer)
|
102
131
|
end
|
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# User-defined variables to be put into context
|
6
7
|
class ContextExtension
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -13,16 +14,25 @@ module Sigma
|
|
13
14
|
attach_function :ergo_lib_context_extension_keys, [:pointer, :pointer], :void
|
14
15
|
attr_accessor :pointer
|
15
16
|
|
17
|
+
# Creates an empty ContextExtension
|
18
|
+
# @return [ContextExtension]
|
16
19
|
def self.create
|
17
20
|
pointer = FFI::MemoryPointer.new(:pointer)
|
18
21
|
ergo_lib_context_extension_empty(pointer)
|
19
22
|
init(pointer)
|
20
23
|
end
|
21
24
|
|
25
|
+
|
26
|
+
# Takes ownership of an existing ContextExtension Pointer.
|
27
|
+
# @note A user of sigma_rb generally does not need to call this function
|
28
|
+
# @param pointer [FFI::MemoryPointer]
|
29
|
+
# @return [ContextExtension]
|
22
30
|
def self.with_raw_pointer(pointer)
|
23
31
|
init(pointer)
|
24
32
|
end
|
25
33
|
|
34
|
+
# Get all keys in the map
|
35
|
+
# @return [Array<uint8>]
|
26
36
|
def get_keys
|
27
37
|
ce_len = ergo_lib_context_extension_len(self.pointer)
|
28
38
|
b_ptr = FFI::MemoryPointer.new(:uint8, ce_len)
|