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
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,13 @@ module Sigma
|
|
273
359
|
|
274
360
|
attr_accessor :pointer
|
275
361
|
|
362
|
+
# Create a new box
|
363
|
+
# @param box_value: [BoxValue] amount of money associated with box
|
364
|
+
# @param creation_height: [Integer] height when a transaction containing the box is created
|
365
|
+
# @param contract: [Contract] guarding contract which should be evaluted to true in order to open(spend) this box
|
366
|
+
# @param tx_id: [TxId] transaction id in which this box was "created" (participated in outputs)
|
367
|
+
# @param index: [Integer] index (in outputs) in the transaction
|
368
|
+
# @return [ErgoBox]
|
276
369
|
def self.create(box_value:,
|
277
370
|
creation_height:,
|
278
371
|
contract:,
|
@@ -289,10 +382,18 @@ module Sigma
|
|
289
382
|
init(eb_pointer)
|
290
383
|
end
|
291
384
|
|
385
|
+
# Takes ownership of an existing ErgoBox Pointer.
|
386
|
+
# @note A user of sigma_rb generally does not need to call this function
|
387
|
+
# @param pointer [FFI::MemoryPointer]
|
388
|
+
# @return [ErgoBox]
|
292
389
|
def self.with_raw_pointer(unread_pointer)
|
293
390
|
init(unread_pointer)
|
294
391
|
end
|
295
392
|
|
393
|
+
# Parse and create from json.
|
394
|
+
# Supports Ergo Node/Explorer API and box values and token amount encoded as strings
|
395
|
+
# @param json_str [String]
|
396
|
+
# @return [ErgoBox]
|
296
397
|
def self.with_json(json_str)
|
297
398
|
pointer = FFI::MemoryPointer.new(:pointer)
|
298
399
|
error = ergo_lib_ergo_box_from_json(json_str, pointer)
|
@@ -300,22 +401,32 @@ module Sigma
|
|
300
401
|
init(pointer)
|
301
402
|
end
|
302
403
|
|
404
|
+
# Get box id
|
405
|
+
# @return [BoxId]
|
303
406
|
def get_box_id
|
304
407
|
box_id_ptr = FFI::MemoryPointer.new(:pointer)
|
305
408
|
ergo_lib_ergo_box_id(self.pointer, box_id_ptr)
|
306
409
|
Sigma::BoxId.with_raw_pointer(box_id_ptr)
|
307
410
|
end
|
308
411
|
|
412
|
+
# Get box value
|
413
|
+
# @return [BoxValue]
|
309
414
|
def get_box_value
|
310
415
|
box_value_ptr = FFI::MemoryPointer.new(:pointer)
|
311
416
|
ergo_lib_ergo_box_value(self.pointer, box_value_ptr)
|
312
417
|
Sigma::BoxValue.with_raw_pointer(box_value_ptr)
|
313
418
|
end
|
314
419
|
|
420
|
+
# Get box creation height
|
421
|
+
# @return [Integer]
|
315
422
|
def get_creation_height
|
316
423
|
ergo_lib_ergo_box_creation_height(self.pointer)
|
317
424
|
end
|
318
425
|
|
426
|
+
# Returns value (ErgoTree constant) stored in the register or `nil` if the register is empty
|
427
|
+
# @param register_id [Integer]
|
428
|
+
# @return [Constant, nil]
|
429
|
+
# @see REGISTER_ID_ENUM
|
319
430
|
def get_register_value(register_id)
|
320
431
|
constant_ptr = FFI::MemoryPointer.new(:pointer)
|
321
432
|
res = ergo_lib_ergo_box_register_value(self.pointer, register_id, constant_ptr)
|
@@ -327,18 +438,24 @@ module Sigma
|
|
327
438
|
end
|
328
439
|
end
|
329
440
|
|
441
|
+
# Get tokens for box
|
442
|
+
# @return [Tokens]
|
330
443
|
def get_tokens
|
331
444
|
tokens_ptr = FFI::MemoryPointer.new(:pointer)
|
332
445
|
ergo_lib_ergo_box_tokens(self.pointer, tokens_ptr)
|
333
446
|
Sigma::Tokens.with_raw_pointer(tokens_ptr)
|
334
447
|
end
|
335
448
|
|
449
|
+
# Get ergo tree for box
|
450
|
+
# @return [ErgoTree]
|
336
451
|
def get_ergo_tree
|
337
452
|
ergo_tree_ptr = FFI::MemoryPointer.new(:pointer)
|
338
453
|
ergo_lib_ergo_box_ergo_tree(self.pointer, ergo_tree_ptr)
|
339
454
|
Sigma::ErgoTree.with_raw_pointer(ergo_tree_ptr)
|
340
455
|
end
|
341
456
|
|
457
|
+
# JSON representation as text (compatible with Ergo Node/Explorer API, numbers are encoded as numbers)
|
458
|
+
# @return [String]
|
342
459
|
def to_json
|
343
460
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
344
461
|
error = ergo_lib_ergo_box_to_json(self.pointer, s_ptr)
|
@@ -349,6 +466,9 @@ module Sigma
|
|
349
466
|
str
|
350
467
|
end
|
351
468
|
|
469
|
+
# JSON representation according to EIP-12
|
470
|
+
# @see <https://github.com/ergoplatform/eips/pull/23> PR with EIP-12
|
471
|
+
# @return [String]
|
352
472
|
def to_json_eip12
|
353
473
|
s_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
354
474
|
error = ergo_lib_ergo_box_to_json_eip12(self.pointer, s_ptr)
|
@@ -359,6 +479,9 @@ module Sigma
|
|
359
479
|
str
|
360
480
|
end
|
361
481
|
|
482
|
+
# Equality check
|
483
|
+
# @param ergo_box_two [ErgoBox]
|
484
|
+
# @return [bool]
|
362
485
|
def ==(ergo_box_two)
|
363
486
|
ergo_lib_ergo_box_eq(self.pointer, ergo_box_two.pointer)
|
364
487
|
end
|
@@ -377,6 +500,7 @@ module Sigma
|
|
377
500
|
end
|
378
501
|
end
|
379
502
|
|
503
|
+
# An ordered collection of ErgoBox
|
380
504
|
class ErgoBoxes
|
381
505
|
extend FFI::Library
|
382
506
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -389,10 +513,16 @@ module Sigma
|
|
389
513
|
|
390
514
|
attr_accessor :pointer
|
391
515
|
|
516
|
+
# Takes ownership of an existing ErgoBoxes Pointer.
|
517
|
+
# @note A user of sigma_rb generally does not need to call this function
|
518
|
+
# @param pointer [FFI::MemoryPointer]
|
519
|
+
# @return [ErgoBoxes]
|
392
520
|
def self.with_raw_pointer(unread_pointer)
|
393
521
|
init(unread_pointer)
|
394
522
|
end
|
395
523
|
|
524
|
+
# Create an empty collection
|
525
|
+
# @return [ErgoBoxes]
|
396
526
|
def self.create
|
397
527
|
pointer = FFI::MemoryPointer.new(:pointer)
|
398
528
|
ergo_lib_ergo_boxes_new(pointer)
|
@@ -400,7 +530,9 @@ module Sigma
|
|
400
530
|
init(pointer)
|
401
531
|
end
|
402
532
|
|
403
|
-
#
|
533
|
+
# Create collection from ErgoBox Array JSON (Node API)
|
534
|
+
# @param array_of_json_elements [Array<String>]
|
535
|
+
# @note Parameter is an ARRAY of JSON Strings
|
404
536
|
def self.from_json(array_of_json_elements)
|
405
537
|
boxes = array_of_json_elements.map do |json|
|
406
538
|
Sigma::ErgoBox.with_json(json)
|
@@ -412,14 +544,21 @@ module Sigma
|
|
412
544
|
container
|
413
545
|
end
|
414
546
|
|
547
|
+
# Get length of collection
|
548
|
+
# @return [Integer]
|
415
549
|
def len
|
416
550
|
ergo_lib_ergo_boxes_len(self.pointer)
|
417
551
|
end
|
418
552
|
|
553
|
+
# Add to collection
|
554
|
+
# @param ergo_box [ErgoBox]
|
419
555
|
def add(ergo_box)
|
420
556
|
ergo_lib_ergo_boxes_add(ergo_box.pointer, self.pointer)
|
421
557
|
end
|
422
558
|
|
559
|
+
# Get item at specified index or return nil if no item exists
|
560
|
+
# @param index [Integer]
|
561
|
+
# @return [ErgoBox, nil]
|
423
562
|
def get(index)
|
424
563
|
pointer = FFI::MemoryPointer.new(:pointer)
|
425
564
|
res = ergo_lib_ergo_boxes_get(self.pointer, index, pointer)
|
@@ -445,6 +584,7 @@ module Sigma
|
|
445
584
|
end
|
446
585
|
end
|
447
586
|
|
587
|
+
# Pair of (value, tokens) for a box
|
448
588
|
class ErgoBoxAssetsData
|
449
589
|
extend FFI::Library
|
450
590
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -457,28 +597,43 @@ module Sigma
|
|
457
597
|
|
458
598
|
attr_accessor :pointer
|
459
599
|
|
600
|
+
# Create new instance
|
601
|
+
# @param box_value: [BoxValue]
|
602
|
+
# @param tokens: [Tokens]
|
603
|
+
# @return [ErgoBoxAssetsData]
|
460
604
|
def self.create(box_value:, tokens:)
|
461
605
|
pointer = FFI::MemoryPointer.new(:pointer)
|
462
606
|
ergo_lib_ergo_box_assets_data_new(box_value.pointer, tokens.pointer, pointer)
|
463
607
|
init(pointer)
|
464
608
|
end
|
465
609
|
|
610
|
+
# Takes ownership of an existing ErgoBoxAssetsData Pointer.
|
611
|
+
# @note A user of sigma_rb generally does not need to call this function
|
612
|
+
# @param pointer [FFI::MemoryPointer]
|
613
|
+
# @return [ErgoBoxAssetsData]
|
466
614
|
def self.with_raw_pointer(pointer)
|
467
615
|
init(pointer)
|
468
616
|
end
|
469
617
|
|
618
|
+
# get box value
|
619
|
+
# @return [BoxValue]
|
470
620
|
def get_box_value
|
471
621
|
pointer = FFI::MemoryPointer.new(:pointer)
|
472
622
|
ergo_lib_ergo_box_assets_data_value(self.pointer, pointer)
|
473
623
|
Sigma::BoxValue.with_raw_pointer(pointer)
|
474
624
|
end
|
475
625
|
|
626
|
+
# get box tokens
|
627
|
+
# @return [Tokens]
|
476
628
|
def get_box_tokens
|
477
629
|
pointer = FFI::MemoryPointer.new(:pointer)
|
478
630
|
ergo_lib_ergo_box_assets_data_tokens(self.pointer, pointer)
|
479
631
|
Sigma::Tokens.with_raw_pointer(pointer)
|
480
632
|
end
|
481
633
|
|
634
|
+
# Equality check
|
635
|
+
# @param eb_asset_data_two [ErgoBoxAssetsData]
|
636
|
+
# @return [bool]
|
482
637
|
def ==(eb_asset_data_two)
|
483
638
|
ergo_lib_ergo_box_assets_data_eq(self.pointer, eb_asset_data_two.pointer)
|
484
639
|
end
|
@@ -497,6 +652,7 @@ module Sigma
|
|
497
652
|
end
|
498
653
|
end
|
499
654
|
|
655
|
+
# An ordered collection of ErgoBoxAssetsData
|
500
656
|
class ErgoBoxAssetsDataList
|
501
657
|
extend FFI::Library
|
502
658
|
ffi_lib FFI::Compiler::Loader.find('csigma')
|
@@ -509,10 +665,16 @@ module Sigma
|
|
509
665
|
|
510
666
|
attr_accessor :pointer
|
511
667
|
|
668
|
+
# Takes ownership of an existing ErgoBoxAssetsDataList Pointer.
|
669
|
+
# @note A user of sigma_rb generally does not need to call this function
|
670
|
+
# @param pointer [FFI::MemoryPointer]
|
671
|
+
# @return [ErgoBoxAssetsDataList]
|
512
672
|
def self.with_raw_pointer(unread_pointer)
|
513
673
|
init(unread_pointer)
|
514
674
|
end
|
515
675
|
|
676
|
+
# Create an empty collection
|
677
|
+
# @return [ErgoBoxAssetsDataList]
|
516
678
|
def self.create
|
517
679
|
pointer = FFI::MemoryPointer.new(:pointer)
|
518
680
|
ergo_lib_ergo_box_assets_data_list_new(pointer)
|
@@ -520,14 +682,21 @@ module Sigma
|
|
520
682
|
init(pointer)
|
521
683
|
end
|
522
684
|
|
685
|
+
# Get length of collection
|
686
|
+
# @return [Integer]
|
523
687
|
def len
|
524
688
|
ergo_lib_ergo_box_assets_data_list_len(self.pointer)
|
525
689
|
end
|
526
690
|
|
691
|
+
# Add to collection
|
692
|
+
# @param ergo_box_assets_data [ErgoBoxAssetsData]
|
527
693
|
def add(ergo_box_assets_data)
|
528
694
|
ergo_lib_ergo_box_assets_data_list_add(ergo_box_assets_data.pointer, self.pointer)
|
529
695
|
end
|
530
696
|
|
697
|
+
# Get item at specified index or return nil if no item exists
|
698
|
+
# @param index [Integer]
|
699
|
+
# @return [ErgoBoxAssetsData, nil]
|
531
700
|
def get(index)
|
532
701
|
pointer = FFI::MemoryPointer.new(:pointer)
|
533
702
|
res = ergo_lib_ergo_box_assets_data_list_get(self.pointer, index, pointer)
|