ethlite 0.2.4 → 0.2.5

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 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