sigma_rb 0.1.3

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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +9 -0
  4. data/ext/Rakefile +7 -0
  5. data/ext/csigma.c +5 -0
  6. data/lib/sigma/address.rb +73 -0
  7. data/lib/sigma/block_header.rb +197 -0
  8. data/lib/sigma/box_selection.rb +105 -0
  9. data/lib/sigma/byte_array.rb +96 -0
  10. data/lib/sigma/constant.rb +117 -0
  11. data/lib/sigma/context_extension.rb +47 -0
  12. data/lib/sigma/contract.rb +70 -0
  13. data/lib/sigma/data_input.rb +100 -0
  14. data/lib/sigma/enums.rb +35 -0
  15. data/lib/sigma/ergo_box.rb +556 -0
  16. data/lib/sigma/ergo_box_candidate_builder.rb +123 -0
  17. data/lib/sigma/ergo_state_context.rb +41 -0
  18. data/lib/sigma/ergo_tree.rb +111 -0
  19. data/lib/sigma/input.rb +249 -0
  20. data/lib/sigma/merkle_proof.rb +79 -0
  21. data/lib/sigma/nipopow.rb +155 -0
  22. data/lib/sigma/pre_header.rb +38 -0
  23. data/lib/sigma/reduced_transaction.rb +88 -0
  24. data/lib/sigma/secret_key.rb +119 -0
  25. data/lib/sigma/structs.rb +31 -0
  26. data/lib/sigma/token.rb +225 -0
  27. data/lib/sigma/transaction.rb +365 -0
  28. data/lib/sigma/tx_builder.rb +116 -0
  29. data/lib/sigma/util.rb +27 -0
  30. data/lib/sigma/wallet.rb +97 -0
  31. data/lib/sigma.rb +32 -0
  32. data/sigma.gemspec +20 -0
  33. data/tests/all.rb +44 -0
  34. data/tests/sigma/address_test.rb +45 -0
  35. data/tests/sigma/block_header_test.rb +35 -0
  36. data/tests/sigma/box_selection_test.rb +78 -0
  37. data/tests/sigma/constant_test.rb +57 -0
  38. data/tests/sigma/context_extension_test.rb +16 -0
  39. data/tests/sigma/contract_test.rb +39 -0
  40. data/tests/sigma/data_input_test.rb +38 -0
  41. data/tests/sigma/ergo_box_candidate_builder_test.rb +76 -0
  42. data/tests/sigma/ergo_box_test.rb +219 -0
  43. data/tests/sigma/ergo_state_context_test.rb +26 -0
  44. data/tests/sigma/ergo_tree_test.rb +66 -0
  45. data/tests/sigma/input_test.rb +41 -0
  46. data/tests/sigma/merkle_proof_test.rb +34 -0
  47. data/tests/sigma/nipopow_test.rb +100 -0
  48. data/tests/sigma/secret_key_test.rb +31 -0
  49. data/tests/sigma/token_test.rb +87 -0
  50. data/tests/sigma/transaction_test.rb +438 -0
  51. data/tests/sigma_test.rb +18 -0
  52. data/tests/test_seeds.rb +35 -0
  53. data/tests/test_utils.rb +11 -0
  54. metadata +174 -0
@@ -0,0 +1,365 @@
1
+ require 'ffi'
2
+ require_relative './util.rb'
3
+ require 'ffi-compiler/loader'
4
+
5
+ module Sigma
6
+ class Transaction
7
+ extend FFI::Library
8
+ ffi_lib FFI::Compiler::Loader.find('csigma')
9
+ typedef :pointer, :error_pointer
10
+ attach_function :ergo_lib_tx_delete, [:pointer], :void
11
+ attach_function :ergo_lib_tx_from_unsigned_tx, [:pointer, :pointer, :pointer], :error_pointer
12
+ attach_function :ergo_lib_tx_from_json, [:pointer, :pointer], :error_pointer
13
+ attach_function :ergo_lib_tx_id, [:pointer, :pointer], :void
14
+ attach_function :ergo_lib_tx_inputs, [:pointer, :pointer], :void
15
+ attach_function :ergo_lib_tx_data_inputs, [:pointer, :pointer], :void
16
+ attach_function :ergo_lib_tx_output_candidates, [:pointer, :pointer], :void
17
+ attach_function :ergo_lib_tx_outputs, [:pointer, :pointer], :void
18
+ attach_function :ergo_lib_tx_to_json, [:pointer, :pointer], :error_pointer
19
+ attach_function :ergo_lib_tx_to_json_eip12, [:pointer, :pointer], :error_pointer
20
+ attr_accessor :pointer
21
+
22
+ def self.create_from_unsigned_tx(unsigned_tx:, proofs:)
23
+ pointer = FFI::MemoryPointer.new(:pointer)
24
+ error = ergo_lib_tx_from_unsigned_tx(unsigned_tx.pointer, proofs.pointer, pointer)
25
+ Util.check_error!(error)
26
+ init(pointer)
27
+ end
28
+
29
+ def self.create_from_json(json)
30
+ pointer = FFI::MemoryPointer.new(:pointer)
31
+ error = ergo_lib_tx_from_json(json, pointer)
32
+ Util.check_error!(error)
33
+ init(pointer)
34
+ end
35
+
36
+ def self.with_raw_pointer(pointer)
37
+ init(pointer)
38
+ end
39
+
40
+ def get_tx_id
41
+ pointer = FFI::MemoryPointer.new(:pointer)
42
+ ergo_lib_tx_id(self.pointer, pointer)
43
+ Sigma::TxId.with_raw_pointer(pointer)
44
+ end
45
+
46
+ def get_inputs
47
+ pointer = FFI::MemoryPointer.new(:pointer)
48
+ ergo_lib_tx_inputs(self.pointer, pointer)
49
+ Sigma::Inputs.with_raw_pointer(pointer)
50
+ end
51
+
52
+ def get_data_inputs
53
+ pointer = FFI::MemoryPointer.new(:pointer)
54
+ ergo_lib_tx_data_inputs(self.pointer, pointer)
55
+ Sigma::DataInputs.with_raw_pointer(pointer)
56
+ end
57
+
58
+ def get_output_candidates
59
+ pointer = FFI::MemoryPointer.new(:pointer)
60
+ ergo_lib_tx_output_candidates(self.pointer, pointer)
61
+ Sigma::ErgoBoxCandidates.with_raw_pointer(pointer)
62
+ end
63
+
64
+ def get_outputs
65
+ pointer = FFI::MemoryPointer.new(:pointer)
66
+ ergo_lib_tx_outputs(self.pointer, pointer)
67
+ Sigma::ErgoBoxes.with_raw_pointer(pointer)
68
+ end
69
+
70
+ def to_json
71
+ s_ptr = FFI::MemoryPointer.new(:pointer, 1)
72
+ error = ergo_lib_tx_to_json(self.pointer, s_ptr)
73
+ Util.check_error!(error)
74
+ s_ptr = s_ptr.read_pointer()
75
+ str = s_ptr.read_string().force_encoding('UTF-8')
76
+ Util.ergo_lib_delete_string(s_ptr)
77
+ str
78
+ end
79
+
80
+ def to_json_eip12
81
+ s_ptr = FFI::MemoryPointer.new(:pointer, 1)
82
+ error = ergo_lib_tx_to_json_eip12(self.pointer, s_ptr)
83
+ Util.check_error!(error)
84
+ s_ptr = s_ptr.read_pointer()
85
+ str = s_ptr.read_string().force_encoding('UTF-8')
86
+ Util.ergo_lib_delete_string(s_ptr)
87
+ str
88
+ end
89
+
90
+ private
91
+
92
+ def self.init(unread_pointer)
93
+ obj = self.new
94
+ obj_ptr = unread_pointer.get_pointer(0)
95
+
96
+ obj.pointer = FFI::AutoPointer.new(
97
+ obj_ptr,
98
+ method(:ergo_lib_tx_delete)
99
+ )
100
+ obj
101
+ end
102
+ end
103
+
104
+ class CommitmentHint
105
+ extend FFI::Library
106
+ ffi_lib FFI::Compiler::Loader.find('csigma')
107
+ typedef :pointer, :error_pointer
108
+ attach_function :ergo_lib_commitment_hint_delete, [:pointer], :void
109
+ attr_accessor :pointer
110
+
111
+ def self.with_raw_pointer(pointer)
112
+ init(pointer)
113
+ end
114
+
115
+ private
116
+
117
+ def self.init(unread_pointer)
118
+ obj = self.new
119
+ obj_ptr = unread_pointer.get_pointer(0)
120
+
121
+ obj.pointer = FFI::AutoPointer.new(
122
+ obj_ptr,
123
+ method(:ergo_lib_commitment_hint_delete)
124
+ )
125
+ obj
126
+ end
127
+ end
128
+
129
+ class HintsBag
130
+ extend FFI::Library
131
+ ffi_lib FFI::Compiler::Loader.find('csigma')
132
+ typedef :pointer, :error_pointer
133
+ attach_function :ergo_lib_hints_bag_delete, [:pointer], :void
134
+ attach_function :ergo_lib_hints_bag_empty, [:pointer], :void
135
+ attach_function :ergo_lib_hints_bag_add_commitment, [:pointer, :pointer], :void
136
+ attach_function :ergo_lib_hints_bag_len, [:pointer], :uint
137
+ attach_function :ergo_lib_hints_bag_get, [:pointer, :uint, :pointer], ReturnOption.by_value
138
+ attr_accessor :pointer
139
+
140
+ def self.create
141
+ pointer = FFI::MemoryPointer.new(:pointer)
142
+ ergo_lib_hints_bag_empty(pointer)
143
+ init(pointer)
144
+ end
145
+
146
+ def self.with_raw_pointer(pointer)
147
+ init(pointer)
148
+ end
149
+
150
+ def add_commitment_hint(commitment_hint)
151
+ ergo_lib_hints_bag_add_commitment(self.pointer, commitment_hint.pointer)
152
+ end
153
+
154
+ def len
155
+ ergo_lib_hints_bag_add_commitment_len(self.pointer)
156
+ end
157
+
158
+ def get_commitment_hint(index)
159
+ pointer = FFI::MemoryPointer.new(:pointer)
160
+ res = ergo_lib_hints_bag_get(self.pointer, index, pointer)
161
+ Util.check_error!(res[:error])
162
+ if res[:is_some]
163
+ Sigma::CommitmentHint.with_raw_pointer(pointer)
164
+ else
165
+ nil
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def self.init(unread_pointer)
172
+ obj = self.new
173
+ obj_ptr = unread_pointer.get_pointer(0)
174
+
175
+ obj.pointer = FFI::AutoPointer.new(
176
+ obj_ptr,
177
+ method(:ergo_lib_hints_bag_delete)
178
+ )
179
+ obj
180
+ end
181
+ end
182
+
183
+ class TransactionHintsBag
184
+ extend FFI::Library
185
+ ffi_lib FFI::Compiler::Loader.find('csigma')
186
+ typedef :pointer, :error_pointer
187
+ attach_function :ergo_lib_transaction_hints_bag_delete, [:pointer], :void
188
+ attach_function :ergo_lib_transaction_hints_bag_empty, [:pointer], :void
189
+ attach_function :ergo_lib_transaction_hints_bag_add_hints_for_input, [:pointer, :uint, :pointer], :void
190
+ attach_function :ergo_lib_transaction_hints_bag_all_hints_for_input, [:pointer, :uint, :pointer], :void
191
+ attach_function :ergo_lib_transaction_extract_hints, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :error_pointer
192
+ attr_accessor :pointer
193
+
194
+ def self.create
195
+ pointer = FFI::MemoryPointer.new(:pointer)
196
+ ergo_lib_transaction_hints_bag_empty(pointer)
197
+ init(pointer)
198
+ end
199
+
200
+ def self.with_raw_pointer(pointer)
201
+ init(pointer)
202
+ end
203
+
204
+ def self.extract_hints_from_signed_transaction(transaction:, state_context:, boxes_to_spend:, data_boxes:, real_propositions:, simulated_propositions:)
205
+ pointer = FFI::MemoryPointer.new(:pointer)
206
+ error = ergo_lib_transaction_extract_hints(transaction.pointer, state_context.pointer, boxes_to_spend.pointer, data_boxes.pointer, real_propositions.pointer, simulated_propositions.pointer, pointer)
207
+ Util.check_error!(error)
208
+ init(pointer)
209
+ end
210
+
211
+ def add_hints_for_input(index:, hints_bag:)
212
+ ergo_lib_transaction_hints_bag_add_hints_for_input(self.pointer, index, hints_bag.pointer)
213
+ end
214
+
215
+ def all_hints_for_input(index)
216
+ pointer = FFI::MemoryPointer.new(:pointer)
217
+ ergo_lib_transaction_hints_bag_all_hints_for_input(self.pointer, index, pointer)
218
+ Sigma::HintsBag.with_raw_pointer(pointer)
219
+ end
220
+
221
+ private
222
+
223
+ def self.init(unread_pointer)
224
+ obj = self.new
225
+ obj_ptr = unread_pointer.get_pointer(0)
226
+
227
+ obj.pointer = FFI::AutoPointer.new(
228
+ obj_ptr,
229
+ method(:ergo_lib_transaction_hints_bag_delete)
230
+ )
231
+ obj
232
+ end
233
+ end
234
+
235
+ class UnsignedTransaction
236
+ extend FFI::Library
237
+ ffi_lib FFI::Compiler::Loader.find('csigma')
238
+ typedef :pointer, :error_pointer
239
+ attach_function :ergo_lib_unsigned_tx_delete, [:pointer], :void
240
+ attach_function :ergo_lib_unsigned_tx_from_json, [:pointer, :pointer], :error_pointer
241
+ attach_function :ergo_lib_unsigned_tx_id, [:pointer, :pointer], :void
242
+ attach_function :ergo_lib_unsigned_tx_inputs, [:pointer, :pointer], :void
243
+ attach_function :ergo_lib_unsigned_tx_data_inputs, [:pointer, :pointer], :void
244
+ attach_function :ergo_lib_unsigned_tx_output_candidates, [:pointer, :pointer], :void
245
+ attach_function :ergo_lib_unsigned_tx_to_json, [:pointer, :pointer], :error_pointer
246
+ attach_function :ergo_lib_unsigned_tx_to_json_eip12, [:pointer, :pointer], :error_pointer
247
+ attr_accessor :pointer
248
+
249
+ def self.with_json(json)
250
+ pointer = FFI::MemoryPointer.new(:pointer)
251
+ error = ergo_lib_unsigned_tx_from_json(json, pointer)
252
+ Util.check_error!(error)
253
+ init(pointer)
254
+ end
255
+
256
+ def self.with_raw_pointer(pointer)
257
+ init(pointer)
258
+ end
259
+
260
+ def get_tx_id
261
+ pointer = FFI::MemoryPointer.new(:pointer)
262
+ ergo_lib_unsigned_tx_id(self.pointer, pointer)
263
+ Sigma::TxId.with_raw_pointer(pointer)
264
+ end
265
+
266
+ def get_unsigned_inputs
267
+ pointer = FFI::MemoryPointer.new(:pointer)
268
+ ergo_lib_unsigned_tx_inputs(self.pointer, pointer)
269
+ Sigma::UnsignedInputs.with_raw_pointer(pointer)
270
+ end
271
+
272
+ def get_data_inputs
273
+ pointer = FFI::MemoryPointer.new(:pointer)
274
+ ergo_lib_unsigned_tx_data_inputs(self.pointer, pointer)
275
+ Sigma::DataInputs.with_raw_pointer(pointer)
276
+ end
277
+
278
+ def get_output_candidates
279
+ pointer = FFI::MemoryPointer.new(:pointer)
280
+ ergo_lib_unsigned_tx_output_candidates(self.pointer, pointer)
281
+ Sigma::ErgoBoxCandidates.with_raw_pointer(pointer)
282
+ end
283
+
284
+ def to_json
285
+ s_ptr = FFI::MemoryPointer.new(:pointer, 1)
286
+ error = ergo_lib_unsigned_tx_to_json(self.pointer, s_ptr)
287
+ Util.check_error!(error)
288
+ s_ptr = s_ptr.read_pointer()
289
+ str = s_ptr.read_string().force_encoding('UTF-8')
290
+ Util.ergo_lib_delete_string(s_ptr)
291
+ str
292
+ end
293
+
294
+ def to_json_eip12
295
+ s_ptr = FFI::MemoryPointer.new(:pointer, 1)
296
+ error = ergo_lib_unsigned_tx_to_json_eip12(self.pointer, s_ptr)
297
+ Util.check_error!(error)
298
+ s_ptr = s_ptr.read_pointer()
299
+ str = s_ptr.read_string().force_encoding('UTF-8')
300
+ Util.ergo_lib_delete_string(s_ptr)
301
+ str
302
+ end
303
+
304
+ private
305
+
306
+ def self.init(unread_pointer)
307
+ obj = self.new
308
+ obj_ptr = unread_pointer.get_pointer(0)
309
+
310
+ obj.pointer = FFI::AutoPointer.new(
311
+ obj_ptr,
312
+ method(:ergo_lib_unsigned_tx_delete)
313
+ )
314
+ obj
315
+ end
316
+ end
317
+
318
+ class TxId
319
+ extend FFI::Library
320
+ ffi_lib FFI::Compiler::Loader.find('csigma')
321
+ typedef :pointer, :error_pointer
322
+ attach_function :ergo_lib_tx_id_delete, [:pointer], :void
323
+ attach_function :ergo_lib_tx_id_from_str, [:pointer, :pointer], :error_pointer
324
+ attach_function :ergo_lib_tx_id_to_str, [:pointer,:pointer], :error_pointer
325
+
326
+ attr_accessor :pointer
327
+
328
+ def self.with_string(str)
329
+ pointer = FFI::MemoryPointer.new(:pointer)
330
+ error = ergo_lib_tx_id_from_str(str, pointer)
331
+ Util.check_error!(error)
332
+
333
+ init(pointer)
334
+ end
335
+
336
+ def self.with_raw_pointer(unread_pointer)
337
+ init(unread_pointer)
338
+ end
339
+
340
+ def to_s
341
+ s_ptr = FFI::MemoryPointer.new(:pointer, 1)
342
+ error = ergo_lib_tx_id_to_str(self.pointer, s_ptr)
343
+ Util.check_error!(error)
344
+ s_ptr = s_ptr.read_pointer()
345
+ str = s_ptr.read_string().force_encoding('UTF-8')
346
+ Util.ergo_lib_delete_string(s_ptr)
347
+ str
348
+ end
349
+
350
+ private
351
+
352
+ def self.init(unread_pointer)
353
+ obj = self.new
354
+ obj_ptr = unread_pointer.get_pointer(0)
355
+
356
+ obj.pointer = FFI::AutoPointer.new(
357
+ obj_ptr,
358
+ method(:ergo_lib_tx_id_delete)
359
+ )
360
+ obj
361
+ end
362
+ end
363
+
364
+ end
365
+
@@ -0,0 +1,116 @@
1
+ require 'ffi'
2
+ require_relative './util.rb'
3
+ require 'ffi-compiler/loader'
4
+
5
+ module Sigma
6
+ class TxBuilder
7
+ extend FFI::Library
8
+ ffi_lib FFI::Compiler::Loader.find('csigma')
9
+ typedef :pointer, :error_pointer
10
+ attach_function :ergo_lib_tx_builder_delete, [:pointer], :void
11
+ attach_function :ergo_lib_tx_builder_new, [:pointer, :pointer, :uint32, :pointer, :pointer, :pointer, :pointer], :void
12
+ attach_function :ergo_lib_tx_builder_suggested_tx_fee, [:pointer], :void
13
+ attach_function :ergo_lib_tx_builder_set_data_inputs, [:pointer, :pointer], :void
14
+ attach_function :ergo_lib_tx_builder_set_context_extension, [:pointer, :pointer, :pointer], :void
15
+ attach_function :ergo_lib_tx_builder_data_inputs, [:pointer, :pointer], :void
16
+ attach_function :ergo_lib_tx_builder_build, [:pointer, :pointer], :error_pointer
17
+ attach_function :ergo_lib_tx_builder_box_selection, [:pointer, :pointer], :void
18
+ attach_function :ergo_lib_tx_builder_output_candidates, [:pointer, :pointer], :void
19
+ attach_function :ergo_lib_tx_builder_current_height, [:pointer], :uint32
20
+ attach_function :ergo_lib_tx_builder_fee_amount, [:pointer, :pointer], :void
21
+ attach_function :ergo_lib_tx_builder_change_address, [:pointer, :pointer], :void
22
+ attach_function :ergo_lib_tx_builder_min_change_value, [:pointer, :pointer], :void
23
+
24
+
25
+ attr_accessor :pointer
26
+
27
+ def self.create(box_selection:, output_candidates:, current_height:, fee_amount:, change_address:, min_change_value:)
28
+ pointer = FFI::MemoryPointer.new(:pointer)
29
+ ergo_lib_tx_builder_new(
30
+ box_selection.pointer,
31
+ output_candidates.pointer,
32
+ current_height,
33
+ fee_amount.pointer,
34
+ change_address.pointer,
35
+ min_change_value.pointer,
36
+ pointer
37
+ )
38
+ init(pointer)
39
+ end
40
+
41
+ def self.suggested_tx_fee
42
+ pointer = FFI::MemoryPointer.new(:pointer)
43
+ ergo_lib_tx_builder_suggested_tx_fee(pointer)
44
+ Sigma::BoxValue.with_raw_pointer(pointer)
45
+ end
46
+
47
+ def set_data_inputs(data_inputs)
48
+ ergo_lib_tx_builder_set_data_inputs(self.pointer, data_inputs.pointer)
49
+ end
50
+
51
+ def set_context_extension(box_id, context_extension)
52
+ ergo_lib_tx_builder_set_context_extension(self.pointer, box_id.pointer, context_extension.pointer)
53
+ end
54
+
55
+ def get_data_inputs
56
+ pointer = FFI::MemoryPointer.new(:pointer)
57
+ ergo_lib_tx_builder_data_inputs(self.pointer, pointer)
58
+ Sigma::DataInputs.with_raw_pointer(pointer)
59
+ end
60
+
61
+ def build
62
+ pointer = FFI::MemoryPointer.new(:pointer)
63
+ error = ergo_lib_tx_builder_build(self.pointer, pointer)
64
+ Util.check_error!(error)
65
+ Sigma::UnsignedTransaction.with_raw_pointer(pointer)
66
+ end
67
+
68
+ def get_box_selection
69
+ pointer = FFI::MemoryPointer.new(:pointer)
70
+ ergo_lib_tx_builder_box_selection(self.pointer, pointer)
71
+ Sigma::BoxSelection.with_raw_pointer(pointer)
72
+ end
73
+
74
+ def get_output_candidates
75
+ pointer = FFI::MemoryPointer.new(:pointer)
76
+ ergo_lib_tx_builder_output_candidates(self.pointer, pointer)
77
+ Sigma::ErgoBoxCandidates.with_raw_pointer(pointer)
78
+ end
79
+
80
+ def get_current_height
81
+ ergo_lib_tx_builder_current_height(self.pointer)
82
+ end
83
+
84
+ def get_fee_amount
85
+ pointer = FFI::MemoryPointer.new(:pointer)
86
+ ergo_lib_tx_builder_fee_amount(self.pointer, pointer)
87
+ Sigma::BoxValue.with_raw_pointer(pointer)
88
+ end
89
+
90
+ def get_change_address
91
+ pointer = FFI::MemoryPointer.new(:pointer)
92
+ ergo_lib_tx_builder_change_address(self.pointer, pointer)
93
+ Sigma::Address.with_raw_pointer(pointer)
94
+ end
95
+
96
+ def get_min_change_value
97
+ pointer = FFI::MemoryPointer.new(:pointer)
98
+ ergo_lib_tx_builder_min_change_value(self.pointer, pointer)
99
+ Sigma::BoxValue.with_raw_pointer(pointer)
100
+ end
101
+
102
+ private
103
+
104
+ def self.init(unread_pointer)
105
+ obj = self.new
106
+ obj_ptr = unread_pointer.get_pointer(0)
107
+
108
+ obj.pointer = FFI::AutoPointer.new(
109
+ obj_ptr,
110
+ method(:ergo_lib_tx_builder_delete)
111
+ )
112
+ obj
113
+ end
114
+ end
115
+ end
116
+
data/lib/sigma/util.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'ffi'
2
+ require 'ffi-compiler/loader'
3
+
4
+ module Sigma
5
+ module Util
6
+ extend FFI::Library
7
+ ffi_lib FFI::Compiler::Loader.find('csigma')
8
+
9
+ class ErgoError < StandardError; end
10
+
11
+ typedef :pointer, :error_pointer
12
+ attach_function :ergo_lib_error_to_string, [:error_pointer], :pointer
13
+ attach_function :ergo_lib_delete_string, [:pointer], :void
14
+ attach_function :ergo_lib_delete_error, [:error_pointer], :void
15
+
16
+ def self.check_error!(error_pointer)
17
+ return if error_pointer.null?
18
+
19
+ c_reason_ptr = ergo_lib_error_to_string(error_pointer)
20
+ reason = c_reason_ptr.read_string
21
+ ergo_lib_delete_string(c_reason_ptr)
22
+ ergo_lib_delete_error(error_pointer)
23
+ raise ErgoError.new(reason: reason)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,97 @@
1
+ require 'ffi'
2
+ require_relative './util.rb'
3
+ require 'ffi-compiler/loader'
4
+
5
+ module Sigma
6
+ class Wallet
7
+ extend FFI::Library
8
+ ffi_lib FFI::Compiler::Loader.find('csigma')
9
+ typedef :pointer, :error_pointer
10
+ attach_function :ergo_lib_wallet_delete, [:pointer], :void
11
+ attach_function :ergo_lib_wallet_from_secrets, [:pointer, :pointer], :void
12
+ attach_function :ergo_lib_wallet_from_mnemonic, [:pointer, :pointer, :pointer], :error_pointer
13
+ attach_function :ergo_lib_wallet_sign_transaction, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :error_pointer
14
+ attach_function :ergo_lib_wallet_sign_transaction_multi, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :error_pointer
15
+ attach_function :ergo_lib_wallet_sign_reduced_transaction, [:pointer, :pointer, :pointer], :error_pointer
16
+ attach_function :ergo_lib_wallet_sign_reduced_transaction_multi, [:pointer, :pointer, :pointer, :pointer], :error_pointer
17
+ attach_function :ergo_lib_wallet_generate_commitments, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :error_pointer
18
+ attach_function :ergo_lib_wallet_generate_commitments_for_reduced_transaction, [:pointer, :pointer, :pointer], :error_pointer
19
+ attach_function :ergo_lib_wallet_add_secret, [:pointer, :pointer], :error_pointer
20
+ attr_accessor :pointer
21
+
22
+ def self.create_from_mnemonic(mnemonic_phrase, mnemonic_pass)
23
+ pointer = FFI::MemoryPointer.new(:pointer)
24
+ error = ergo_lib_wallet_from_mnemonic(mnemonic_phrase, mnemonic_pass, pointer)
25
+ Util.check_error!(error)
26
+ init(pointer)
27
+ end
28
+
29
+ def self.create_from_secrets(secrets)
30
+ pointer = FFI::MemoryPointer.new(:pointer)
31
+ ergo_lib_wallet_from_secrets(secrets.pointer, pointer)
32
+ init(pointer)
33
+ end
34
+
35
+ def add_secret(secret)
36
+ error = ergo_lib_wallet_add_secret(self.pointer, secret.pointer)
37
+ Util.check_error!(error)
38
+ end
39
+
40
+ def sign_transaction(state_context:, unsigned_tx:, boxes_to_spend:, data_boxes:)
41
+ pointer = FFI::MemoryPointer.new(:pointer)
42
+ error = ergo_lib_wallet_sign_transaction(self.pointer, state_context.pointer, unsigned_tx.pointer, boxes_to_spend.pointer, data_boxes.pointer, pointer)
43
+ Util.check_error!(error)
44
+ Sigma::Transaction.with_raw_pointer(pointer)
45
+ end
46
+
47
+ def sign_transaction_multi(state_context:, unsigned_tx:, boxes_to_spend:, data_boxes:, tx_hints:)
48
+ pointer = FFI::MemoryPointer.new(:pointer)
49
+ error = ergo_lib_wallet_sign_transaction_multi(self.pointer, state_context.pointer, unsigned_tx.pointer, boxes_to_spend.pointer, data_boxes.pointer, tx_hints.pointer, pointer)
50
+ Util.check_error!(error)
51
+ Sigma::Transaction.with_raw_pointer(pointer)
52
+ end
53
+
54
+ def sign_reduced_transaction(reduced_tx)
55
+ pointer = FFI::MemoryPointer.new(:pointer)
56
+ error = ergo_lib_wallet_sign_reduced_transaction(self.pointer, reduced_tx.pointer, pointer)
57
+ Util.check_error!(error)
58
+ Sigma::Transaction.with_raw_pointer(pointer)
59
+ end
60
+
61
+ def sign_reduced_transaction_multi(reduced_tx:, tx_hints:)
62
+ pointer = FFI::MemoryPointer.new(:pointer)
63
+ error = ergo_lib_wallet_sign_reduced_transaction_multi(self.pointer, reduced_tx.pointer, tx_hints.pointer, pointer)
64
+ Util.check_error!(error)
65
+ Sigma::Transaction.with_raw_pointer(pointer)
66
+ end
67
+
68
+ def generate_commitments(state_context:, unsigned_tx:, boxes_to_spend:, data_boxes:)
69
+ pointer = FFI::MemoryPointer.new(:pointer)
70
+ error = ergo_lib_wallet_generate_commitments(self.pointer, state_context.pointer, unsigned_tx.pointer, boxes_to_spend.pointer, data_boxes.pointer, pointer)
71
+ Util.check_error!(error)
72
+ Sigma::TransactionHintsBag.with_raw_pointer(pointer)
73
+ end
74
+
75
+ def generate_commitments_for_reduced_transaction(reduced_tx)
76
+ pointer = FFI::MemoryPointer.new(:pointer)
77
+ error = ergo_lib_wallet_generate_commitments_for_reduced_transaction(self.pointer, reduced_tx.pointer, pointer)
78
+ Util.check_error!(error)
79
+ Sigma::TransactionHintsBag.with_raw_pointer(pointer)
80
+ end
81
+
82
+ private
83
+
84
+ def self.init(unread_pointer)
85
+ obj = self.new
86
+ obj_ptr = unread_pointer.get_pointer(0)
87
+
88
+ obj.pointer = FFI::AutoPointer.new(
89
+ obj_ptr,
90
+ method(:ergo_lib_wallet_delete)
91
+ )
92
+ obj
93
+ end
94
+ end
95
+ end
96
+
97
+
data/lib/sigma.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'ffi'
2
+
3
+ module Sigma
4
+ require_relative 'sigma/structs'
5
+ require_relative 'sigma/enums'
6
+ require_relative 'sigma/address'
7
+ require_relative 'sigma/ergo_box'
8
+ require_relative 'sigma/constant'
9
+ require_relative 'sigma/token'
10
+ require_relative 'sigma/ergo_tree'
11
+ require_relative 'sigma/contract'
12
+ require_relative 'sigma/transaction'
13
+ require_relative 'sigma/reduced_transaction'
14
+ require_relative 'sigma/tx_builder'
15
+ require_relative 'sigma/data_input'
16
+ require_relative 'sigma/box_selection'
17
+ require_relative 'sigma/input'
18
+ require_relative 'sigma/context_extension'
19
+ require_relative 'sigma/ergo_box_candidate_builder'
20
+ require_relative 'sigma/secret_key'
21
+ require_relative 'sigma/block_header'
22
+ require_relative 'sigma/pre_header'
23
+ require_relative 'sigma/ergo_state_context'
24
+ require_relative 'sigma/byte_array'
25
+ require_relative 'sigma/wallet'
26
+ require_relative 'sigma/merkle_proof'
27
+ require_relative 'sigma/nipopow'
28
+
29
+ SIGMA_RUST_VERSION = '0.16.0'
30
+ end
31
+
32
+
data/sigma.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'sigma_rb'
3
+ s.version = '0.1.3'
4
+ s.summary = "Ruby bindings for Ergo types, abstractions, and interfaces provided by Sigma-Rust."
5
+ s.description = "Ruby bindings for the Ergo-Lib crate of Sigma-Rust. Specifically for chain types and abstractions, json serialization, box selection for tx inputs, tx creation, and signing."
6
+ s.authors = ["Dark Lord of Programming"]
7
+ s.email = 'thedlop@sent.com'
8
+ s.homepage = 'https://github.com/thedlop/sigma_rb'
9
+ s.license = 'MIT'
10
+ s.files = Dir.glob("{lib}/**/*")
11
+ s.files += %w(sigma.gemspec README.md LICENSE ext/Rakefile ext/csigma.c)
12
+ s.add_dependency 'ffi-compiler', '1.0.1'
13
+ s.add_dependency 'rake', '~> 13.0'
14
+ s.add_development_dependency 'ffi', '1.15.5'
15
+ s.add_development_dependency 'test-unit', '~> 3.5'
16
+ s.extensions << "ext/Rakefile"
17
+ s.test_files = Dir["tests/**/*.rb"]
18
+ s.require_paths = ["lib"]
19
+ s.required_ruby_version = '>= 3.0.1'
20
+ end
data/tests/all.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'test/unit'
2
+
3
+ def is_ruby_test_file(filename)
4
+ filename[-8..-1] == "_test.rb"
5
+ end
6
+
7
+ IGNORE = %w(
8
+ all.rb . ..
9
+ )
10
+
11
+ dirs_to_walk = ["./tests"]
12
+ test_files = []
13
+
14
+ module DirWalker
15
+ def self.walk_files(dirs_to_walk, ignore_list:[".", ".."], &block)
16
+ loop do
17
+ break if dirs_to_walk.empty?
18
+ current_dir = dirs_to_walk.shift
19
+ Dir.chdir(current_dir)
20
+ Dir.foreach(".") do |f|
21
+ next if ignore_list.include?(f)
22
+ if File.directory?(f)
23
+ dirs_to_walk.push(File.expand_path(f))
24
+ else
25
+ block.call(f)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ DirWalker.walk_files(dirs_to_walk, ignore_list: IGNORE) do |f|
33
+ if is_ruby_test_file(f)
34
+ test_files << File.expand_path(f)
35
+ end
36
+ end
37
+
38
+ puts test_files.inspect
39
+
40
+ # Require test files
41
+ test_files.each do |f|
42
+ require f
43
+ end
44
+