sigma_rb 0.1.3 → 0.2.0
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 +175 -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/lib/sigma.rb +1 -1
- 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/sigma/token_test.rb +6 -4
- data/tests/test_seeds.rb +1 -0
- metadata +16 -2
data/lib/sigma/contract.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Defines the contract (script) that will be guarding box contents
|
6
7
|
class Contract
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -16,10 +17,17 @@ module Sigma
|
|
16
17
|
|
17
18
|
attr_accessor :pointer
|
18
19
|
|
20
|
+
# Takes ownership of an existing Contract Pointer.
|
21
|
+
# @note A user of sigma_rb generally does not need to call this function
|
22
|
+
# @param pointer [FFI::MemoryPointer]
|
23
|
+
# @return [Contract]
|
19
24
|
def self.with_raw_pointer(contract_pointer)
|
20
25
|
init(contract_pointer)
|
21
26
|
end
|
22
27
|
|
28
|
+
# Create a new contract from an ErgoTree
|
29
|
+
# @param ergo_tree [ErgoTree]
|
30
|
+
# @return [Contract]
|
23
31
|
def self.from_ergo_tree(ergo_tree)
|
24
32
|
pointer = FFI::MemoryPointer.new(:pointer)
|
25
33
|
ergo_lib_contract_new(ergo_tree.pointer, pointer)
|
@@ -27,14 +35,20 @@ module Sigma
|
|
27
35
|
init(pointer)
|
28
36
|
end
|
29
37
|
|
30
|
-
|
38
|
+
# Compiles a contract from ErgoScript source code
|
39
|
+
# @param source [String]
|
40
|
+
# @return [Contract]
|
41
|
+
def self.compile_from_string(source)
|
31
42
|
pointer = FFI::MemoryPointer.new(:pointer)
|
32
|
-
error = ergo_lib_contract_compile(
|
43
|
+
error = ergo_lib_contract_compile(source, pointer)
|
33
44
|
Util.check_error!(error)
|
34
45
|
|
35
46
|
init(pointer)
|
36
47
|
end
|
37
48
|
|
49
|
+
# Create new contract that allow spending of the guarded box by a given recipient (Address)
|
50
|
+
# @param address [Address]
|
51
|
+
# @return [Contract]
|
38
52
|
def self.pay_to_address(address)
|
39
53
|
pointer = FFI::MemoryPointer.new(:pointer)
|
40
54
|
error = ergo_lib_contract_pay_to_address(address.pointer, pointer)
|
@@ -43,12 +57,17 @@ module Sigma
|
|
43
57
|
init(pointer)
|
44
58
|
end
|
45
59
|
|
60
|
+
# Get the ErgoTree of the contract
|
61
|
+
# @return [ErgoTree]
|
46
62
|
def get_ergo_tree
|
47
63
|
pointer = FFI::MemoryPointer.new(:pointer)
|
48
64
|
ergo_lib_contract_ergo_tree(self.pointer, pointer)
|
49
65
|
Sigma::ErgoTree.with_raw_pointer(pointer)
|
50
66
|
end
|
51
67
|
|
68
|
+
# Equality check for two Contracts
|
69
|
+
# @param contract_two [Contract]
|
70
|
+
# @return [bool]
|
52
71
|
def ==(contract_two)
|
53
72
|
ergo_lib_contract_eq(self.pointer, contract_two.pointer)
|
54
73
|
end
|
data/lib/sigma/data_input.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative './util.rb'
|
|
3
3
|
require 'ffi-compiler/loader'
|
4
4
|
|
5
5
|
module Sigma
|
6
|
+
# Inputs, that are used to enrich script context, but won't be spent by the transaction
|
6
7
|
class DataInput
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -12,16 +13,25 @@ module Sigma
|
|
12
13
|
attach_function :ergo_lib_data_input_delete, [:pointer], :void
|
13
14
|
attr_accessor :pointer
|
14
15
|
|
16
|
+
# Parse BoxId and create DataInput
|
17
|
+
# @param box_id [BoxId]
|
18
|
+
# @return [DataInput]
|
15
19
|
def self.with_box_id(box_id)
|
16
20
|
pointer = FFI::MemoryPointer.new(:pointer)
|
17
21
|
ergo_lib_data_input_new(box_id.pointer, pointer)
|
18
22
|
init(pointer)
|
19
23
|
end
|
20
24
|
|
25
|
+
# Takes ownership of an existing DataInput Pointer.
|
26
|
+
# @note A user of sigma_rb generally does not need to call this function
|
27
|
+
# @param pointer [FFI::MemoryPointer]
|
28
|
+
# @return [DataInput]
|
21
29
|
def self.with_raw_pointer(pointer)
|
22
30
|
init(pointer)
|
23
31
|
end
|
24
32
|
|
33
|
+
# Get BoxId
|
34
|
+
# @return [BoxId]
|
25
35
|
def get_box_id
|
26
36
|
pointer = FFI::MemoryPointer.new(:pointer)
|
27
37
|
ergo_lib_data_input_new(self.pointer, pointer)
|
@@ -43,6 +53,7 @@ module Sigma
|
|
43
53
|
|
44
54
|
end
|
45
55
|
|
56
|
+
# An ordered collection of DataInput
|
46
57
|
class DataInputs
|
47
58
|
extend FFI::Library
|
48
59
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -54,10 +65,16 @@ module Sigma
|
|
54
65
|
attach_function :ergo_lib_data_inputs_get, [:pointer, :uint8, :pointer], ReturnOption.by_value
|
55
66
|
attr_accessor :pointer
|
56
67
|
|
68
|
+
# Takes ownership of an existing DataInputs Pointer.
|
69
|
+
# @note A user of sigma_rb generally does not need to call this function
|
70
|
+
# @param pointer [FFI::MemoryPointer]
|
71
|
+
# @return [DataInputs]
|
57
72
|
def self.with_raw_pointer(unread_pointer)
|
58
73
|
init(unread_pointer)
|
59
74
|
end
|
60
75
|
|
76
|
+
# Create an empty collection
|
77
|
+
# @return [DataInputs]
|
61
78
|
def self.create
|
62
79
|
pointer = FFI::MemoryPointer.new(:pointer)
|
63
80
|
ergo_lib_data_inputs_new(pointer)
|
@@ -65,14 +82,21 @@ module Sigma
|
|
65
82
|
init(pointer)
|
66
83
|
end
|
67
84
|
|
85
|
+
# Get length of DataInputs
|
86
|
+
# @return [Integer]
|
68
87
|
def len
|
69
88
|
ergo_lib_data_inputs_len(self.pointer)
|
70
89
|
end
|
71
90
|
|
91
|
+
# Add a DataInput
|
92
|
+
# @param data_input [DataInput]
|
72
93
|
def add(data_input)
|
73
94
|
ergo_lib_data_inputs_add(data_input.pointer, self.pointer)
|
74
95
|
end
|
75
96
|
|
97
|
+
# Get item at specified index or return nil if no item exists
|
98
|
+
# @params index [Integer]
|
99
|
+
# @return [DataInput, nil]
|
76
100
|
def get(index)
|
77
101
|
pointer = FFI::MemoryPointer.new(:pointer)
|
78
102
|
res = ergo_lib_data_inputs_get(self.pointer, index, pointer)
|
data/lib/sigma/enums.rb
CHANGED
@@ -4,6 +4,8 @@ module Sigma
|
|
4
4
|
extend FFI::Library
|
5
5
|
typedef :pointer, :error_pointer
|
6
6
|
|
7
|
+
# Address type prefix
|
8
|
+
# @see https://github.com/ffi/ffi/wiki/Enums FFI Enum Documentation
|
7
9
|
ADDRESS_TYPE_PREFIX_ENUM = enum :address_type_prefix,
|
8
10
|
[
|
9
11
|
:p2pk, 1,
|
@@ -11,12 +13,16 @@ module Sigma
|
|
11
13
|
:pay2s
|
12
14
|
]
|
13
15
|
|
16
|
+
# Network prefix
|
17
|
+
# @see https://github.com/ffi/ffi/wiki/Enums FFI Enum Documentation
|
14
18
|
NETWORK_PREFIX_ENUM = enum :network_prefix,
|
15
19
|
[
|
16
20
|
:mainnet, 0,
|
17
21
|
:testnet, 16,
|
18
22
|
]
|
19
23
|
|
24
|
+
# Register id
|
25
|
+
# @see https://github.com/ffi/ffi/wiki/Enums FFI Enum Documentation
|
20
26
|
REGISTER_ID_ENUM = enum :non_mandatory_register_id,
|
21
27
|
[
|
22
28
|
:r4, 4,
|
@@ -27,6 +33,8 @@ module Sigma
|
|
27
33
|
:r9
|
28
34
|
]
|
29
35
|
|
36
|
+
# Represents which side the node is on in the merkle tree
|
37
|
+
# @see https://github.com/ffi/ffi/wiki/Enums FFI Enum Documentation
|
30
38
|
NODE_SIDE_ENUM = enum :node_side,
|
31
39
|
[
|
32
40
|
:left, 0,
|
data/lib/sigma/ergo_box.rb
CHANGED
@@ -4,6 +4,7 @@ require 'ffi-compiler/loader'
|
|
4
4
|
require 'json'
|
5
5
|
|
6
6
|
module Sigma
|
7
|
+
# BoxId (32-byte digest)
|
7
8
|
class BoxId
|
8
9
|
extend FFI::Library
|
9
10
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -16,10 +17,17 @@ module Sigma
|
|
16
17
|
|
17
18
|
attr_accessor :pointer
|
18
19
|
|
20
|
+
# Takes ownership of an existing BoxId Pointer.
|
21
|
+
# @note A user of sigma_rb generally does not need to call this function
|
22
|
+
# @param pointer [FFI::MemoryPointer]
|
23
|
+
# @return [BoxId]
|
19
24
|
def self.with_raw_pointer(bid_ptr)
|
20
25
|
init(bid_ptr)
|
21
26
|
end
|
22
27
|
|
28
|
+
# Parse box id (32 byte digest) from base16-encoded string
|
29
|
+
# @param str [String]
|
30
|
+
# @return [BoxId]
|
23
31
|
def self.with_string(str)
|
24
32
|
bid_ptr = FFI::MemoryPointer.new(:pointer)
|
25
33
|
error = ergo_lib_box_id_from_str(str, bid_ptr)
|
@@ -28,12 +36,16 @@ module Sigma
|
|
28
36
|
init(bid_ptr)
|
29
37
|
end
|
30
38
|
|
39
|
+
# Returns byte array (32-bytes) representation
|
40
|
+
# @return [Array<uint8, 32>]
|
31
41
|
def to_bytes
|
32
42
|
b_ptr = FFI::MemoryPointer.new(:uint8, 32)
|
33
43
|
ergo_lib_box_id_to_bytes(self.pointer, b_ptr)
|
34
44
|
b_ptr.get_array_of_uint8(0, 32)
|
35
45
|
end
|
36
46
|
|
47
|
+
# Returns base16 encoded string representation
|
48
|
+
# @return [String]
|
37
49
|
def to_s
|
38
50
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
39
51
|
ergo_lib_box_id_to_str(self.pointer, s_ptr)
|
@@ -43,6 +55,9 @@ module Sigma
|
|
43
55
|
str
|
44
56
|
end
|
45
57
|
|
58
|
+
# Equality check of two BoxId
|
59
|
+
# @param box_id_two [BoxId]
|
60
|
+
# @return [bool]
|
46
61
|
def ==(box_id_two)
|
47
62
|
ergo_lib_box_id_eq(self.pointer, box_id_two.pointer)
|
48
63
|
end
|
@@ -61,6 +76,7 @@ module Sigma
|
|
61
76
|
end
|
62
77
|
end
|
63
78
|
|
79
|
+
# Box value in nanoERGs with bound checks
|
64
80
|
class BoxValue
|
65
81
|
extend FFI::Library
|
66
82
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -75,21 +91,28 @@ module Sigma
|
|
75
91
|
|
76
92
|
attr_accessor :pointer
|
77
93
|
|
94
|
+
# Takes ownership of an existing BoxValue Pointer.
|
95
|
+
# @note A user of sigma_rb generally does not need to call this function
|
96
|
+
# @param pointer [FFI::MemoryPointer]
|
97
|
+
# @return [BoxValue]
|
78
98
|
def self.with_raw_pointer(bv_pointer)
|
79
99
|
init(bv_pointer)
|
80
100
|
end
|
81
101
|
|
102
|
+
# Number of units inside one ERGO (i.e. one ERG using nano ERG representation)
|
82
103
|
def self.units_per_ergo
|
83
104
|
ergo_lib_box_value_units_per_ergo
|
84
105
|
end
|
85
106
|
|
107
|
+
# Recommended (safe) minimal box value to use in case box size estimation is unavailable.
|
108
|
+
# Allows box size upto 2777 bytes with current min box value per byte of 360 nanoERGs
|
86
109
|
def self.safe_user_min
|
87
110
|
bv_ptr = FFI::MemoryPointer.new(:pointer)
|
88
111
|
ergo_lib_box_value_safe_user_min(bv_ptr)
|
89
112
|
|
90
113
|
init(bv_ptr)
|
91
114
|
end
|
92
|
-
|
115
|
+
# Create a new box value which is the sum of the arguments, throwing error if value is out of bounds.
|
93
116
|
def self.sum_of(bv_one, bv_two)
|
94
117
|
bv_ptr = FFI::MemoryPointer.new(:pointer)
|
95
118
|
error = ergo_lib_box_value_sum_of(bv_one.pointer, bv_two.pointer, bv_ptr)
|
@@ -98,6 +121,9 @@ module Sigma
|
|
98
121
|
init(bv_ptr)
|
99
122
|
end
|
100
123
|
|
124
|
+
# Create BoxValue from 64-bit integer
|
125
|
+
# @param int [Integer]
|
126
|
+
# @return [BoxValue]
|
101
127
|
def self.from_i64(int)
|
102
128
|
bv_ptr = FFI::MemoryPointer.new(:pointer)
|
103
129
|
error = ergo_lib_box_value_from_i64(int, bv_ptr)
|
@@ -106,10 +132,15 @@ module Sigma
|
|
106
132
|
init(bv_ptr)
|
107
133
|
end
|
108
134
|
|
135
|
+
# Get value as 64-bit integer
|
136
|
+
# @return [Integer]
|
109
137
|
def to_i64
|
110
138
|
ergo_lib_box_value_as_i64(self.pointer)
|
111
139
|
end
|
112
140
|
|
141
|
+
# Equality check for two BoxValues
|
142
|
+
# @param box_value_two [BoxValue]
|
143
|
+
# @return [bool]
|
113
144
|
def ==(box_value_two)
|
114
145
|
ergo_lib_box_value_eq(self.pointer, box_value_two.pointer)
|
115
146
|
end
|
@@ -128,6 +159,8 @@ module Sigma
|
|
128
159
|
end
|
129
160
|
end
|
130
161
|
|
162
|
+
# Contains the same fields as ``ErgoBox``, except for transaction id and index, that will be
|
163
|
+
# calculated after full transaction formation. Use ``ErgoBoxCandidateBuilder`` to create an instance
|
131
164
|
class ErgoBoxCandidate
|
132
165
|
extend FFI::Library
|
133
166
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -142,10 +175,18 @@ module Sigma
|
|
142
175
|
|
143
176
|
attr_accessor :pointer
|
144
177
|
|
178
|
+
# Takes ownership of an existing ErgoBoxCandidate Pointer.
|
179
|
+
# @note A user of sigma_rb generally does not need to call this function
|
180
|
+
# @param pointer [FFI::MemoryPointer]
|
181
|
+
# @return [ErgoBoxCandidate]
|
145
182
|
def self.with_raw_pointer(pointer)
|
146
183
|
init(pointer)
|
147
184
|
end
|
148
185
|
|
186
|
+
# Returns value (ErgoTree constant) stored in the register or `nil` if the register is empty
|
187
|
+
# @param register_id [Integer]
|
188
|
+
# @return [Constant, nil]
|
189
|
+
# @see REGISTER_ID_ENUM
|
149
190
|
def get_register_value(register_id)
|
150
191
|
constant_ptr = FFI::MemoryPointer.new(:pointer)
|
151
192
|
res = ergo_lib_ergo_box_candidate_register_value(self.pointer, register_id, constant_ptr)
|
@@ -157,28 +198,39 @@ module Sigma
|
|
157
198
|
end
|
158
199
|
end
|
159
200
|
|
201
|
+
# Get box creation height
|
202
|
+
# @return [Integer]
|
160
203
|
def get_creation_height
|
161
204
|
ergo_lib_ergo_box_candidate_creation_height(self.pointer)
|
162
205
|
end
|
163
206
|
|
207
|
+
# Get tokens for box
|
208
|
+
# @return [Tokens]
|
164
209
|
def get_tokens
|
165
210
|
pointer = FFI::MemoryPointer.new(:pointer)
|
166
211
|
ergo_lib_ergo_box_candidate_tokens(self.pointer, pointer)
|
167
212
|
Sigma::Tokens.with_raw_pointer(pointer)
|
168
213
|
end
|
169
214
|
|
215
|
+
# Get ErgoTree for box
|
216
|
+
# @return [ErgoTree]
|
170
217
|
def get_ergo_tree
|
171
218
|
pointer = FFI::MemoryPointer.new(:pointer)
|
172
219
|
ergo_lib_ergo_box_candidate_ergo_tree(self.pointer, pointer)
|
173
220
|
Sigma::ErgoTree.with_raw_pointer(pointer)
|
174
221
|
end
|
175
222
|
|
223
|
+
# Get box value
|
224
|
+
# @return [BoxValue]
|
176
225
|
def get_box_value
|
177
226
|
pointer = FFI::MemoryPointer.new(:pointer)
|
178
227
|
ergo_lib_ergo_box_candidate_box_value(self.pointer, pointer)
|
179
228
|
Sigma::BoxValue.with_raw_pointer(pointer)
|
180
229
|
end
|
181
230
|
|
231
|
+
# Equality check
|
232
|
+
# @param ebc_two [ErgoBoxCandidate]
|
233
|
+
# @return [bool]
|
182
234
|
def ==(ebc_two)
|
183
235
|
ergo_lib_ergo_box_candidate_eq(self.pointer, ebc_two.pointer)
|
184
236
|
end
|
@@ -197,6 +249,7 @@ module Sigma
|
|
197
249
|
end
|
198
250
|
end
|
199
251
|
|
252
|
+
# An ordered collection of ErgoBoxCandidate
|
200
253
|
class ErgoBoxCandidates
|
201
254
|
extend FFI::Library
|
202
255
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -209,6 +262,8 @@ module Sigma
|
|
209
262
|
|
210
263
|
attr_accessor :pointer
|
211
264
|
|
265
|
+
# Create an empty collection
|
266
|
+
# @return [ErgoBoxCandidates]
|
212
267
|
def self.create
|
213
268
|
pointer = FFI::MemoryPointer.new(:pointer)
|
214
269
|
ergo_lib_ergo_box_candidates_new(pointer)
|
@@ -216,18 +271,29 @@ module Sigma
|
|
216
271
|
init(pointer)
|
217
272
|
end
|
218
273
|
|
274
|
+
# Takes ownership of an existing ErgoBoxCandidates Pointer.
|
275
|
+
# @note A user of sigma_rb generally does not need to call this function
|
276
|
+
# @param pointer [FFI::MemoryPointer]
|
277
|
+
# @return [ErgoBoxCandidates]
|
219
278
|
def self.with_raw_pointer(pointer)
|
220
279
|
init(pointer)
|
221
280
|
end
|
222
281
|
|
282
|
+
# Get length of collection
|
283
|
+
# @return [Integer]
|
223
284
|
def len
|
224
285
|
ergo_lib_ergo_box_candidates_len(self.pointer)
|
225
286
|
end
|
226
287
|
|
288
|
+
# Add to collection
|
289
|
+
# @param ergo_box_candidate [ErgoBoxCandidate]
|
227
290
|
def add(ergo_box_candidate)
|
228
291
|
ergo_lib_ergo_box_candidates_add(ergo_box_candidate.pointer, self.pointer)
|
229
292
|
end
|
230
293
|
|
294
|
+
# Get item at specified index or return nil if no item exists
|
295
|
+
# @param index [Integer]
|
296
|
+
# @return [ErgoBoxCandidate, nil]
|
231
297
|
def get(index)
|
232
298
|
pointer = FFI::MemoryPointer.new(:pointer)
|
233
299
|
res = ergo_lib_ergo_box_candidates_get(self.pointer, index, pointer)
|
@@ -253,6 +319,26 @@ module Sigma
|
|
253
319
|
end
|
254
320
|
end
|
255
321
|
|
322
|
+
# Box (aka coin, or an unspent output) is a basic concept of a UTXO-based cryptocurrency.
|
323
|
+
# In Bitcoin, such an object is associated with some monetary value (arbitrary,
|
324
|
+
# but with predefined precision, so we use integer arithmetic to work with the value),
|
325
|
+
# and also a guarding script (aka proposition) to protect the box from unauthorized opening.
|
326
|
+
#
|
327
|
+
# In other way, a box is a state element locked by some proposition (ErgoTree).
|
328
|
+
#
|
329
|
+
# In Ergo, box is just a collection of registers, some with mandatory types and semantics,
|
330
|
+
# others could be used by applications in any way.
|
331
|
+
# We add additional fields in addition to amount and proposition~(which stored in the registers R0 and R1).
|
332
|
+
# Namely, register R2 contains additional tokens (a sequence of pairs (token identifier, value)).
|
333
|
+
# Register R3 contains height when block got included into the blockchain and also transaction
|
334
|
+
# identifier and box index in the transaction outputs.
|
335
|
+
# Registers R4-R9 are free for arbitrary usage.
|
336
|
+
#
|
337
|
+
# A transaction is unsealing a box. As a box can not be open twice, any further valid transaction
|
338
|
+
# can not be linked to the same box.
|
339
|
+
# Ergo box, that is taking part in some transaction on the chain Differs with ``ErgoBoxCandidate``
|
340
|
+
# by added transaction id and an index in the input of that transaction
|
341
|
+
|
256
342
|
class ErgoBox
|
257
343
|
extend FFI::Library
|
258
344
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -273,6 +359,17 @@ module Sigma
|
|
273
359
|
|
274
360
|
attr_accessor :pointer
|
275
361
|
|
362
|
+
# Safe maximum number of tokens in the box
|
363
|
+
# Calculated from the max box size (4kb) limit and the size of the token (32 bytes)
|
364
|
+
MAX_TOKENS_COUNT = 100
|
365
|
+
|
366
|
+
# Create a new box
|
367
|
+
# @param box_value: [BoxValue] amount of money associated with box
|
368
|
+
# @param creation_height: [Integer] height when a transaction containing the box is created
|
369
|
+
# @param contract: [Contract] guarding contract which should be evaluted to true in order to open(spend) this box
|
370
|
+
# @param tx_id: [TxId] transaction id in which this box was "created" (participated in outputs)
|
371
|
+
# @param index: [Integer] index (in outputs) in the transaction
|
372
|
+
# @return [ErgoBox]
|
276
373
|
def self.create(box_value:,
|
277
374
|
creation_height:,
|
278
375
|
contract:,
|
@@ -289,10 +386,18 @@ module Sigma
|
|
289
386
|
init(eb_pointer)
|
290
387
|
end
|
291
388
|
|
389
|
+
# Takes ownership of an existing ErgoBox Pointer.
|
390
|
+
# @note A user of sigma_rb generally does not need to call this function
|
391
|
+
# @param pointer [FFI::MemoryPointer]
|
392
|
+
# @return [ErgoBox]
|
292
393
|
def self.with_raw_pointer(unread_pointer)
|
293
394
|
init(unread_pointer)
|
294
395
|
end
|
295
396
|
|
397
|
+
# Parse and create from json.
|
398
|
+
# Supports Ergo Node/Explorer API and box values and token amount encoded as strings
|
399
|
+
# @param json_str [String]
|
400
|
+
# @return [ErgoBox]
|
296
401
|
def self.with_json(json_str)
|
297
402
|
pointer = FFI::MemoryPointer.new(:pointer)
|
298
403
|
error = ergo_lib_ergo_box_from_json(json_str, pointer)
|
@@ -300,22 +405,32 @@ module Sigma
|
|
300
405
|
init(pointer)
|
301
406
|
end
|
302
407
|
|
408
|
+
# Get box id
|
409
|
+
# @return [BoxId]
|
303
410
|
def get_box_id
|
304
411
|
box_id_ptr = FFI::MemoryPointer.new(:pointer)
|
305
412
|
ergo_lib_ergo_box_id(self.pointer, box_id_ptr)
|
306
413
|
Sigma::BoxId.with_raw_pointer(box_id_ptr)
|
307
414
|
end
|
308
415
|
|
416
|
+
# Get box value
|
417
|
+
# @return [BoxValue]
|
309
418
|
def get_box_value
|
310
419
|
box_value_ptr = FFI::MemoryPointer.new(:pointer)
|
311
420
|
ergo_lib_ergo_box_value(self.pointer, box_value_ptr)
|
312
421
|
Sigma::BoxValue.with_raw_pointer(box_value_ptr)
|
313
422
|
end
|
314
423
|
|
424
|
+
# Get box creation height
|
425
|
+
# @return [Integer]
|
315
426
|
def get_creation_height
|
316
427
|
ergo_lib_ergo_box_creation_height(self.pointer)
|
317
428
|
end
|
318
429
|
|
430
|
+
# Returns value (ErgoTree constant) stored in the register or `nil` if the register is empty
|
431
|
+
# @param register_id [Integer]
|
432
|
+
# @return [Constant, nil]
|
433
|
+
# @see REGISTER_ID_ENUM
|
319
434
|
def get_register_value(register_id)
|
320
435
|
constant_ptr = FFI::MemoryPointer.new(:pointer)
|
321
436
|
res = ergo_lib_ergo_box_register_value(self.pointer, register_id, constant_ptr)
|
@@ -327,18 +442,24 @@ module Sigma
|
|
327
442
|
end
|
328
443
|
end
|
329
444
|
|
445
|
+
# Get tokens for box
|
446
|
+
# @return [Tokens]
|
330
447
|
def get_tokens
|
331
448
|
tokens_ptr = FFI::MemoryPointer.new(:pointer)
|
332
449
|
ergo_lib_ergo_box_tokens(self.pointer, tokens_ptr)
|
333
450
|
Sigma::Tokens.with_raw_pointer(tokens_ptr)
|
334
451
|
end
|
335
452
|
|
453
|
+
# Get ergo tree for box
|
454
|
+
# @return [ErgoTree]
|
336
455
|
def get_ergo_tree
|
337
456
|
ergo_tree_ptr = FFI::MemoryPointer.new(:pointer)
|
338
457
|
ergo_lib_ergo_box_ergo_tree(self.pointer, ergo_tree_ptr)
|
339
458
|
Sigma::ErgoTree.with_raw_pointer(ergo_tree_ptr)
|
340
459
|
end
|
341
460
|
|
461
|
+
# JSON representation as text (compatible with Ergo Node/Explorer API, numbers are encoded as numbers)
|
462
|
+
# @return [String]
|
342
463
|
def to_json
|
343
464
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
344
465
|
error = ergo_lib_ergo_box_to_json(self.pointer, s_ptr)
|
@@ -349,6 +470,9 @@ module Sigma
|
|
349
470
|
str
|
350
471
|
end
|
351
472
|
|
473
|
+
# JSON representation according to EIP-12
|
474
|
+
# @see <https://github.com/ergoplatform/eips/pull/23> PR with EIP-12
|
475
|
+
# @return [String]
|
352
476
|
def to_json_eip12
|
353
477
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
354
478
|
error = ergo_lib_ergo_box_to_json_eip12(self.pointer, s_ptr)
|
@@ -359,6 +483,9 @@ module Sigma
|
|
359
483
|
str
|
360
484
|
end
|
361
485
|
|
486
|
+
# Equality check
|
487
|
+
# @param ergo_box_two [ErgoBox]
|
488
|
+
# @return [bool]
|
362
489
|
def ==(ergo_box_two)
|
363
490
|
ergo_lib_ergo_box_eq(self.pointer, ergo_box_two.pointer)
|
364
491
|
end
|
@@ -377,6 +504,7 @@ module Sigma
|
|
377
504
|
end
|
378
505
|
end
|
379
506
|
|
507
|
+
# An ordered collection of ErgoBox
|
380
508
|
class ErgoBoxes
|
381
509
|
extend FFI::Library
|
382
510
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -389,10 +517,16 @@ module Sigma
|
|
389
517
|
|
390
518
|
attr_accessor :pointer
|
391
519
|
|
520
|
+
# Takes ownership of an existing ErgoBoxes Pointer.
|
521
|
+
# @note A user of sigma_rb generally does not need to call this function
|
522
|
+
# @param pointer [FFI::MemoryPointer]
|
523
|
+
# @return [ErgoBoxes]
|
392
524
|
def self.with_raw_pointer(unread_pointer)
|
393
525
|
init(unread_pointer)
|
394
526
|
end
|
395
527
|
|
528
|
+
# Create an empty collection
|
529
|
+
# @return [ErgoBoxes]
|
396
530
|
def self.create
|
397
531
|
pointer = FFI::MemoryPointer.new(:pointer)
|
398
532
|
ergo_lib_ergo_boxes_new(pointer)
|
@@ -400,7 +534,9 @@ module Sigma
|
|
400
534
|
init(pointer)
|
401
535
|
end
|
402
536
|
|
403
|
-
#
|
537
|
+
# Create collection from ErgoBox Array JSON (Node API)
|
538
|
+
# @param array_of_json_elements [Array<String>]
|
539
|
+
# @note Parameter is an ARRAY of JSON Strings
|
404
540
|
def self.from_json(array_of_json_elements)
|
405
541
|
boxes = array_of_json_elements.map do |json|
|
406
542
|
Sigma::ErgoBox.with_json(json)
|
@@ -412,14 +548,21 @@ module Sigma
|
|
412
548
|
container
|
413
549
|
end
|
414
550
|
|
551
|
+
# Get length of collection
|
552
|
+
# @return [Integer]
|
415
553
|
def len
|
416
554
|
ergo_lib_ergo_boxes_len(self.pointer)
|
417
555
|
end
|
418
556
|
|
557
|
+
# Add to collection
|
558
|
+
# @param ergo_box [ErgoBox]
|
419
559
|
def add(ergo_box)
|
420
560
|
ergo_lib_ergo_boxes_add(ergo_box.pointer, self.pointer)
|
421
561
|
end
|
422
562
|
|
563
|
+
# Get item at specified index or return nil if no item exists
|
564
|
+
# @param index [Integer]
|
565
|
+
# @return [ErgoBox, nil]
|
423
566
|
def get(index)
|
424
567
|
pointer = FFI::MemoryPointer.new(:pointer)
|
425
568
|
res = ergo_lib_ergo_boxes_get(self.pointer, index, pointer)
|
@@ -445,6 +588,7 @@ module Sigma
|
|
445
588
|
end
|
446
589
|
end
|
447
590
|
|
591
|
+
# Pair of (value, tokens) for a box
|
448
592
|
class ErgoBoxAssetsData
|
449
593
|
extend FFI::Library
|
450
594
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -457,28 +601,43 @@ module Sigma
|
|
457
601
|
|
458
602
|
attr_accessor :pointer
|
459
603
|
|
604
|
+
# Create new instance
|
605
|
+
# @param box_value: [BoxValue]
|
606
|
+
# @param tokens: [Tokens]
|
607
|
+
# @return [ErgoBoxAssetsData]
|
460
608
|
def self.create(box_value:, tokens:)
|
461
609
|
pointer = FFI::MemoryPointer.new(:pointer)
|
462
610
|
ergo_lib_ergo_box_assets_data_new(box_value.pointer, tokens.pointer, pointer)
|
463
611
|
init(pointer)
|
464
612
|
end
|
465
613
|
|
614
|
+
# Takes ownership of an existing ErgoBoxAssetsData Pointer.
|
615
|
+
# @note A user of sigma_rb generally does not need to call this function
|
616
|
+
# @param pointer [FFI::MemoryPointer]
|
617
|
+
# @return [ErgoBoxAssetsData]
|
466
618
|
def self.with_raw_pointer(pointer)
|
467
619
|
init(pointer)
|
468
620
|
end
|
469
621
|
|
622
|
+
# get box value
|
623
|
+
# @return [BoxValue]
|
470
624
|
def get_box_value
|
471
625
|
pointer = FFI::MemoryPointer.new(:pointer)
|
472
626
|
ergo_lib_ergo_box_assets_data_value(self.pointer, pointer)
|
473
627
|
Sigma::BoxValue.with_raw_pointer(pointer)
|
474
628
|
end
|
475
629
|
|
630
|
+
# get box tokens
|
631
|
+
# @return [Tokens]
|
476
632
|
def get_box_tokens
|
477
633
|
pointer = FFI::MemoryPointer.new(:pointer)
|
478
634
|
ergo_lib_ergo_box_assets_data_tokens(self.pointer, pointer)
|
479
635
|
Sigma::Tokens.with_raw_pointer(pointer)
|
480
636
|
end
|
481
637
|
|
638
|
+
# Equality check
|
639
|
+
# @param eb_asset_data_two [ErgoBoxAssetsData]
|
640
|
+
# @return [bool]
|
482
641
|
def ==(eb_asset_data_two)
|
483
642
|
ergo_lib_ergo_box_assets_data_eq(self.pointer, eb_asset_data_two.pointer)
|
484
643
|
end
|
@@ -497,6 +656,7 @@ module Sigma
|
|
497
656
|
end
|
498
657
|
end
|
499
658
|
|
659
|
+
# An ordered collection of ErgoBoxAssetsData
|
500
660
|
class ErgoBoxAssetsDataList
|
501
661
|
extend FFI::Library
|
502
662
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -509,10 +669,16 @@ module Sigma
|
|
509
669
|
|
510
670
|
attr_accessor :pointer
|
511
671
|
|
672
|
+
# Takes ownership of an existing ErgoBoxAssetsDataList Pointer.
|
673
|
+
# @note A user of sigma_rb generally does not need to call this function
|
674
|
+
# @param pointer [FFI::MemoryPointer]
|
675
|
+
# @return [ErgoBoxAssetsDataList]
|
512
676
|
def self.with_raw_pointer(unread_pointer)
|
513
677
|
init(unread_pointer)
|
514
678
|
end
|
515
679
|
|
680
|
+
# Create an empty collection
|
681
|
+
# @return [ErgoBoxAssetsDataList]
|
516
682
|
def self.create
|
517
683
|
pointer = FFI::MemoryPointer.new(:pointer)
|
518
684
|
ergo_lib_ergo_box_assets_data_list_new(pointer)
|
@@ -520,14 +686,21 @@ module Sigma
|
|
520
686
|
init(pointer)
|
521
687
|
end
|
522
688
|
|
689
|
+
# Get length of collection
|
690
|
+
# @return [Integer]
|
523
691
|
def len
|
524
692
|
ergo_lib_ergo_box_assets_data_list_len(self.pointer)
|
525
693
|
end
|
526
694
|
|
695
|
+
# Add to collection
|
696
|
+
# @param ergo_box_assets_data [ErgoBoxAssetsData]
|
527
697
|
def add(ergo_box_assets_data)
|
528
698
|
ergo_lib_ergo_box_assets_data_list_add(ergo_box_assets_data.pointer, self.pointer)
|
529
699
|
end
|
530
700
|
|
701
|
+
# Get item at specified index or return nil if no item exists
|
702
|
+
# @param index [Integer]
|
703
|
+
# @return [ErgoBoxAssetsData, nil]
|
531
704
|
def get(index)
|
532
705
|
pointer = FFI::MemoryPointer.new(:pointer)
|
533
706
|
res = ergo_lib_ergo_box_assets_data_list_get(self.pointer, index, pointer)
|