sigma_rb 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c92fe136337de8a807df096f11be91adc0adbbcdd3ec1954e1d709330f0923ce
|
4
|
+
data.tar.gz: 9b8e1184fbfb6b4bc3fac7f1ae17c9af6ff944b1fef162610a59c424115ddf35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f074423dd70b380e840e38a3c1a30569c019578e0e0cb57db8254f135ee8e8572ea8a9b4cf33fe10764c60ab968bd504a385532e74e963bacf8113b5ef18f9a
|
7
|
+
data.tar.gz: 9b22745d040d9ff79166bc8a14226ad6582796faf248b0d3a449d637c13a629387330564ac4a31af5af3f779f940117783447ab609ea083f92e7469fcae110ba
|
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.2.0 | 0.18.0 |
|
10
|
+
| 0.1.3 - 0.1.5 | 0.16.0 |
|
11
|
+
|
12
|
+
|
13
|
+
## Build ErgoLib Dependencies
|
14
|
+
Checkout the supported Sigma-Rust version on the [releases](https://github.com/ergoplatform/sigma-rust/releases) page .
|
15
|
+
|
16
|
+
### Build the ergo-lib-c bindings
|
17
|
+
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)
|
18
|
+
|
19
|
+
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.
|
20
|
+
|
21
|
+
After checking out the proper Sigma-Rust and starting at it's root directory:
|
22
|
+
```
|
23
|
+
cd bindings/ergo-lib-c
|
24
|
+
cargo build --release -p ergo-lib-c
|
25
|
+
```
|
26
|
+
|
27
|
+
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.
|
28
|
+
|
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` .
|
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)
|