tezos_client 0.4.17 → 1.0.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/.gitignore +2 -0
- data/.travis.yml +14 -7
- data/Gemfile.lock +4 -4
- data/README.md +64 -1
- data/lib/tezos_client/client_interface/block_contextual.rb +0 -16
- data/lib/tezos_client/client_interface/client_wrapper.rb +0 -37
- data/lib/tezos_client/client_interface/contract.rb +0 -17
- data/lib/tezos_client/client_interface/key.rb +0 -35
- data/lib/tezos_client/client_interface/misc.rb +0 -26
- data/lib/tezos_client/commands.rb +4 -10
- data/lib/tezos_client/crypto.rb +8 -4
- data/lib/tezos_client/exceptions.rb +9 -2
- data/lib/tezos_client/liquidity_inteface/liquidity_wrapper.rb +3 -17
- data/lib/tezos_client/liquidity_interface.rb +8 -33
- data/lib/tezos_client/operation_mgr.rb +63 -50
- data/lib/tezos_client/operations/transaction_operation.rb +9 -1
- data/lib/tezos_client/rpc_interface/blocks.rb +1 -1
- data/lib/tezos_client/rpc_interface/contracts.rb +7 -0
- data/lib/tezos_client/rpc_interface/helper.rb +4 -6
- data/lib/tezos_client/rpc_interface/operations.rb +14 -3
- data/lib/tezos_client/rpc_interface.rb +0 -1
- data/lib/tezos_client/smartpy_inteface/micheline_serializer_wrapper.rb +17 -0
- data/lib/tezos_client/smartpy_inteface/smartpy_wrapper.rb +20 -0
- data/lib/tezos_client/smartpy_interface.rb +46 -0
- data/lib/tezos_client/tools/system_call.rb +24 -0
- data/lib/tezos_client/tools/temporary_file.rb +30 -0
- data/lib/tezos_client/version.rb +1 -1
- data/lib/tezos_client.rb +75 -20
- data/travis-scripts/prepare-ubuntu.sh +1 -1
- metadata +7 -5
- data/lib/tezos_client/client_interface.rb +0 -25
- data/travis-scripts/install-liquidity.sh +0 -20
- data/travis-scripts/install-opam.sh +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 579469179cc4a5bb283d1bcf72b47ef45526cfa043b8e726c0f0fd28ce898660
|
|
4
|
+
data.tar.gz: 96812ca579b2385498b1d6d77ec0402b971e0cd5404a14358d82afef38d9a155
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2430302849c553bb54824fdb7f9f42f2370e382996217560895a4423fb7639d4ce3ed35bbeab04726385b156759ffff938912cb1d9d9c10f0a59fbc682e9e573
|
|
7
|
+
data.tar.gz: 9e998064917d3163aa589ba96bf7dbbb06cee177192d9487d17d5d181141634b951fb2c3c0c39358abe911efc21b7c44e9bbefc670171f0b613c8417a71abeed
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
service:
|
|
3
|
+
- docker
|
|
2
4
|
dist: xenial
|
|
3
5
|
language: ruby
|
|
4
6
|
sudo: required
|
|
@@ -6,17 +8,22 @@ cache:
|
|
|
6
8
|
bundler: true
|
|
7
9
|
directories:
|
|
8
10
|
- $HOME/.opam
|
|
9
|
-
- liquidity
|
|
10
11
|
rvm:
|
|
11
12
|
- 2.5.1
|
|
12
|
-
env:
|
|
13
|
-
- OPAMYES=1
|
|
14
13
|
before_install:
|
|
15
14
|
- sh travis-scripts/prepare-ubuntu.sh
|
|
16
|
-
-
|
|
17
|
-
-
|
|
15
|
+
- mkdir $HOME/bin
|
|
16
|
+
- docker pull moneytrack/liquidity:babylonnet
|
|
17
|
+
- id=$(docker create moneytrack/liquidity:babylonnet)
|
|
18
|
+
- docker cp $id:/home/opam/.opam/4.07/bin/liquidity - > $HOME/bin/liquidity
|
|
19
|
+
- chmod +x liquidity
|
|
20
|
+
- curl -s https://SmartPy.io/SmartPyBasicTest2/SmartPy.sh > SmartPy.sh
|
|
21
|
+
- chmod +x ./SmartPy.sh
|
|
22
|
+
- ./SmartPy.sh local-install-custom SmartPyBasicTest2 $HOME/bin/smartpy
|
|
23
|
+
- rm ./SmartPy.sh
|
|
24
|
+
- export PATH="$PATH:$HOME/bin/:$HOME/bin/smartpy/SmartPyBasic/"
|
|
25
|
+
- npm link michelson-to-micheline
|
|
18
26
|
- gem install bundler -v 1.16.3
|
|
19
27
|
script:
|
|
20
|
-
- eval `opam config env`
|
|
21
28
|
- bundle install
|
|
22
|
-
- bundle exec rake
|
|
29
|
+
- bundle exec rake
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
tezos_client (0.
|
|
4
|
+
tezos_client (1.0.0)
|
|
5
5
|
activesupport (~> 6.0.0)
|
|
6
6
|
base58 (~> 0.2.3)
|
|
7
7
|
bip_mnemonic (~> 0.0.2)
|
|
@@ -47,7 +47,7 @@ GEM
|
|
|
47
47
|
domain_name (0.5.20190701)
|
|
48
48
|
unf (>= 0.0.5, < 1.0.0)
|
|
49
49
|
erubi (1.9.0)
|
|
50
|
-
ffi (1.12.
|
|
50
|
+
ffi (1.12.1)
|
|
51
51
|
hashdiff (1.0.0)
|
|
52
52
|
http-cookie (1.0.3)
|
|
53
53
|
domain_name (~> 0.5)
|
|
@@ -65,7 +65,7 @@ GEM
|
|
|
65
65
|
mime-types-data (~> 3.2015)
|
|
66
66
|
mime-types-data (3.2019.1009)
|
|
67
67
|
mini_portile2 (2.4.0)
|
|
68
|
-
minitest (5.
|
|
68
|
+
minitest (5.13.0)
|
|
69
69
|
money-tree (0.10.0)
|
|
70
70
|
ffi
|
|
71
71
|
multi_xml (0.6.0)
|
|
@@ -146,7 +146,7 @@ GEM
|
|
|
146
146
|
addressable (>= 2.3.6)
|
|
147
147
|
crack (>= 0.3.2)
|
|
148
148
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
149
|
-
zeitwerk (2.2.
|
|
149
|
+
zeitwerk (2.2.1)
|
|
150
150
|
|
|
151
151
|
PLATFORMS
|
|
152
152
|
ruby
|
data/README.md
CHANGED
|
@@ -10,6 +10,31 @@ Tezos Client interracts with tezos nodes using RPC commands.
|
|
|
10
10
|
Tezos client requires liquidity to be installed in order to work properly.
|
|
11
11
|
For installing on linux, you can basically follow the steps coded in travis-script folder.
|
|
12
12
|
|
|
13
|
+
## Dependency
|
|
14
|
+
|
|
15
|
+
### michelson-to-micheline
|
|
16
|
+
```bash
|
|
17
|
+
sudo apt-get install nodejs
|
|
18
|
+
npm i -g michelson-to-micheline
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### liquidity
|
|
22
|
+
[liquidity installation](http://www.liquidity-lang.org/doc/installation/index.html)
|
|
23
|
+
|
|
24
|
+
need the tezos version (not Dune version)
|
|
25
|
+
|
|
26
|
+
### SmartPy
|
|
27
|
+
[SmartPy](https://smartpy.io/)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
sh <(curl -s https://SmartPy.io/SmartPyBasic/SmartPy.sh) local-install /
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### TypeScript (for dev)
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g typescript
|
|
36
|
+
```
|
|
37
|
+
|
|
13
38
|
## Installation
|
|
14
39
|
|
|
15
40
|
Add this line to your application's Gemfile:
|
|
@@ -122,10 +147,48 @@ TezosClient.new.call_contract(
|
|
|
122
147
|
script: File.expand_path("./spec/fixtures/demo.liq"),
|
|
123
148
|
secret_key: "edsk4EcqupPmaebat5mP57ZQ3zo8NDkwv8vQmafdYZyeXxrSc72pjN",
|
|
124
149
|
to: "KT1STzq9p2tfW3K4RdoM9iYd1htJ4QcJ8Njs",
|
|
125
|
-
|
|
150
|
+
entrypoint: "manage",
|
|
151
|
+
params: "(Some { destination = tz1YLtLqD1fWHthSVHPD116oYvsd4PTAHUoc; amount = 1tz })" ,
|
|
152
|
+
params_type: :caml
|
|
126
153
|
)
|
|
127
154
|
```
|
|
128
155
|
|
|
156
|
+
### Originate a contract written in SmartPy
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
script = File.expand_path("./spec/fixtures/demo.py")
|
|
160
|
+
source = "tz1ZWiiPXowuhN1UqNGVTrgNyf5tdxp4XUUq"
|
|
161
|
+
secret_key = "edsk4EcqupPmaebat5mP57ZQ3zo8NDkwv8vQmafdYZyeXxrSc72pjN"
|
|
162
|
+
amount = 0
|
|
163
|
+
init_params = "MyContract(1, 1)"
|
|
164
|
+
client = TezosClient.new
|
|
165
|
+
|
|
166
|
+
res = client.originate_contract(
|
|
167
|
+
from: source,
|
|
168
|
+
amount: amount,
|
|
169
|
+
script: script,
|
|
170
|
+
secret_key: secret_key,
|
|
171
|
+
init_params: init_params
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
puts "Origination operation: #{res[:operation_id]}"
|
|
175
|
+
puts "Contract address: #{res[:originated_contract]}"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Call a contract written in SmartPy
|
|
179
|
+
```ruby
|
|
180
|
+
TezosClient.new.call_contract(
|
|
181
|
+
from: "tz1ZWiiPXowuhN1UqNGVTrgNyf5tdxp4XUUq",
|
|
182
|
+
secret_key: "edsk4EcqupPmaebat5mP57ZQ3zo8NDkwv8vQmafdYZyeXxrSc72pjN",
|
|
183
|
+
to: "KT1STzq9p2tfW3K4RdoM9iYd1htJ4QcJ8Njs",
|
|
184
|
+
amount: 0,
|
|
185
|
+
entrypoint: "myEntryPoint",
|
|
186
|
+
params: { int: 1 },
|
|
187
|
+
params_type: :micheline
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
|
|
129
192
|
## Options
|
|
130
193
|
|
|
131
194
|
### Liquidity options
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class TezosClient
|
|
4
|
-
class ClientInterface
|
|
5
|
-
# Commands managing keys and accounts
|
|
6
|
-
module BlockContextual
|
|
7
|
-
def transfer(quantity:, from:, to:, dry_run: false, arg: nil)
|
|
8
|
-
cmd = ["transfer", quantity, "from", from, "to", to]
|
|
9
|
-
cmd << "--dry-run" if dry_run
|
|
10
|
-
cmd += ["--arg", "#{arg}"] unless arg.nil?
|
|
11
|
-
|
|
12
|
-
res = call_client(cmd)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class TezosClient
|
|
4
|
-
class ClientInterface
|
|
5
|
-
# Wrapper used to call the tezos-client binary
|
|
6
|
-
module ClientWrapper
|
|
7
|
-
def call_client(command)
|
|
8
|
-
cmd = client_cmd + command
|
|
9
|
-
Open3.popen3(*cmd) do |_stdin, stdout, stderr, wait_thr|
|
|
10
|
-
err = stderr.read
|
|
11
|
-
status = wait_thr.value.exitstatus
|
|
12
|
-
|
|
13
|
-
if status != 0
|
|
14
|
-
raise "command '#{cmd}' existed with status #{status}: #{err}"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
log err
|
|
18
|
-
output = stdout.read
|
|
19
|
-
|
|
20
|
-
if block_given?
|
|
21
|
-
yield(output)
|
|
22
|
-
else
|
|
23
|
-
output
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def client_cmd
|
|
29
|
-
res = ["tezos-client", "-l"]
|
|
30
|
-
if config_file
|
|
31
|
-
res += ["-c", config_file]
|
|
32
|
-
end
|
|
33
|
-
res
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class TezosClient
|
|
4
|
-
class ClientInterface
|
|
5
|
-
# Commands managing keys and accounts
|
|
6
|
-
module Contract
|
|
7
|
-
def known_contracts
|
|
8
|
-
res = call_client(["list", "known", "contracts"])
|
|
9
|
-
res.lines.reduce({}) do |acc, contract_output|
|
|
10
|
-
address_format = /([^:]+): (\w+)/
|
|
11
|
-
res = address_format.match(contract_output)
|
|
12
|
-
acc.merge(res[1] => res[2])
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class TezosClient
|
|
4
|
-
class ClientInterface
|
|
5
|
-
# Commands managing keys and accounts
|
|
6
|
-
module Key
|
|
7
|
-
def gen_keys(name)
|
|
8
|
-
call_client(["gen", "keys", name])
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def addresses
|
|
12
|
-
output = call_client(["list", "known", "addresses"])
|
|
13
|
-
output.lines.reduce({}) do |acc, address_output|
|
|
14
|
-
address_format = /([^:]+): (\w+) /
|
|
15
|
-
res = address_format.match(address_output)
|
|
16
|
-
acc.merge(res[1] => res[2])
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def import_public_key(name, public_key, force: false)
|
|
21
|
-
cmd = ["import", "public", "key", name, public_key]
|
|
22
|
-
cmd << "--force" if force
|
|
23
|
-
|
|
24
|
-
call_client(cmd)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def import_secret_key(name, secret_key, force: false)
|
|
28
|
-
cmd = ["import", "secret", "key", name, secret_key]
|
|
29
|
-
cmd << "--force" if force
|
|
30
|
-
|
|
31
|
-
call_client(cmd)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "open3"
|
|
4
|
-
require "date"
|
|
5
|
-
|
|
6
|
-
class TezosClient
|
|
7
|
-
class ClientInterface
|
|
8
|
-
module Misc
|
|
9
|
-
def bootstrapped
|
|
10
|
-
call_client(["bootstrapped"]) do |output|
|
|
11
|
-
output_format = /Current head: ([^ ]+) \(timestamp: ([^,]+), validation: (.+)\)/
|
|
12
|
-
res = output_format.match(output)
|
|
13
|
-
head = res[1]
|
|
14
|
-
timestamp = DateTime.parse(res[2])
|
|
15
|
-
validation = DateTime.parse(res[3])
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
"block" => head,
|
|
19
|
-
"timestamp" => timestamp,
|
|
20
|
-
"validated_at" => validation
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -18,18 +18,12 @@ class TezosClient
|
|
|
18
18
|
:balance,
|
|
19
19
|
:contract_manager_key,
|
|
20
20
|
:contract_storage,
|
|
21
|
-
:pending_operations
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
:gen_keys,
|
|
25
|
-
:addresses,
|
|
26
|
-
:import_public_key,
|
|
27
|
-
:import_secret_key,
|
|
28
|
-
:known_contracts,
|
|
29
|
-
:transfer
|
|
21
|
+
:pending_operations,
|
|
22
|
+
:pack_data,
|
|
23
|
+
:big_map_value
|
|
30
24
|
|
|
31
25
|
def_delegators :liquidity_interface,
|
|
32
26
|
:get_storage,
|
|
33
|
-
:
|
|
27
|
+
:liquidity_pack_data
|
|
34
28
|
end
|
|
35
29
|
end
|
data/lib/tezos_client/crypto.rb
CHANGED
|
@@ -15,6 +15,7 @@ class TezosClient
|
|
|
15
15
|
tz2: [6, 161, 161],
|
|
16
16
|
tz3: [6, 161, 164],
|
|
17
17
|
KT: [2, 90, 121],
|
|
18
|
+
expr: [13, 44, 64, 27],
|
|
18
19
|
edpk: [13, 15, 37, 217],
|
|
19
20
|
edsk2: [13, 15, 58, 7],
|
|
20
21
|
spsk: [17, 162, 224, 201],
|
|
@@ -112,10 +113,7 @@ class TezosClient
|
|
|
112
113
|
def generate_key(mnemonic: nil, password: nil, wallet_seed: nil, path: nil)
|
|
113
114
|
signing_key = generate_signing_key(mnemonic: mnemonic, password: password, wallet_seed: wallet_seed, path: path).to_bytes.to_hex
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
hex_pubkey = verify_key.to_s.to_hex
|
|
117
|
-
|
|
118
|
-
secret_key = encode_tz(:edsk, signing_key + hex_pubkey)
|
|
116
|
+
secret_key = encode_tz(:edsk2, signing_key)
|
|
119
117
|
public_key = secret_key_to_public_key(secret_key)
|
|
120
118
|
address = public_key_to_address(public_key)
|
|
121
119
|
|
|
@@ -199,6 +197,12 @@ class TezosClient
|
|
|
199
197
|
key.merge(activation_secret: wallet_config[:secret])
|
|
200
198
|
end
|
|
201
199
|
|
|
200
|
+
def encode_script_expr(data:, type:)
|
|
201
|
+
packed_key = pack_data(data: data, type: type)
|
|
202
|
+
raw_expr_key = RbNaCl::Hash::Blake2b.digest(packed_key["packed"].to_bin, digest_size: 32).to_hex
|
|
203
|
+
encode_tz(:expr, raw_expr_key)
|
|
204
|
+
end
|
|
205
|
+
|
|
202
206
|
private
|
|
203
207
|
def generate_signing_key(mnemonic: nil, password: nil, wallet_seed: nil, path: nil)
|
|
204
208
|
if mnemonic
|
|
@@ -18,6 +18,15 @@ class TezosClient
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
class SysCallError < RuntimeError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class LiquidityError < SysCallError
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class SmartPyError < SysCallError
|
|
28
|
+
end
|
|
29
|
+
|
|
21
30
|
class InvalidActivation < RpcRequestFailure
|
|
22
31
|
attr_reader :pkh
|
|
23
32
|
|
|
@@ -101,6 +110,4 @@ class TezosClient
|
|
|
101
110
|
super
|
|
102
111
|
end
|
|
103
112
|
end
|
|
104
|
-
|
|
105
|
-
class UnknownTransactionError < Exception; end
|
|
106
113
|
end
|
|
@@ -6,24 +6,10 @@ class TezosClient
|
|
|
6
6
|
module LiquidityWrapper
|
|
7
7
|
def call_liquidity(command, verbose: false)
|
|
8
8
|
cmd = liquidity_cmd(verbose: verbose).concat command
|
|
9
|
-
log cmd.to_s
|
|
10
|
-
Open3.popen3(*cmd) do |_stdin, stdout, stderr, wait_thr|
|
|
11
|
-
err = stderr.read
|
|
12
|
-
status = wait_thr.value.exitstatus
|
|
13
|
-
log err
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
output = stdout.read
|
|
20
|
-
|
|
21
|
-
if block_given?
|
|
22
|
-
yield(output)
|
|
23
|
-
else
|
|
24
|
-
output
|
|
25
|
-
end
|
|
26
|
-
end
|
|
10
|
+
Tools::SystemCall.execute(cmd)
|
|
11
|
+
rescue SysCallError => e
|
|
12
|
+
raise LiquidityError, e.message
|
|
27
13
|
end
|
|
28
14
|
|
|
29
15
|
def liquidity_cmd(verbose:)
|
|
@@ -28,7 +28,7 @@ class TezosClient
|
|
|
28
28
|
init_params = args.fetch :init_params
|
|
29
29
|
init_params = format_params(init_params)
|
|
30
30
|
|
|
31
|
-
with_tempfile(".json") do |json_file|
|
|
31
|
+
Tools::TemporaryFile.with_tempfile(".json") do |json_file|
|
|
32
32
|
cmd_opt = ["--source", from.to_s,"--json", script.to_s, "-o", json_file.path.to_s, "--init-storage"] + init_params
|
|
33
33
|
|
|
34
34
|
call_liquidity cmd_opt, verbose: options[:verbose]
|
|
@@ -36,34 +36,8 @@ class TezosClient
|
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
def
|
|
40
|
-
|
|
41
|
-
yield(file)
|
|
42
|
-
|
|
43
|
-
ensure
|
|
44
|
-
file.unlink
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def with_file_copy(source_file_path)
|
|
48
|
-
source_file = File.open(source_file_path, "r")
|
|
49
|
-
source_extention = File.extname(source_file_path)
|
|
50
|
-
|
|
51
|
-
file_copy_path = nil
|
|
52
|
-
|
|
53
|
-
res = with_tempfile(source_extention) do |file_copy|
|
|
54
|
-
file_copy.write(source_file.read)
|
|
55
|
-
file_copy_path = file_copy.path
|
|
56
|
-
file_copy.close
|
|
57
|
-
yield(file_copy_path)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
res
|
|
61
|
-
ensure
|
|
62
|
-
File.delete(file_copy_path) if File.exists? file_copy_path
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def json_scripts(args)
|
|
66
|
-
with_file_copy(args[:script]) do |script_copy_path|
|
|
39
|
+
def json_scripts(script:)
|
|
40
|
+
Tools::TemporaryFile.with_file_copy(script) do |script_copy_path|
|
|
67
41
|
script_basename = script_copy_path.sub(/.liq$/, "")
|
|
68
42
|
|
|
69
43
|
json_init_script_path = "#{script_basename}.initializer.tz.json"
|
|
@@ -96,7 +70,7 @@ class TezosClient
|
|
|
96
70
|
|
|
97
71
|
def origination_script(args)
|
|
98
72
|
storage = initial_storage(args)
|
|
99
|
-
_json_init_script, json_contract_script = json_scripts(args)
|
|
73
|
+
_json_init_script, json_contract_script = json_scripts(script: args[:script])
|
|
100
74
|
|
|
101
75
|
{
|
|
102
76
|
code: json_contract_script,
|
|
@@ -129,15 +103,16 @@ class TezosClient
|
|
|
129
103
|
res.strip
|
|
130
104
|
end
|
|
131
105
|
|
|
132
|
-
def call_parameters(script:, parameters:)
|
|
106
|
+
def call_parameters(script:, entrypoint:, parameters:)
|
|
133
107
|
params = format_params parameters
|
|
134
|
-
with_tempfile(".json") do |json_file|
|
|
108
|
+
Tools::TemporaryFile.with_tempfile(".json") do |json_file|
|
|
109
|
+
params = [ entrypoint ] + params
|
|
135
110
|
res = call_liquidity ["--json", "-o", "#{json_file.path}", "#{script}", "--data"] + params
|
|
136
111
|
JSON.parse res
|
|
137
112
|
end
|
|
138
113
|
end
|
|
139
114
|
|
|
140
|
-
def
|
|
115
|
+
def liquidity_pack_data(data:, type:)
|
|
141
116
|
res = call_liquidity ["--pack", "#{data}", "#{type}"]
|
|
142
117
|
res.strip
|
|
143
118
|
end
|
|
@@ -39,6 +39,10 @@ class TezosClient
|
|
|
39
39
|
@protocol ||= rpc_interface.protocol
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def chain_id
|
|
43
|
+
@chain_id ||= rpc_interface.chain_id
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
def simulate_and_update_limits
|
|
43
47
|
run_result = run
|
|
44
48
|
|
|
@@ -47,13 +51,21 @@ class TezosClient
|
|
|
47
51
|
rpc_operation_args[:gas_limit] = (operation_result[:consumed_gas].to_i.from_satoshi + 0.001).to_satoshi.to_s
|
|
48
52
|
end
|
|
49
53
|
end
|
|
54
|
+
|
|
55
|
+
run_result
|
|
50
56
|
end
|
|
51
57
|
|
|
52
58
|
def to_hex
|
|
53
59
|
rpc_interface.forge_operations(operations: rpc_operation_args, branch: branch)
|
|
54
60
|
end
|
|
55
61
|
|
|
62
|
+
def valid_secret_key?
|
|
63
|
+
@secret_key&.match?(/^edsk/)
|
|
64
|
+
end
|
|
65
|
+
|
|
56
66
|
def sign
|
|
67
|
+
raise ArgumentError, "Invalid secret key" unless valid_secret_key?
|
|
68
|
+
|
|
57
69
|
sign_operation(
|
|
58
70
|
secret_key: @secret_key,
|
|
59
71
|
operation_hex: to_hex
|
|
@@ -80,52 +92,73 @@ class TezosClient
|
|
|
80
92
|
|
|
81
93
|
def simulate
|
|
82
94
|
# simulate operations and adjust gas limits
|
|
83
|
-
simulate_and_update_limits
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
95
|
+
run_result = simulate_and_update_limits
|
|
96
|
+
if valid_secret_key?
|
|
97
|
+
preapply
|
|
98
|
+
else
|
|
99
|
+
run_result
|
|
100
|
+
end
|
|
90
101
|
end
|
|
91
102
|
|
|
92
103
|
def test_and_broadcast
|
|
93
104
|
simulate_res = simulate
|
|
94
105
|
op_id = broadcast
|
|
95
106
|
|
|
96
|
-
|
|
107
|
+
simulate_res.merge(
|
|
97
108
|
operation_id: op_id,
|
|
98
|
-
|
|
99
|
-
}
|
|
109
|
+
)
|
|
100
110
|
end
|
|
101
111
|
|
|
102
112
|
def run
|
|
103
113
|
rpc_responses = rpc_interface.run_operations(
|
|
104
114
|
operations: rpc_operation_args,
|
|
105
|
-
signature:
|
|
106
|
-
branch: branch
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
total_consumed_gas = 0
|
|
115
|
+
signature: RANDOM_SIGNATURE,
|
|
116
|
+
branch: branch,
|
|
117
|
+
chain_id: chain_id
|
|
118
|
+
)
|
|
110
119
|
|
|
111
120
|
ensure_applied!(rpc_responses)
|
|
112
121
|
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
convert_rpc_response(rpc_responses)
|
|
123
|
+
end
|
|
115
124
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
def convert_rpc_response(rpc_responses)
|
|
126
|
+
converted_rpc_responce = {
|
|
127
|
+
status: :applied,
|
|
128
|
+
operation_results: operation_results(rpc_responses),
|
|
129
|
+
internal_operation_results: internal_operation_result(rpc_responses)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
converted_rpc_responce.merge(consumed_tez(rpc_responses))
|
|
133
|
+
end
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
def operation_results(rpc_responses)
|
|
136
|
+
rpc_responses.map do |rpc_response|
|
|
137
|
+
metadata = rpc_response[:metadata]
|
|
138
|
+
metadata[:operation_result][:consumed_gas] = compute_consumed_gas(metadata) if metadata.key? :operation_result
|
|
121
139
|
metadata[:operation_result]
|
|
122
140
|
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def internal_operation_result(rpc_responses)
|
|
144
|
+
rpc_responses.map do |rpc_response|
|
|
145
|
+
rpc_response[:metadata][:internal_operation_results]
|
|
146
|
+
end.compact.flatten
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def consumed_tez(rpc_responses)
|
|
150
|
+
total_consumed_storage = 0
|
|
151
|
+
total_consumed_gas = 0
|
|
152
|
+
|
|
153
|
+
rpc_responses.each do |rpc_response|
|
|
154
|
+
metadata = rpc_response[:metadata]
|
|
155
|
+
total_consumed_storage += compute_consumed_storage(metadata)
|
|
156
|
+
total_consumed_gas += compute_consumed_gas(metadata)
|
|
157
|
+
end
|
|
123
158
|
|
|
124
159
|
{
|
|
125
|
-
status: :applied,
|
|
126
|
-
consumed_gas: total_consumed_gas,
|
|
127
160
|
consumed_storage: total_consumed_storage,
|
|
128
|
-
|
|
161
|
+
consumed_gas: total_consumed_gas
|
|
129
162
|
}
|
|
130
163
|
end
|
|
131
164
|
|
|
@@ -144,7 +177,6 @@ class TezosClient
|
|
|
144
177
|
(metadata.dig(:operation_result, :paid_storage_size_diff) || "0").to_i.from_satoshi
|
|
145
178
|
end
|
|
146
179
|
|
|
147
|
-
|
|
148
180
|
def preapply
|
|
149
181
|
rpc_responses = rpc_interface.preapply_operations(
|
|
150
182
|
operations: rpc_operation_args,
|
|
@@ -153,6 +185,8 @@ class TezosClient
|
|
|
153
185
|
branch: branch)
|
|
154
186
|
|
|
155
187
|
ensure_applied!(rpc_responses)
|
|
188
|
+
|
|
189
|
+
convert_rpc_response(rpc_responses)
|
|
156
190
|
end
|
|
157
191
|
|
|
158
192
|
def broadcast
|
|
@@ -168,39 +202,18 @@ class TezosClient
|
|
|
168
202
|
|
|
169
203
|
def ensure_applied!(rpc_responses)
|
|
170
204
|
metadatas = rpc_responses.map { |response| response[:metadata] }
|
|
171
|
-
|
|
172
|
-
{ op_result: metadata[:operation_result], internal_operation_results: metadata[:internal_operation_results]}
|
|
173
|
-
end
|
|
205
|
+
operation_results = metadatas.map { |metadata| metadata[:operation_result] }
|
|
174
206
|
|
|
175
|
-
failed =
|
|
207
|
+
failed = operation_results.detect do |operation_result|
|
|
176
208
|
operation_result != nil && operation_result[:status] != "applied"
|
|
177
209
|
end
|
|
178
210
|
|
|
179
211
|
return metadatas if failed.nil?
|
|
180
212
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def process_transaction_errors!(operations_full_results)
|
|
185
|
-
detect_operation = ->(op_full_results, status: "failed") do
|
|
186
|
-
op_full_results.detect do |operation_result|
|
|
187
|
-
operation_result[:op_result][:status] == status
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
failed_operation_result = detect_operation.call(operations_full_results)
|
|
192
|
-
|
|
193
|
-
if failed_operation_result.nil?
|
|
194
|
-
backtracked_operation_result = detect_operation.call(operations_full_results, status: "backtracked")
|
|
195
|
-
raise UnknownTransactionError if backtracked_operation_result.nil?
|
|
196
|
-
|
|
197
|
-
internal_operations_results = backtracked_operation_result[:internal_operation_results].map{|op| op[:result]}
|
|
198
|
-
failed_operation_result = internal_operations_results.detect { |op_result| op_result[:status] == "failed" }
|
|
199
|
-
else
|
|
200
|
-
failed_operation_result = failed_operation_result[:op_result]
|
|
213
|
+
failed_operation_result = operation_results.detect do |operation_result|
|
|
214
|
+
operation_result[:status] == "failed"
|
|
201
215
|
end
|
|
202
216
|
|
|
203
|
-
operation_results = operations_full_results.map { |full_result| full_result[:op_result] }
|
|
204
217
|
failed!("failed", failed_operation_result[:errors], operation_results)
|
|
205
218
|
end
|
|
206
219
|
|
|
@@ -32,7 +32,15 @@ class TezosClient
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def parameters
|
|
35
|
-
|
|
35
|
+
parameters = @args[:parameters].clone
|
|
36
|
+
if parameters.is_a? String
|
|
37
|
+
{
|
|
38
|
+
entrypoint: "default",
|
|
39
|
+
value: encode_args(@args[:parameters])
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
parameters
|
|
43
|
+
end
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class TezosClient
|
|
4
4
|
class RpcInterface
|
|
5
5
|
using CurrencyUtils
|
|
6
|
+
include Crypto
|
|
6
7
|
|
|
7
8
|
module Contracts
|
|
8
9
|
def contract_link(contract_id)
|
|
@@ -26,6 +27,12 @@ class TezosClient
|
|
|
26
27
|
def contract_storage(contract_id)
|
|
27
28
|
get "#{contract_link(contract_id)}/storage"
|
|
28
29
|
end
|
|
30
|
+
|
|
31
|
+
def big_map_value(big_map_id:, key:, type_key:)
|
|
32
|
+
expr_key = encode_script_expr(data: key, type: type_key)
|
|
33
|
+
|
|
34
|
+
get "/chains/main/blocks/head/context/big_maps/#{big_map_id}/#{expr_key}"
|
|
35
|
+
end
|
|
29
36
|
end
|
|
30
37
|
end
|
|
31
38
|
end
|
|
@@ -16,24 +16,22 @@ class TezosClient
|
|
|
16
16
|
counter: counter(args).to_s,
|
|
17
17
|
fee: args.fetch(:fee, 0.05).to_satoshi.to_s
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
if args[:parameters]
|
|
21
|
+
operation[:parameters] = args[:parameters]
|
|
22
|
+
end
|
|
20
23
|
operation
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def origination_operation(args)
|
|
24
|
-
manager = (args.fetch(:manager) { args.fetch(:from) })
|
|
25
|
-
|
|
26
27
|
operation = {
|
|
27
28
|
kind: "origination",
|
|
28
|
-
delegatable: args.fetch(:delegatable, false),
|
|
29
|
-
spendable: args.fetch(:spendable, false),
|
|
30
29
|
balance: args.fetch(:amount, 0).to_satoshi.to_s,
|
|
31
30
|
source: args.fetch(:from),
|
|
32
31
|
gas_limit: args.fetch(:gas_limit, 0.1).to_satoshi.to_s,
|
|
33
32
|
storage_limit: args.fetch(:storage_limit, 0.06).to_satoshi.to_s,
|
|
34
33
|
counter: counter(args).to_s,
|
|
35
34
|
fee: args.fetch(:fee, 0.05).to_satoshi.to_s,
|
|
36
|
-
manager_pubkey: manager
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
operation[:script] = args[:script] if args[:script]
|
|
@@ -20,9 +20,12 @@ class TezosClient
|
|
|
20
20
|
|
|
21
21
|
def run_operations(operations:, **options)
|
|
22
22
|
content = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
operation: {
|
|
24
|
+
branch: options.fetch(:branch),
|
|
25
|
+
contents: operations,
|
|
26
|
+
signature: options.fetch(:signature)
|
|
27
|
+
},
|
|
28
|
+
chain_id: options.fetch(:chain_id)
|
|
26
29
|
}
|
|
27
30
|
res = post("chains/main/blocks/head/helpers/scripts/run_operation", content)
|
|
28
31
|
res["contents"]
|
|
@@ -43,6 +46,14 @@ class TezosClient
|
|
|
43
46
|
def pending_operations
|
|
44
47
|
get("chains/main/mempool/pending_operations")
|
|
45
48
|
end
|
|
49
|
+
|
|
50
|
+
def pack_data(data:, type:)
|
|
51
|
+
content = {
|
|
52
|
+
data: data,
|
|
53
|
+
type: type
|
|
54
|
+
}
|
|
55
|
+
post("/chains/main/blocks/head/helpers/scripts/pack_data", content)
|
|
56
|
+
end
|
|
46
57
|
end
|
|
47
58
|
end
|
|
48
59
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class TezosClient
|
|
4
|
+
class SmartpyInterface
|
|
5
|
+
module MichelineSerializerWrapper
|
|
6
|
+
def convert_michelson_to_micheline(script)
|
|
7
|
+
cmd = ["michelson-to-micheline", script]
|
|
8
|
+
|
|
9
|
+
Tools::SystemCall.execute(cmd)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def actual_project_path
|
|
13
|
+
TezosClient.root_path
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class TezosClient
|
|
4
|
+
class SmartpyInterface
|
|
5
|
+
# Wrapper used to call the tezos-client binary
|
|
6
|
+
module SmartpyWrapper
|
|
7
|
+
def call_smartpy(command)
|
|
8
|
+
cmd = smartpy_cmd + command
|
|
9
|
+
|
|
10
|
+
Tools::SystemCall.execute(cmd)
|
|
11
|
+
rescue SysCallError => e
|
|
12
|
+
raise SmartPyError, e.to_s
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def smartpy_cmd
|
|
16
|
+
[ "SmartPy.sh" ]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "smartpy_inteface/smartpy_wrapper"
|
|
4
|
+
require_relative "smartpy_inteface/micheline_serializer_wrapper"
|
|
5
|
+
|
|
6
|
+
class TezosClient
|
|
7
|
+
class SmartpyInterface
|
|
8
|
+
include Logger
|
|
9
|
+
include SmartpyWrapper
|
|
10
|
+
include MichelineSerializerWrapper
|
|
11
|
+
|
|
12
|
+
attr_reader :options
|
|
13
|
+
|
|
14
|
+
def json_scripts(args)
|
|
15
|
+
compile_to_michelson(args) do |contract_script_filename, init_script_filename|
|
|
16
|
+
micheline_contract = File.read(contract_script_filename)
|
|
17
|
+
micheline_storage = convert_michelson_to_micheline(File.read(init_script_filename))
|
|
18
|
+
|
|
19
|
+
[JSON.parse(micheline_storage), JSON.parse(micheline_contract)]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def origination_script(args)
|
|
24
|
+
json_init_script, json_contract_script = json_scripts(args)
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
code: json_contract_script,
|
|
28
|
+
storage: json_init_script
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def compile_to_michelson(args)
|
|
35
|
+
Tools::TemporaryFile.with_file_copy(args[:script]) do |script_copy_path|
|
|
36
|
+
script_basename = script_copy_path.split("/").last.sub(/.py$/, "")
|
|
37
|
+
script_path = "/tmp/#{script_basename}/"
|
|
38
|
+
init_script_filename = "contractStorage.tz"
|
|
39
|
+
contract_script_filename = "contractCode.tz.json"
|
|
40
|
+
call_smartpy ["local-compile", script_copy_path, args[:init_params], script_path]
|
|
41
|
+
|
|
42
|
+
yield(script_path + contract_script_filename, script_path + init_script_filename)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class TezosClient
|
|
2
|
+
module Tools
|
|
3
|
+
module SystemCall
|
|
4
|
+
def self.execute(cmd)
|
|
5
|
+
Open3.popen3(*cmd) do |_stdin, stdout, stderr, wait_thr|
|
|
6
|
+
err = stderr.read
|
|
7
|
+
status = wait_thr.value.exitstatus
|
|
8
|
+
|
|
9
|
+
if status != 0
|
|
10
|
+
raise ::TezosClient::SysCallError, "command '#{cmd}' existed with status #{status}: #{err}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
output = stdout.read
|
|
14
|
+
|
|
15
|
+
if block_given?
|
|
16
|
+
yield(output)
|
|
17
|
+
else
|
|
18
|
+
output
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class TezosClient
|
|
2
|
+
module Tools
|
|
3
|
+
module TemporaryFile
|
|
4
|
+
def self.with_file_copy(source_file_path)
|
|
5
|
+
source_file = File.open(source_file_path, "r")
|
|
6
|
+
source_extention = File.extname(source_file_path)
|
|
7
|
+
|
|
8
|
+
file_copy_path = nil
|
|
9
|
+
|
|
10
|
+
res = Tools::TemporaryFile.with_tempfile(source_extention) do |file_copy|
|
|
11
|
+
file_copy.write(source_file.read)
|
|
12
|
+
file_copy_path = file_copy.path
|
|
13
|
+
file_copy.close
|
|
14
|
+
yield(file_copy_path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
res
|
|
18
|
+
ensure
|
|
19
|
+
File.delete(file_copy_path) if File.exists? file_copy_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.with_tempfile(extension)
|
|
23
|
+
file = Tempfile.new(["script", extension])
|
|
24
|
+
yield(file)
|
|
25
|
+
ensure
|
|
26
|
+
file.unlink
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/tezos_client/version.rb
CHANGED
data/lib/tezos_client.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "active_support/core_ext/string/inflections"
|
|
|
6
6
|
require "active_support/core_ext/module/delegation"
|
|
7
7
|
require "timeout"
|
|
8
8
|
require "benchmark"
|
|
9
|
+
require "open3"
|
|
9
10
|
|
|
10
11
|
require "tezos_client/version"
|
|
11
12
|
require "tezos_client/string_utils"
|
|
@@ -25,9 +26,12 @@ require "tezos_client/operations/reveal_operation"
|
|
|
25
26
|
require "tezos_client/operations/raw_operation_array"
|
|
26
27
|
require "tezos_client/operations/operation_array"
|
|
27
28
|
|
|
28
|
-
require "tezos_client/
|
|
29
|
+
require "tezos_client/tools/system_call"
|
|
30
|
+
require "tezos_client/tools/temporary_file"
|
|
31
|
+
|
|
29
32
|
require "tezos_client/rpc_interface"
|
|
30
33
|
require "tezos_client/liquidity_interface"
|
|
34
|
+
require "tezos_client/smartpy_interface"
|
|
31
35
|
|
|
32
36
|
class TezosClient
|
|
33
37
|
using CurrencyUtils
|
|
@@ -38,9 +42,9 @@ class TezosClient
|
|
|
38
42
|
include Commands
|
|
39
43
|
include Crypto
|
|
40
44
|
|
|
41
|
-
attr_accessor :client_interface
|
|
42
45
|
attr_accessor :rpc_interface
|
|
43
46
|
attr_accessor :liquidity_interface
|
|
47
|
+
attr_accessor :smartpy_interface
|
|
44
48
|
|
|
45
49
|
RANDOM_SIGNATURE = "edsigu165B7VFf3Dpw2QABVzEtCxJY2gsNBNcE3Ti7rRxtDUjqTFRpg67EdAQmY6YWPE5tKJDMnSTJDFu65gic8uLjbW2YwGvAZ"
|
|
46
50
|
|
|
@@ -50,15 +54,14 @@ class TezosClient
|
|
|
50
54
|
@liquidity_options = liquidity_options
|
|
51
55
|
|
|
52
56
|
@client_config_file = ENV["TEZOS_CLIENT_CONFIG_FILE"]
|
|
53
|
-
@client_interface = ClientInterface.new(
|
|
54
|
-
config_file: @client_config_file
|
|
55
|
-
)
|
|
56
57
|
|
|
57
58
|
@rpc_interface = RpcInterface.new(
|
|
58
59
|
host: @rpc_node_address,
|
|
59
60
|
port: @rpc_node_port
|
|
60
61
|
)
|
|
61
62
|
|
|
63
|
+
@smartpy_interface = SmartpyInterface.new
|
|
64
|
+
|
|
62
65
|
@liquidity_interface = LiquidityInterface.new(
|
|
63
66
|
rpc_node_address: @rpc_node_address,
|
|
64
67
|
rpc_node_port: @rpc_node_port,
|
|
@@ -79,7 +82,7 @@ class TezosClient
|
|
|
79
82
|
#
|
|
80
83
|
# @return [Hash] result of the origination containing :operation_id, :operation_result and :originated_contract
|
|
81
84
|
#
|
|
82
|
-
def originate_contract(from:, amount:, secret_key
|
|
85
|
+
def originate_contract(from:, amount:, secret_key: nil, script: nil, init_params: nil, dry_run: false, **args)
|
|
83
86
|
origination_args = {
|
|
84
87
|
rpc_interface: rpc_interface,
|
|
85
88
|
from: from,
|
|
@@ -88,13 +91,11 @@ class TezosClient
|
|
|
88
91
|
**args
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
end
|
|
94
|
+
origination_args[:script] = contract_interface(script).origination_script(
|
|
95
|
+
from: from,
|
|
96
|
+
script: script,
|
|
97
|
+
init_params: init_params
|
|
98
|
+
)
|
|
98
99
|
|
|
99
100
|
operation = OriginationOperation.new(origination_args)
|
|
100
101
|
res = broadcast_operation(operation: operation, dry_run: dry_run)
|
|
@@ -166,15 +167,19 @@ class TezosClient
|
|
|
166
167
|
broadcast_operation(operation: operation, dry_run: dry_run)
|
|
167
168
|
end
|
|
168
169
|
|
|
169
|
-
def call_contract(dry_run: false, **args)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
script:
|
|
174
|
-
|
|
170
|
+
def call_contract(dry_run: false, entrypoint:, params:, script: nil, params_type:, **args)
|
|
171
|
+
json_params = micheline_params(
|
|
172
|
+
params: params,
|
|
173
|
+
entrypoint: entrypoint,
|
|
174
|
+
script: script,
|
|
175
|
+
params_type: params_type
|
|
175
176
|
)
|
|
176
177
|
|
|
177
|
-
transfer_args = args.merge(
|
|
178
|
+
transfer_args = args.merge(
|
|
179
|
+
entrypoint: entrypoint,
|
|
180
|
+
parameters: json_params,
|
|
181
|
+
dry_run: dry_run
|
|
182
|
+
)
|
|
178
183
|
|
|
179
184
|
transfer(transfer_args)
|
|
180
185
|
end
|
|
@@ -242,6 +247,10 @@ class TezosClient
|
|
|
242
247
|
end
|
|
243
248
|
end
|
|
244
249
|
|
|
250
|
+
def self.root_path
|
|
251
|
+
File.expand_path(File.dirname(__FILE__))
|
|
252
|
+
end
|
|
253
|
+
|
|
245
254
|
private
|
|
246
255
|
|
|
247
256
|
def broadcast_operation(operation:, dry_run:)
|
|
@@ -256,4 +265,50 @@ class TezosClient
|
|
|
256
265
|
)
|
|
257
266
|
end
|
|
258
267
|
|
|
268
|
+
def liquidity_contract? filename
|
|
269
|
+
filename&.to_s&.end_with?(".liq")
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def micheline_params(params:, entrypoint:, script: nil, params_type:)
|
|
273
|
+
{
|
|
274
|
+
entrypoint: entrypoint,
|
|
275
|
+
value: convert_params(
|
|
276
|
+
params: params,
|
|
277
|
+
entrypoint: entrypoint,
|
|
278
|
+
script: script,
|
|
279
|
+
params_type: params_type
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def convert_params(params:, entrypoint:, script: nil, params_type:)
|
|
285
|
+
case params_type.to_sym
|
|
286
|
+
when :micheline
|
|
287
|
+
params
|
|
288
|
+
when :caml
|
|
289
|
+
raise ::ArgumentError, "need liquidity script path with camel type" if script.nil?
|
|
290
|
+
|
|
291
|
+
liquidity_interface.call_parameters(
|
|
292
|
+
script: script,
|
|
293
|
+
entrypoint: entrypoint,
|
|
294
|
+
parameters: params
|
|
295
|
+
)
|
|
296
|
+
else
|
|
297
|
+
raise ::ArgumentError, "params type must be equal to [ :micheline, :caml ]"
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def contract_interface(script)
|
|
303
|
+
case script.to_s
|
|
304
|
+
when /[A-Za-z_\/\-]*.liq/
|
|
305
|
+
liquidity_interface
|
|
306
|
+
when /[A-Za-z_\/\-]*.py/
|
|
307
|
+
smartpy_interface
|
|
308
|
+
when nil
|
|
309
|
+
raise "script var unset"
|
|
310
|
+
else
|
|
311
|
+
raise "unknown contract type"
|
|
312
|
+
end
|
|
313
|
+
end
|
|
259
314
|
end
|
|
@@ -11,4 +11,4 @@ sudo add-apt-repository "deb http://fr.archive.ubuntu.com/ubuntu bionic main uni
|
|
|
11
11
|
sudo apt-get update -qq
|
|
12
12
|
sudo apt-get install -y -qq \
|
|
13
13
|
libsecp256k1-dev libsecp256k1-0 libsodium-dev libssl-dev \
|
|
14
|
-
bubblewrap libev-dev libhidapi-dev
|
|
14
|
+
bubblewrap libev-dev libhidapi-dev npm
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tezos_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pierre Michard
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-02-
|
|
11
|
+
date: 2020-02-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -227,7 +227,6 @@ files:
|
|
|
227
227
|
- bin/console
|
|
228
228
|
- bin/setup
|
|
229
229
|
- lib/tezos_client.rb
|
|
230
|
-
- lib/tezos_client/client_interface.rb
|
|
231
230
|
- lib/tezos_client/client_interface/block_contextual.rb
|
|
232
231
|
- lib/tezos_client/client_interface/client_wrapper.rb
|
|
233
232
|
- lib/tezos_client/client_interface/contract.rb
|
|
@@ -259,11 +258,14 @@ files:
|
|
|
259
258
|
- lib/tezos_client/rpc_interface/monitor.rb
|
|
260
259
|
- lib/tezos_client/rpc_interface/operations.rb
|
|
261
260
|
- lib/tezos_client/rpc_interface/request_manager.rb
|
|
261
|
+
- lib/tezos_client/smartpy_inteface/micheline_serializer_wrapper.rb
|
|
262
|
+
- lib/tezos_client/smartpy_inteface/smartpy_wrapper.rb
|
|
263
|
+
- lib/tezos_client/smartpy_interface.rb
|
|
262
264
|
- lib/tezos_client/string_utils.rb
|
|
265
|
+
- lib/tezos_client/tools/system_call.rb
|
|
266
|
+
- lib/tezos_client/tools/temporary_file.rb
|
|
263
267
|
- lib/tezos_client/version.rb
|
|
264
268
|
- tezos_client.gemspec
|
|
265
|
-
- travis-scripts/install-liquidity.sh
|
|
266
|
-
- travis-scripts/install-opam.sh
|
|
267
269
|
- travis-scripts/prepare-ubuntu.sh
|
|
268
270
|
homepage: http://moneytrack.io
|
|
269
271
|
licenses:
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "client_interface/client_wrapper"
|
|
4
|
-
require_relative "client_interface/misc"
|
|
5
|
-
require_relative "client_interface/key"
|
|
6
|
-
require_relative "client_interface/contract"
|
|
7
|
-
require_relative "client_interface/block_contextual"
|
|
8
|
-
|
|
9
|
-
class TezosClient
|
|
10
|
-
class ClientInterface
|
|
11
|
-
attr_reader :config_file
|
|
12
|
-
|
|
13
|
-
include Logger
|
|
14
|
-
|
|
15
|
-
include ClientWrapper
|
|
16
|
-
include Misc
|
|
17
|
-
include Key
|
|
18
|
-
include Contract
|
|
19
|
-
include BlockContextual
|
|
20
|
-
|
|
21
|
-
def initialize(config_file: nil)
|
|
22
|
-
@config_file = config_file
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
#set -ex
|
|
3
|
-
# This script is used in .travis.yml for continuous integration on travis.
|
|
4
|
-
# BTW, it also show some needed system packages to build liquidity
|
|
5
|
-
# Travis CI is done on Ubuntu trusty
|
|
6
|
-
export OPAMYES=1
|
|
7
|
-
|
|
8
|
-
[ -d "liquidity/.git" ] || git clone --depth=50 https://github.com/OCamlPro/liquidity.git liquidity
|
|
9
|
-
cd liquidity
|
|
10
|
-
git pull
|
|
11
|
-
# git checkout next
|
|
12
|
-
git checkout 5ed5b09674cb96f8cd4ac83a55621f77d9a9110c
|
|
13
|
-
|
|
14
|
-
eval `opam config env`
|
|
15
|
-
|
|
16
|
-
opam install camlp4 ctypes-foreign ocaml-migrate-parsetree
|
|
17
|
-
make build-deps
|
|
18
|
-
make clone-tezos
|
|
19
|
-
make
|
|
20
|
-
make install
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# This script is used in .travis.yml for continuous integration on travis.
|
|
2
|
-
# Travis CI is done on Ubuntu trusty
|
|
3
|
-
|
|
4
|
-
export OPAMYES=1
|
|
5
|
-
wget https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh
|
|
6
|
-
yes "" | sh install.sh
|
|
7
|
-
|
|
8
|
-
opam switch create liquidity 4.06.1 || opam switch set liquidity
|
|
9
|
-
|
|
10
|
-
eval $(opam config env)
|
|
11
|
-
|
|
12
|
-
opam update
|