ethlite 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6a9601ad8c91c592541ffc721dbe9bbb8572683ef88c995a1bb810f7da79e33
4
- data.tar.gz: 4ddf8c5a91c9a370e580bc9519f4d7c9832f863f31e4dfb8fa2b0505c2c6d6e0
3
+ metadata.gz: 3cd659223f8049ca63302c5bb595da6faf483d29d776ed747b5970dde11b415e
4
+ data.tar.gz: fde6fca03683dac98d474d82bc520a82dc45e74b08eaabbc0c521e2635ca3d3b
5
5
  SHA512:
6
- metadata.gz: 12d4cd45f40f8ecf3835f058e2ac5d4e9a9b361e3cd91fd5bca193e982c7fd726ff3ffab08ed7bedb543c3800e76808364c51f2992d4971816629ac170f700f6
7
- data.tar.gz: 236164ce176d5b50187e7402729a895130354f929df269e3b9d7b04472300b1661b9992a5579ba53064cbe0b7aee95e21aeeaae65225519ca55707caad771533
6
+ metadata.gz: 050226ff51c20a38cb8f1db254e246a555d07baf8a6e12766985850400749a463698e89818780cd031e5ed3cab6bb05e2afae37588149084160138d5e6783e0f
7
+ data.tar.gz: 0d16770efc489cf88f08ec8ef471563905b2197c1d8330c58558348f1a9076dd717f654b5c221ea78052d31855bb458105c79f2f7ec1021a04451a202088b722
data/README.md CHANGED
@@ -11,10 +11,178 @@ ethlite - light-weight machinery to query / call ethereum (blockchain contract)
11
11
 
12
12
 
13
13
 
14
-
15
14
  ## Usage
16
15
 
17
- to be done
16
+
17
+ ### Step 0: Setup JSON RPC Client
18
+
19
+ ```ruby
20
+ ## let's use a simple JSON RPC client
21
+ ## get the eth node uri via the INFURA_URI enviroment variable / key
22
+ ## e.g. https://mainnet.infura.io/v3/<YOUR_KEY_HERE>
23
+ ETH_NODE = JsonRpc.new( ENV['INFURA_URI'] )
24
+ ```
25
+
26
+
27
+
28
+ ### Do-It-Yourself (DIY) JSON RPC eth_call With "Hand-Coded" To-The-Metal ABI Encoding/Decoding
29
+
30
+
31
+ Let's try to build a JSON-RPC request from scratch calling
32
+ a (constant/read-only/view) blockchain contract method via `eth_call`.
33
+
34
+ Let's try `function tokenURI(uint256 tokenId) returns (string)`
35
+ that lets you request the metdata uri for a (non-fungible) token.
36
+
37
+ Let's try the Moonbirds contract @ [0x23581767a106ae21c074b2276d25e5c3e136a68b](https://etherscan.io/address/0x23581767a106ae21c074b2276d25e5c3e136a68b):
38
+
39
+ ```ruby
40
+ ## contract address - let's try moonbirds
41
+ contract_address = '0x23581767a106ae21c074b2276d25e5c3e136a68b'
42
+
43
+ token_ids = (0..9)
44
+ token_ids.each do |token_id|
45
+
46
+ puts "==> calling tokenURI(#{token_id})..."
47
+ tokenURI = eth_call( contract_address,
48
+ 'tokenURI', ['uint256'], ['string'],
49
+ [token_id] )
50
+ puts " ...returns: #{tokenURI}"
51
+ end
52
+ ```
53
+
54
+
55
+ And the "magic" hand-coded to-the-metal `eth_call` machinery:
56
+
57
+ ```ruby
58
+ ## construct a json-rpc call from scratch
59
+ def eth_call( contract_address,
60
+ name, inputs, outputs,
61
+ args )
62
+
63
+ ## binary encode method sig(nature)
64
+ signature = "#{name}(#{inputs.join(',')})"
65
+ signature_hash = Ethlite::Abi::Utils.encode_hex(
66
+ Ethlite::Abi::Utils.keccak256(signature))[0..7]
67
+
68
+ pp signature
69
+ # => "tokenURI(uint256)"
70
+ pp signature_hash
71
+ # => "c87b56dd"
72
+
73
+ ## binary encode method arg(ument)s
74
+ args_encoded = Ethlite::Abi::Utils.encode_hex(
75
+ Ethlite::Abi::AbiCoder.encode_abi( inputs, args) )
76
+
77
+ data = '0x' + signature_hash + args_encoded
78
+
79
+ ## json-rpc method and params
80
+ method = 'eth_call'
81
+ params = [{ to: contract_address,
82
+ data: data},
83
+ 'latest'
84
+ ]
85
+
86
+ ## do the json-rpc request
87
+ response = ETH_NODE.request( method, params )
88
+
89
+ puts "response:"
90
+ pp response
91
+
92
+ ## decode binary result
93
+ string_data = Ethlite::Abi::Utils.decode_hex(
94
+ Ethlite::Abi::Utils.remove_0x_head(response))
95
+ result = Ethlite::Abi::AbiCoder.decode_abi( outputs, string_data )
96
+ result.length == 1 ? result[0] : result
97
+ end
98
+ ```
99
+
100
+ resulting in (with debug json rpc request/reponse output):
101
+
102
+
103
+ calling `tokenURI(0)`... json_rpc POST payload request:
104
+
105
+ ``` json
106
+ {"jsonrpc":"2.0",
107
+ "method":"eth_call",
108
+ "params":[
109
+ {"to":"0x23581767a106ae21c074b2276d25e5c3e136a68b",
110
+ "data":"0xc87b56dd0000000000000000000000000000000000000000000000000000000000000000"},
111
+ "latest"],
112
+ "id":1
113
+ }
114
+ ```
115
+
116
+ json_rpc response:
117
+
118
+ ``` json
119
+ {"jsonrpc":"2.0",
120
+ "id":1,"result":"0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6c6976652d2d2d6d657461646174612d35636f767071696a61612d75632e612e72756e2e6170702f6d657461646174612f30000000000000"
121
+ }
122
+ ```
123
+
124
+ ...returns: `https://live---metadata-5covpqijaa-uc.a.run.app/metadata/0`
125
+
126
+
127
+ calling `tokenURI(1)...` json_rpc POST payload request:
128
+
129
+ ``` json
130
+ {"jsonrpc":"2.0",
131
+ "method":"eth_call",
132
+ "params":[
133
+ {"to":"0x23581767a106ae21c074b2276d25e5c3e136a68b",
134
+ "data":"0xc87b56dd0000000000000000000000000000000000000000000000000000000000000001"},
135
+ "latest"],
136
+ "id":2
137
+ }
138
+ ```
139
+
140
+ json_rpc response:
141
+
142
+ ``` json
143
+ {"jsonrpc":"2.0",
144
+ "id":2,"result":"0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6c6976652d2d2d6d657461646174612d35636f767071696a61612d75632e612e72756e2e6170702f6d657461646174612f31000000000000"
145
+ }
146
+ ```
147
+
148
+ ...returns: `https://live---metadata-5covpqijaa-uc.a.run.app/metadata/1`
149
+
150
+
151
+
152
+ ### JSON RPC eth_call With ContractMethod Helper
153
+
154
+ Let's retry using the convenience builtin
155
+ `ContractMethod` helper:
156
+
157
+ ```ruby
158
+ ## contract address - let's try moonbirds
159
+ contract_address = '0x23581767a106ae21c074b2276d25e5c3e136a68b'
160
+
161
+ ETH_tokenURI = Ethlite::ContractMethod.new( 'tokenURI',
162
+ inputs: ['uint256'],
163
+ outputs: ['string'] )
164
+
165
+ token_ids = (0..9)
166
+ token_ids.each do |token_id|
167
+ puts "==> tokenURI(#{token_id}) returns:"
168
+ pp ETH_tokenURI.do_call( ETH_NODE, contract_address, [token_id] )
169
+ end
170
+ ```
171
+
172
+ resulting in:
173
+
174
+ ```
175
+ ==> tokenURI(0) returns:
176
+ "https://live---metadata-5covpqijaa-uc.a.run.app/metadata/0"
177
+ ==> tokenURI(1) returns:
178
+ "https://live---metadata-5covpqijaa-uc.a.run.app/metadata/1"
179
+ ==> tokenURI(2) returns:
180
+ "https://live---metadata-5covpqijaa-uc.a.run.app/metadata/3"
181
+ ...
182
+ ```
183
+
184
+
185
+ And so on and so forth.
18
186
 
19
187
 
20
188
 
@@ -70,7 +70,7 @@ module Abi
70
70
  end
71
71
 
72
72
  def decode_hex(str)
73
- raise TypeError, "Value must be an instance of string" unless sstr.instance_of?(String)
73
+ raise TypeError, "Value must be an instance of string" unless str.instance_of?(String)
74
74
  raise TypeError, 'Non-hexadecimal digit found' unless str =~ /\A[0-9a-fA-F]*\z/
75
75
  [str].pack("H*")
76
76
  end
@@ -63,7 +63,8 @@
63
63
  puts "response:"
64
64
  pp response
65
65
 
66
- string_data = [Abi::Utils.remove_0x_head(response)].pack('H*')
66
+ string_data = Abi::Utils.decode_hex(
67
+ Abi::Utils.remove_0x_head(response))
67
68
  return nil if string_data.empty?
68
69
 
69
70
  result = Abi::AbiCoder.decode_abi( @output_types, string_data )
@@ -3,7 +3,7 @@
3
3
  module Ethlite
4
4
  MAJOR = 0
5
5
  MINOR = 2
6
- PATCH = 4
6
+ PATCH = 5
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
@@ -23,7 +23,7 @@ class JsonRpc
23
23
 
24
24
  @request_id += 1
25
25
 
26
- puts "json POST payload:"
26
+ puts "json_rpc POST payload:"
27
27
  puts data.to_json
28
28
 
29
29
  response = Webclient.post( @uri, json: data )
@@ -33,6 +33,9 @@ class JsonRpc
33
33
  raise "Error code #{response.status.code} on request #{@uri} #{data}"
34
34
  end
35
35
 
36
+ puts "json_rpc response.body:"
37
+ puts response.body
38
+
36
39
 
37
40
  body = JSON.parse( response.body, max_nesting: 1500 )
38
41
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ethlite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-19 00:00:00.000000000 Z
11
+ date: 2022-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocos