ethereum.rb 2.0.1 → 2.0.2
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/.travis.yml +2 -6
- data/README.md +3 -3
- data/lib/ethereum/contract.rb +6 -17
- data/lib/ethereum/decoder.rb +9 -2
- data/lib/ethereum/encoder.rb +22 -16
- data/lib/ethereum/formatter.rb +0 -33
- data/lib/ethereum/solidity.rb +14 -21
- data/lib/ethereum/version.rb +1 -1
- data/lib/tasks/ethereum_node.rake +5 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c3d499f0acb7794b25b60c3caec8f728ce1212e
|
4
|
+
data.tar.gz: e3a239e91d23154acb7bbbc2ba4a528e7754b1eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b91b2eeb93f071839e1f7985915c4ec1ca47a98d58741e6e314b374a7c3aed13db7e2da53672b2075f3783a8508050aa5830404b79755cba04cf91ebf69a453
|
7
|
+
data.tar.gz: c82e52904d885da8073c8a1af9f33a9f70610d2dd12e1acbeb35c937e9dffdb73e8a707b1025f2527c5b914881c4b2bfb43d96ce993a54388ccd90bb880f08ef
|
data/.travis.yml
CHANGED
@@ -3,11 +3,7 @@ language: ruby
|
|
3
3
|
rvm:
|
4
4
|
- 2.3.1
|
5
5
|
env:
|
6
|
-
- PARITY="1.4.8"
|
7
6
|
- PARITY="1.5.0"
|
8
|
-
matrix:
|
9
|
-
allow_failures:
|
10
|
-
- env: PARITY="1.5.0"
|
11
7
|
cache:
|
12
8
|
bundler: true
|
13
9
|
directories:
|
@@ -16,10 +12,10 @@ before_install:
|
|
16
12
|
- sudo bin/install_parity
|
17
13
|
- gem install bundler -v 1.11.2
|
18
14
|
before_script:
|
19
|
-
- parity --chain ~/.parity
|
15
|
+
- parity --chain testnet -d ~/.parity --password ~/.parity/pass --unlock 3089630d06fD90Ef48a0c43f000971587c1F3247 --author 3089630d06fD90Ef48a0c43f000971587c1F3247 daemon ~/.parity.pid --log-file ~/.parity.log
|
20
16
|
- cat ~/.parity.log
|
21
17
|
- sleep 5
|
22
|
-
- parity --chain
|
18
|
+
- parity --chain testnet account list
|
23
19
|
- cat ~/.parity.log
|
24
20
|
- bundle exec rake ethereum:node:waitforsync
|
25
21
|
- bundle exec rake ethereum:test:setup
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://travis-ci.org/marekkirejczyk/ethereum.rb) [](https://hakiri.io/github/NullVoxPopuli/MetaHash/master) [](https://gemnasium.com/marekkirejczyk/ethereum.rb) [](https://codeclimate.com/github/marekkirejczyk/ethereum.rb)
|
4
4
|
|
5
|
-
|
5
|
+
The goal of ethereum.rb is to make interacting with ethereum blockchain from ruby as easy as possible (but not easier).
|
6
6
|
|
7
7
|
## Highlights
|
8
8
|
|
@@ -14,8 +14,8 @@ A ruby gem for interacting with Ethereum.
|
|
14
14
|
|
15
15
|
## Compatibility and requirements
|
16
16
|
|
17
|
-
* Tested with parity 1.
|
18
|
-
* Tested with solc 0.4.
|
17
|
+
* Tested with parity 1.5.0, might work with geth (but was not tested)
|
18
|
+
* Tested with solc 0.4.9
|
19
19
|
* Ruby 2.x
|
20
20
|
* UNIX/Linux or OS X environment
|
21
21
|
|
data/lib/ethereum/contract.rb
CHANGED
@@ -77,16 +77,11 @@ module Ethereum
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def call_raw(fun, *args)
|
80
|
-
|
81
|
-
|
82
|
-
payload = [fun.signature]
|
83
|
-
arg_types.zip(args).each do |arg|
|
84
|
-
payload << @formatter.to_payload(arg)
|
85
|
-
end
|
86
|
-
raw_result = @client.eth_call({to: @address, from: @sender, data: "0x" + payload.join()})
|
80
|
+
payload = fun.signature + @encoder.encode_arguments(fun.inputs, args)
|
81
|
+
raw_result = @client.eth_call({to: @address, from: @sender, data: "0x" + payload})
|
87
82
|
raw_result = raw_result["result"]
|
88
83
|
output = @decoder.decode_arguments(fun.outputs, raw_result)
|
89
|
-
return {data: "0x" + payload
|
84
|
+
return {data: "0x" + payload, raw: raw_result, formatted: output}
|
90
85
|
end
|
91
86
|
|
92
87
|
def call(fun, *args)
|
@@ -99,15 +94,9 @@ module Ethereum
|
|
99
94
|
end
|
100
95
|
|
101
96
|
def transact(fun, *args)
|
102
|
-
|
103
|
-
|
104
|
-
payload
|
105
|
-
payload << fun.signature
|
106
|
-
arg_types.zip(args).each do |arg|
|
107
|
-
payload << @formatter.to_payload(arg)
|
108
|
-
end
|
109
|
-
txid = @client.eth_send_transaction({to: @address, from: @sender, data: "0x" + payload.join()})["result"]
|
110
|
-
return Ethereum::Transaction.new(txid, @client, payload.join(), args)
|
97
|
+
payload = fun.signature + @encoder.encode_arguments(fun.inputs, args)
|
98
|
+
txid = @client.eth_send_transaction({to: @address, from: @sender, data: "0x" + payload})["result"]
|
99
|
+
return Ethereum::Transaction.new(txid, @client, payload, args)
|
111
100
|
end
|
112
101
|
|
113
102
|
def transact_and_wait(fun, *args)
|
data/lib/ethereum/decoder.rb
CHANGED
@@ -9,18 +9,25 @@ module Ethereum
|
|
9
9
|
decode_dynamic_bytes(value, start)
|
10
10
|
elsif "string" == core
|
11
11
|
self.send(method_name, value, start)
|
12
|
+
elsif "int" == core
|
13
|
+
size = subtype.present? ? subtype.to_i : 256
|
14
|
+
self.send(method_name, value[start+63-(size/4-1)..start+63], size)
|
12
15
|
else
|
13
16
|
self.send(method_name, value[start..start+63])
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
20
|
+
def decode_fixed(value, n = 128)
|
21
|
+
decode_int(value).to_f / 2**n
|
22
|
+
end
|
23
|
+
|
17
24
|
def decode_uint(value)
|
18
25
|
value.hex
|
19
26
|
end
|
20
27
|
|
21
|
-
def decode_int(value)
|
28
|
+
def decode_int(value, size = 256)
|
22
29
|
raise ArgumentError if value.nil?
|
23
|
-
(value[0..1] == "ff") ? (value.hex - (2 **
|
30
|
+
(value[0..1] == "ff") ? (value.hex - (2 ** size)) : value.hex
|
24
31
|
end
|
25
32
|
|
26
33
|
def decode_bool(value)
|
data/lib/ethereum/encoder.rb
CHANGED
@@ -4,54 +4,59 @@ module Ethereum
|
|
4
4
|
|
5
5
|
def encode(type, value)
|
6
6
|
core, subtype = Abi::parse_type(type)
|
7
|
-
|
8
|
-
|
9
|
-
else
|
10
|
-
method_name = "encode_#{core}".to_sym
|
11
|
-
self.send(method_name, value)
|
12
|
-
end
|
7
|
+
method_name = "encode_#{core}".to_sym
|
8
|
+
self.send(method_name, value, subtype)
|
13
9
|
end
|
14
10
|
|
15
|
-
def encode_int(value)
|
11
|
+
def encode_int(value, _ = nil)
|
16
12
|
to_twos_complement(value).to_s(16).rjust(64, '0')
|
17
13
|
end
|
18
14
|
|
19
|
-
def encode_uint(value)
|
15
|
+
def encode_uint(value, _ = nil)
|
20
16
|
raise ArgumentError if value < 0
|
21
17
|
encode_int(value)
|
22
18
|
end
|
23
19
|
|
24
|
-
def encode_bool(value)
|
20
|
+
def encode_bool(value, _)
|
25
21
|
(value ? "1" : "0").rjust(64, '0')
|
26
22
|
end
|
27
23
|
|
28
|
-
def encode_fixed(
|
29
|
-
|
24
|
+
def encode_fixed(value, subtype)
|
25
|
+
n = subtype.nil? ? 128 : /(\d+)x(\d+)/.match(subtype)[2].to_i
|
26
|
+
do_encode_fixed(value, n)
|
30
27
|
end
|
31
28
|
|
32
|
-
def
|
29
|
+
def do_encode_fixed(value, n)
|
30
|
+
encode_uint((value * 2**n).to_i)
|
31
|
+
end
|
32
|
+
|
33
|
+
def encode_ufixed(_value, _)
|
33
34
|
raise NotImplementedError
|
34
35
|
end
|
35
36
|
|
36
|
-
def encode_bytes(value)
|
37
|
+
def encode_bytes(value, subtype)
|
38
|
+
subtype.nil? ? encode_dynamic_bytes(value) : encode_static_bytes(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
def encode_static_bytes(value)
|
37
42
|
value.each_char.map {|x| x.ord.to_s(16)}.join("").ljust(64, '0')
|
38
43
|
end
|
39
44
|
|
40
45
|
def encode_dynamic_bytes(value)
|
41
46
|
location = encode_uint(@inputs ? @inputs.size * 32 : 32)
|
42
47
|
size = encode_uint(value.size)
|
43
|
-
content =
|
48
|
+
content = encode_static_bytes(value)
|
44
49
|
[location, size + content]
|
45
50
|
end
|
46
51
|
|
47
|
-
def encode_string(value)
|
52
|
+
def encode_string(value, _)
|
48
53
|
location = encode_uint(@inputs ? @inputs.size * 32 : 32)
|
49
54
|
size = encode_uint(value.bytes.size)
|
50
55
|
content = value.bytes.map {|x| x.to_s(16)}.join("").ljust(64, '0')
|
51
56
|
[location, size + content]
|
52
57
|
end
|
53
58
|
|
54
|
-
def encode_address(value)
|
59
|
+
def encode_address(value, _)
|
55
60
|
value = value.gsub(/^0x/,'')
|
56
61
|
raise ArgumentError if value.size != 40
|
57
62
|
value
|
@@ -62,6 +67,7 @@ module Ethereum
|
|
62
67
|
end
|
63
68
|
|
64
69
|
def encode_arguments(inputs, args)
|
70
|
+
raise "Wrong number of arguments" if inputs.length != args.length
|
65
71
|
@head = ""
|
66
72
|
@tail = ""
|
67
73
|
@inputs = inputs
|
data/lib/ethereum/formatter.rb
CHANGED
@@ -103,43 +103,10 @@ module Ethereum
|
|
103
103
|
(hexstring.gsub(/^0x/,'')[0..1] == "ff") ? (hexstring.hex - (2 ** 256)) : hexstring.hex
|
104
104
|
end
|
105
105
|
|
106
|
-
def bool_to_payload(bool)
|
107
|
-
int_to_payload(bool ? 1 : 0)
|
108
|
-
end
|
109
|
-
|
110
|
-
def address_to_payload(address)
|
111
|
-
from_address(address)
|
112
|
-
end
|
113
|
-
|
114
|
-
def uint_to_payload(uint)
|
115
|
-
self.to_twos_complement(uint).rjust(64, '0')
|
116
|
-
end
|
117
|
-
|
118
|
-
def int_to_payload(int)
|
119
|
-
self.to_twos_complement(int).rjust(64, '0')
|
120
|
-
end
|
121
|
-
|
122
|
-
def bytes_to_payload(bytes)
|
123
|
-
self.from_utf8(bytes).ljust(64, '0')
|
124
|
-
end
|
125
|
-
|
126
|
-
def string_to_payload(bytes)
|
127
|
-
self.bytes_to_payload(bytes)
|
128
|
-
end
|
129
|
-
|
130
|
-
def construtor_params_to_payload(abi, params)
|
131
|
-
abi.map.with_index { |var, i| to_payload([var["type"], params[i]]) }.join
|
132
|
-
end
|
133
|
-
|
134
106
|
def get_base_type(typename)
|
135
107
|
typename.gsub(/\d+/,'')
|
136
108
|
end
|
137
109
|
|
138
|
-
def to_payload(args)
|
139
|
-
converter = "#{self.get_base_type(args[0])}_to_payload".to_sym
|
140
|
-
self.send(converter, args[1])
|
141
|
-
end
|
142
|
-
|
143
110
|
def from_payload(args)
|
144
111
|
converter = "output_to_#{self.get_base_type(args[0])}".to_sym
|
145
112
|
self.send(converter, args[1])
|
data/lib/ethereum/solidity.rb
CHANGED
@@ -10,38 +10,31 @@ module Ethereum
|
|
10
10
|
|
11
11
|
class Solidity
|
12
12
|
|
13
|
+
OUTPUT_REGEXP = /======= (\S*):(\S*) =======\s*Binary:\s*(\S*)\sContract JSON ABI\s(\S*)/
|
14
|
+
|
13
15
|
def initialize(bin_path = "solc")
|
14
16
|
@bin_path = bin_path
|
15
|
-
@args = "--bin --abi --
|
17
|
+
@args = "--bin --abi --add-std --optimize"
|
16
18
|
end
|
17
19
|
|
18
20
|
def compile(filename)
|
19
|
-
{}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
21
|
+
result = {}
|
22
|
+
execute_solc(nil, filename).scan(OUTPUT_REGEXP).each do |match|
|
23
|
+
file, name, bin, abi = match
|
24
|
+
result[name] = {}
|
25
|
+
result[name]["abi"] = abi
|
26
|
+
result[name]["bin"] = bin
|
26
27
|
end
|
28
|
+
result
|
27
29
|
end
|
28
|
-
|
30
|
+
|
29
31
|
private
|
30
|
-
def process_file(dir, file, result)
|
31
|
-
extension = File.extname(file)
|
32
|
-
path = "#{dir}/#{file}"
|
33
|
-
basename = File.basename(path, extension)
|
34
|
-
unless File.directory?(path)
|
35
|
-
result[basename] ||= {}
|
36
|
-
result[basename][extension[1..-1]] = File.read(path)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
32
|
def execute_solc(dir, filename)
|
41
|
-
cmd = "#{@bin_path} #{@args} '#{
|
42
|
-
|
33
|
+
cmd = "#{@bin_path} #{@args} '#{filename}'"
|
34
|
+
out, stderr, status = Open3.capture3(cmd)
|
43
35
|
raise SystemCallError, "Unanable to run solc compliers" if status.exitstatus == 127
|
44
36
|
raise CompilationError, stderr unless status.exitstatus == 0
|
37
|
+
out
|
45
38
|
end
|
46
39
|
end
|
47
40
|
end
|
data/lib/ethereum/version.rb
CHANGED
@@ -3,16 +3,17 @@ require 'open3'
|
|
3
3
|
namespace :ethereum do
|
4
4
|
namespace :node do
|
5
5
|
|
6
|
-
desc "Run testnet node
|
6
|
+
desc "Run testnet (ropsten) node"
|
7
7
|
task :test do
|
8
|
-
|
8
|
+
args = "--chain testnet -d ~/.parity"
|
9
|
+
out, _, _ = Open3.capture3("parity #{args} account list")
|
9
10
|
account = out.split(/[\[,\]]/)[1]
|
10
|
-
cmd = "parity
|
11
|
+
cmd = "parity #{args} --password ~/.parity/pass --unlock #{account} --author #{account}"
|
11
12
|
puts cmd
|
12
13
|
system cmd
|
13
14
|
end
|
14
15
|
|
15
|
-
desc "Run
|
16
|
+
desc "Run production node"
|
16
17
|
task :run do
|
17
18
|
_, out, _ = Open3.capture3("parity account list")
|
18
19
|
account = out.split(/[\[,\]]/)[1]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ethereum.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Kirejczyk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01
|
11
|
+
date: 2017-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
194
|
version: '0'
|
195
195
|
requirements: []
|
196
196
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.5.
|
197
|
+
rubygems_version: 2.5.2
|
198
198
|
signing_key:
|
199
199
|
specification_version: 4
|
200
200
|
summary: Ruby Ethereum client using the JSON-RPC interface
|