platon 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +18 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +10 -0
  6. data/Gemfile +12 -0
  7. data/Gemfile.lock +69 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +216 -0
  10. data/Rakefile +12 -0
  11. data/bin/console +15 -0
  12. data/bin/setup +8 -0
  13. data/doc/zh-cn.md +1762 -0
  14. data/lib/bech32.rb +82 -0
  15. data/lib/platon.rb +77 -0
  16. data/lib/platon/abi.rb +32 -0
  17. data/lib/platon/address.rb +62 -0
  18. data/lib/platon/client.rb +175 -0
  19. data/lib/platon/contract.rb +351 -0
  20. data/lib/platon/contract_event.rb +24 -0
  21. data/lib/platon/contract_initializer.rb +54 -0
  22. data/lib/platon/decoder.rb +99 -0
  23. data/lib/platon/deployment.rb +49 -0
  24. data/lib/platon/encoder.rb +120 -0
  25. data/lib/platon/explorer_url_helper.rb +0 -0
  26. data/lib/platon/formatter.rb +142 -0
  27. data/lib/platon/function.rb +36 -0
  28. data/lib/platon/function_input.rb +13 -0
  29. data/lib/platon/function_output.rb +14 -0
  30. data/lib/platon/gas.rb +9 -0
  31. data/lib/platon/http_client.rb +55 -0
  32. data/lib/platon/initializer.rb +0 -0
  33. data/lib/platon/ipc_client.rb +45 -0
  34. data/lib/platon/key.rb +105 -0
  35. data/lib/platon/key/decrypter.rb +113 -0
  36. data/lib/platon/key/encrypter.rb +128 -0
  37. data/lib/platon/open_ssl.rb +267 -0
  38. data/lib/platon/ppos.rb +344 -0
  39. data/lib/platon/railtie.rb +0 -0
  40. data/lib/platon/secp256k1.rb +7 -0
  41. data/lib/platon/sedes.rb +40 -0
  42. data/lib/platon/segwit_addr.rb +66 -0
  43. data/lib/platon/singleton.rb +39 -0
  44. data/lib/platon/solidity.rb +40 -0
  45. data/lib/platon/transaction.rb +41 -0
  46. data/lib/platon/tx.rb +201 -0
  47. data/lib/platon/utils.rb +180 -0
  48. data/lib/platon/version.rb +5 -0
  49. data/lib/tasks/platon_contract.rake +27 -0
  50. data/platon-ruby-logo.png +0 -0
  51. data/platon.gemspec +50 -0
  52. metadata +235 -0
@@ -0,0 +1,267 @@
1
+ # originally lifted from https://github.com/lian/bitcoin-ruby
2
+ # thanks to everyone there for figuring this out
3
+
4
+ module Platon
5
+ class OpenSsl
6
+ extend FFI::Library
7
+
8
+ if FFI::Platform.windows?
9
+ ffi_lib 'libeay32', 'ssleay32'
10
+ else
11
+ ffi_lib [
12
+ 'libssl.so.1.1.0', 'libssl.so.1.1',
13
+ 'libssl.so.1.0.0', 'libssl.so.10',
14
+ 'ssl'
15
+ ]
16
+ end
17
+
18
+ NID_secp256k1 = 714
19
+ POINT_CONVERSION_COMPRESSED = 2
20
+ POINT_CONVERSION_UNCOMPRESSED = 4
21
+
22
+ # OpenSSL 1.1.0 version as a numerical version value as defined in:
23
+ # https://www.openssl.org/docs/man1.1.0/man3/OpenSSL_version.html
24
+ VERSION_1_1_0_NUM = 0x10100000
25
+
26
+ # OpenSSL 1.1.0 engine constants, taken from:
27
+ # https://github.com/openssl/openssl/blob/2be8c56a39b0ec2ec5af6ceaf729df154d784a43/include/openssl/crypto.h
28
+ OPENSSL_INIT_ENGINE_RDRAND = 0x00000200
29
+ OPENSSL_INIT_ENGINE_DYNAMIC = 0x00000400
30
+ OPENSSL_INIT_ENGINE_CRYPTODEV = 0x00001000
31
+ OPENSSL_INIT_ENGINE_CAPI = 0x00002000
32
+ OPENSSL_INIT_ENGINE_PADLOCK = 0x00004000
33
+ OPENSSL_INIT_ENGINE_ALL_BUILTIN = (
34
+ OPENSSL_INIT_ENGINE_RDRAND |
35
+ OPENSSL_INIT_ENGINE_DYNAMIC |
36
+ OPENSSL_INIT_ENGINE_CRYPTODEV |
37
+ OPENSSL_INIT_ENGINE_CAPI |
38
+ OPENSSL_INIT_ENGINE_PADLOCK
39
+ )
40
+
41
+ # OpenSSL 1.1.0 load strings constant, taken from:
42
+ # https://github.com/openssl/openssl/blob/c162c126be342b8cd97996346598ecf7db56130f/include/openssl/ssl.h
43
+ OPENSSL_INIT_LOAD_SSL_STRINGS = 0x00200000
44
+
45
+ # This is the very first function we need to use to determine what version
46
+ # of OpenSSL we are interacting with.
47
+ begin
48
+ attach_function :OpenSSL_version_num, [], :ulong
49
+ rescue FFI::NotFoundError
50
+ attach_function :SSLeay, [], :long
51
+ end
52
+
53
+ # Returns the version of SSL present.
54
+ #
55
+ # @return [Integer] version number as an integer.
56
+ def self.version
57
+ if self.respond_to?(:OpenSSL_version_num)
58
+ OpenSSL_version_num()
59
+ else
60
+ SSLeay()
61
+ end
62
+ end
63
+
64
+ # if version >= VERSION_1_1_0_NUM
65
+
66
+ # # Initialization procedure for the library was changed in OpenSSL 1.1.0
67
+ # attach_function :OPENSSL_init_ssl, [:uint64, :pointer], :int
68
+ # else
69
+
70
+ attach_function :SSL_library_init, [], :int
71
+ attach_function :ERR_load_crypto_strings, [], :void
72
+ attach_function :SSL_load_error_strings, [], :void
73
+ # end
74
+
75
+ attach_function :RAND_poll, [], :int
76
+ attach_function :BN_CTX_free, [:pointer], :int
77
+ attach_function :BN_CTX_new, [], :pointer
78
+ attach_function :BN_add, [:pointer, :pointer, :pointer], :int
79
+ attach_function :BN_bin2bn, [:pointer, :int, :pointer], :pointer
80
+ attach_function :BN_bn2bin, [:pointer, :pointer], :int
81
+ attach_function :BN_cmp, [:pointer, :pointer], :int
82
+ attach_function :BN_dup, [:pointer], :pointer
83
+ attach_function :BN_free, [:pointer], :int
84
+ attach_function :BN_mod_inverse, [:pointer, :pointer, :pointer, :pointer], :pointer
85
+ attach_function :BN_mod_mul, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
86
+ attach_function :BN_mod_sub, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
87
+ attach_function :BN_mul_word, [:pointer, :int], :int
88
+ attach_function :BN_new, [], :pointer
89
+ attach_function :BN_num_bits, [:pointer], :int
90
+ attach_function :BN_rshift, [:pointer, :pointer, :int], :int
91
+ attach_function :BN_set_word, [:pointer, :int], :int
92
+ attach_function :ECDSA_SIG_free, [:pointer], :void
93
+ attach_function :ECDSA_do_sign, [:pointer, :uint, :pointer], :pointer
94
+ attach_function :EC_GROUP_get_curve_GFp, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
95
+ attach_function :EC_GROUP_get_degree, [:pointer], :int
96
+ attach_function :EC_GROUP_get_order, [:pointer, :pointer, :pointer], :int
97
+ attach_function :EC_KEY_free, [:pointer], :int
98
+ attach_function :EC_KEY_get0_group, [:pointer], :pointer
99
+ attach_function :EC_KEY_new_by_curve_name, [:int], :pointer
100
+ attach_function :EC_KEY_set_conv_form, [:pointer, :int], :void
101
+ attach_function :EC_KEY_set_private_key, [:pointer, :pointer], :int
102
+ attach_function :EC_KEY_set_public_key, [:pointer, :pointer], :int
103
+ attach_function :EC_POINT_free, [:pointer], :int
104
+ attach_function :EC_POINT_mul, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
105
+ attach_function :EC_POINT_new, [:pointer], :pointer
106
+ attach_function :EC_POINT_set_compressed_coordinates_GFp, [:pointer, :pointer, :pointer, :int, :pointer], :int
107
+ attach_function :i2o_ECPublicKey, [:pointer, :pointer], :uint
108
+
109
+ class << self
110
+ def BN_num_bytes(ptr)
111
+ (BN_num_bits(ptr) + 7) / 8
112
+ end
113
+
114
+ def sign_compact(hash, private_key, public_key_hex)
115
+ private_key = [private_key].pack("H*") if private_key.bytesize >= 64
116
+ pubkey_compressed = false
117
+
118
+ init_ffi_ssl
119
+ eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
120
+ priv_key = BN_bin2bn(private_key, private_key.bytesize, BN_new())
121
+
122
+ group, order, ctx = EC_KEY_get0_group(eckey), BN_new(), BN_CTX_new()
123
+ EC_GROUP_get_order(group, order, ctx)
124
+
125
+ pub_key = EC_POINT_new(group)
126
+ EC_POINT_mul(group, pub_key, priv_key, nil, nil, ctx)
127
+ EC_KEY_set_private_key(eckey, priv_key)
128
+ EC_KEY_set_public_key(eckey, pub_key)
129
+
130
+ signature = ECDSA_do_sign(hash, hash.bytesize, eckey)
131
+
132
+ BN_free(order)
133
+ BN_CTX_free(ctx)
134
+ EC_POINT_free(pub_key)
135
+ BN_free(priv_key)
136
+ EC_KEY_free(eckey)
137
+
138
+ buf, rec_id, head = FFI::MemoryPointer.new(:uint8, 32), nil, nil
139
+ r, s = signature.get_array_of_pointer(0, 2).map{|i| BN_bn2bin(i, buf); buf.read_string(BN_num_bytes(i)).rjust(32, "\x00") }
140
+
141
+ if signature.get_array_of_pointer(0, 2).all?{|i| BN_num_bits(i) <= 256 }
142
+ 4.times{|i|
143
+ head = [ Platon.v_base + i ].pack("C")
144
+ if public_key_hex == recover_public_key_from_signature(hash, [head, r, s].join, i, pubkey_compressed)
145
+ rec_id = i; break
146
+ end
147
+ }
148
+ end
149
+
150
+ ECDSA_SIG_free(signature)
151
+
152
+ [ head, [r,s] ].join if rec_id
153
+ end
154
+
155
+ def recover_public_key_from_signature(message_hash, signature, rec_id, is_compressed)
156
+ return nil if rec_id < 0 or signature.bytesize != 65
157
+ init_ffi_ssl
158
+
159
+ signature = FFI::MemoryPointer.from_string(signature)
160
+ r = BN_bin2bn(signature[1], 32, BN_new())
161
+ s = BN_bin2bn(signature[33], 32, BN_new())
162
+
163
+ _n, i = 0, rec_id / 2
164
+ eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
165
+
166
+ EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED) if is_compressed
167
+
168
+ group = EC_KEY_get0_group(eckey)
169
+ order = BN_new()
170
+ EC_GROUP_get_order(group, order, nil)
171
+ x = BN_dup(order)
172
+ BN_mul_word(x, i)
173
+ BN_add(x, x, r)
174
+
175
+ field = BN_new()
176
+ EC_GROUP_get_curve_GFp(group, field, nil, nil, nil)
177
+
178
+ if BN_cmp(x, field) >= 0
179
+ bn_free_each r, s, order, x, field
180
+ EC_KEY_free(eckey)
181
+ return nil
182
+ end
183
+
184
+ big_r = EC_POINT_new(group)
185
+ EC_POINT_set_compressed_coordinates_GFp(group, big_r, x, rec_id % 2, nil)
186
+
187
+ big_q = EC_POINT_new(group)
188
+ n = EC_GROUP_get_degree(group)
189
+ e = BN_bin2bn(message_hash, message_hash.bytesize, BN_new())
190
+ BN_rshift(e, e, 8 - (n & 7)) if 8 * message_hash.bytesize > n
191
+
192
+ ctx = BN_CTX_new()
193
+ zero, rr, sor, eor = BN_new(), BN_new(), BN_new(), BN_new()
194
+ BN_set_word(zero, 0)
195
+ BN_mod_sub(e, zero, e, order, ctx)
196
+ BN_mod_inverse(rr, r, order, ctx)
197
+ BN_mod_mul(sor, s, rr, order, ctx)
198
+ BN_mod_mul(eor, e, rr, order, ctx)
199
+ EC_POINT_mul(group, big_q, eor, big_r, sor, ctx)
200
+ EC_KEY_set_public_key(eckey, big_q)
201
+ BN_CTX_free(ctx)
202
+
203
+ bn_free_each r, s, order, x, field, e, zero, rr, sor, eor
204
+ [big_r, big_q].each{|j| EC_POINT_free(j) }
205
+
206
+ recover_public_hex eckey
207
+ end
208
+
209
+ def recover_compact(hash, signature)
210
+ return false if signature.bytesize != 65
211
+
212
+ version = signature.unpack('C')[0]
213
+
214
+ # Version of signature should be 27 or 28, but 0 and 1 are also possible versions
215
+ # which can show up in Ledger hardwallet signings
216
+ if version < 27
217
+ version += 27
218
+ end
219
+
220
+ v_base = Platon.replayable_v?(version) ? Platon.replayable_chain_id : Platon.v_base
221
+
222
+ return false if version < v_base
223
+
224
+ recover_public_key_from_signature(hash, signature, (version - v_base), false)
225
+ end
226
+
227
+ def init_ffi_ssl
228
+ return if @ssl_loaded
229
+
230
+ # if version >= VERSION_1_1_0_NUM
231
+ # OPENSSL_init_ssl(
232
+ # OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_ENGINE_ALL_BUILTIN,
233
+ # nil
234
+ # )
235
+ # else
236
+ SSL_library_init()
237
+ ERR_load_crypto_strings()
238
+ SSL_load_error_strings()
239
+ # end
240
+
241
+ RAND_poll()
242
+ @ssl_loaded = true
243
+ end
244
+
245
+
246
+ private
247
+
248
+ def bn_free_each(*list)
249
+ list.each{|j| BN_free(j) }
250
+ end
251
+
252
+ def recover_public_hex(eckey)
253
+ length = i2o_ECPublicKey(eckey, nil)
254
+ buf = FFI::MemoryPointer.new(:uint8, length)
255
+ ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
256
+ pub_hex = if i2o_ECPublicKey(eckey, ptr) == length
257
+ buf.read_string(length).unpack("H*")[0]
258
+ end
259
+
260
+ EC_KEY_free(eckey)
261
+
262
+ pub_hex
263
+ end
264
+ end
265
+
266
+ end
267
+ end
@@ -0,0 +1,344 @@
1
+ module Platon
2
+ class Ppos
3
+
4
+ PARAMS_ORDER = {
5
+ "1000"=> ['typ', 'benefitAddress', 'nodeId', 'externalId', 'nodeName', 'website', 'details', 'amount', 'rewardPer', 'programVersion', 'programVersionSign', 'blsPubKey', 'blsProof'],
6
+ "1001"=> ['benefitAddress', 'nodeId', 'rewardPer', 'externalId', 'nodeName', 'website', 'details'],
7
+ "1002"=> ['nodeId', 'typ', 'amount'],
8
+ "1003"=> ['nodeId'],
9
+ "1004"=> ['typ', 'nodeId', 'amount'],
10
+ "1005"=> ['stakingBlockNum', 'nodeId', 'amount'],
11
+ "1100"=> [],
12
+ "1101"=> [],
13
+ "1102"=> [],
14
+ "1103"=> ['addr'],
15
+ "1104"=> ['stakingBlockNum', 'delAddr', 'nodeId'],
16
+ "1105"=> ['nodeId'],
17
+ "1200"=> [],
18
+ "1201"=> [],
19
+ "1202"=> [],
20
+
21
+ "2000"=> ['verifier', 'pIDID'],
22
+ "2001"=> ['verifier', 'pIDID', 'newVersion', 'endVotingRounds'],
23
+ "2002"=> ['verifier', 'pIDID', 'module', 'name', 'newValue'],
24
+ "2005"=> ['verifier', 'pIDID', 'endVotingRounds', 'tobeCanceledProposalID'],
25
+ "2003"=> ['verifier', 'proposalID', 'option', 'programVersion', 'versionSign'],
26
+ "2004"=> ['verifier', 'programVersion', 'versionSign'],
27
+ "2100"=> ['proposalID'],
28
+ "2101"=> ['proposalID'],
29
+ "2102"=> [],
30
+ "2103"=> [],
31
+ "2104"=> ['module', 'name'],
32
+ "2105"=> ['proposalID', 'blockHash'],
33
+ "2106"=> ['module'],
34
+
35
+ "3000"=> ['typ', 'data'],
36
+ "3001"=> ['typ', 'addr', 'blockNumber'],
37
+
38
+ "4000"=> ['account', 'plan'],
39
+ "4100"=> ['account'],
40
+
41
+ "5000"=> [],
42
+ "5100"=> ['address', 'nodeIDs']
43
+ }
44
+
45
+ def initialize(client)
46
+ @client = client
47
+ end
48
+
49
+ def params_to_data(params) #params should be Array
50
+ arr =params.map{|param| RLP.encode(param)}
51
+ rlpData = "0x"+RLP.encode(arr).unpack("H*").first
52
+ end
53
+
54
+ def obj_to_params(params)
55
+ return params if params.instance_of?(Array)
56
+ pars = [params["funcType"]]
57
+ order = PARAMS_ORDER[params["funcType"].to_s]
58
+ order.each do |key|
59
+ pars << params[key]
60
+ end
61
+ return pars
62
+ end
63
+
64
+ def funcType_to_address(funcType)
65
+ case funcType
66
+ when 1000...2000
67
+ return "0x1000000000000000000000000000000000000002"
68
+ when 2000...3000
69
+ return "0x1000000000000000000000000000000000000005"
70
+ when 3000...4000
71
+ return "0x1000000000000000000000000000000000000004"
72
+ when 4000...5000
73
+ return "0x1000000000000000000000000000000000000001"
74
+ when 5000...6000
75
+ return "0x1000000000000000000000000000000000000006"
76
+ end
77
+ end
78
+
79
+ def funcType_to_bech32(hrp,funcType) ### TODO!!!
80
+ case funcType
81
+ when 1000...2000
82
+ return Utils.to_bech32_address(hrp,"0x1000000000000000000000000000000000000002")
83
+ when 2000...3000
84
+ return Utils.to_bech32_address(hrp,"0x1000000000000000000000000000000000000005")
85
+ when 3000...4000
86
+ return Utils.to_bech32_address(hrp,"0x1000000000000000000000000000000000000004")
87
+ when 4000...5000
88
+ return Utils.to_bech32_address(hrp,"0x1000000000000000000000000000000000000001")
89
+ when 5000...6000
90
+ return Utils.to_bech32_address(hrp,"0x1000000000000000000000000000000000000006")
91
+ end
92
+ end
93
+
94
+ def ppos_hex_to_obj(hex_str)
95
+ hex_str = hex_str.downcase.start_with?("0x") ? hex_str[2..-1] : hex_str
96
+ str = JSON.parse([hex_str].pack("H*")) rescue ""
97
+ if(str["Data"].instance_of?(String))
98
+ str["Data"] = JSON.parse(str["Data"]) rescue ""
99
+ end
100
+ return str
101
+ end
102
+
103
+ def call(params,block_param="latest") ##注意:个别参数需提前 hex_to_bin
104
+ begin
105
+ rawTx = {}
106
+ params = obj_to_params(params)
107
+
108
+ rawTx["data"] = params_to_data(params)
109
+ rawTx["to"] = funcType_to_bech32(@client.hrp,params[0])
110
+ data = @client.platon_call(rawTx,block_param)
111
+
112
+ return ppos_hex_to_obj(data)
113
+
114
+ rescue Exception => e
115
+ # puts "ppos call error :#{e}"
116
+ puts e.backtrace
117
+ end
118
+ end
119
+
120
+ def send(key,params,other=nil)
121
+ raise ArgumentError, "key or chain_id is not exist." if key == nil || @client.chain_id == nil
122
+
123
+ begin
124
+
125
+ rawTx = {
126
+ from:key.address,
127
+ to: funcType_to_address(params[0]),
128
+ data: params_to_data(obj_to_params(params)),
129
+ nonce: @client.get_nonce(key.bech32_address(hrp:@client.hrp)),
130
+ gas_limit: (other && other[:gas_limit])|| @client.gas_limit,
131
+ gas_price: (other && other[:gas_price]) || @client.gas_price,
132
+ chain_id: @client.chain_id,
133
+ value:0
134
+ }
135
+ # p rawTx
136
+ tx = Platon::Tx.new(rawTx)
137
+ tmp = tx.sign key
138
+ # p tmp
139
+ @client.platon_send_raw_transaction(tx.hex)
140
+
141
+ rescue Exception => e
142
+ # puts "ppos send error :#{e}"
143
+ puts e.backtrace
144
+ end
145
+
146
+
147
+ end
148
+
149
+ def create_staking(key,typ,benefit_address,node_id,external_id,node_name,website,details,amount,reward_per,program_version,program_version_sign,bls_pub_key,bls_proof) #(1000)
150
+ send key,[1000,
151
+ typ,
152
+ Utils.bech32_to_bin(benefit_address),
153
+ Utils.hex_to_bin(node_id),
154
+ Utils.hex_to_bin(external_id),
155
+ node_name,
156
+ website,
157
+ details,
158
+ Platon::Formatter.new.to_von(amount),
159
+ reward_per,
160
+ program_version, #client.admin_get_program_version 获取
161
+ Utils.hex_to_bin(program_version_sign), #client.admin_get_program_version 获取
162
+ Utils.hex_to_bin(bls_pub_key),
163
+ Utils.hex_to_bin(bls_proof) ## client.admin_get_schnorr_nizk_prove获取
164
+ ]
165
+ end
166
+
167
+ def update_staking_info(key,benefit_address,node_id,reward_per,external_id,node_name,website,details) #(1001)
168
+ send key,[1001,
169
+ Utils.bech32_to_bin(benefit_address),
170
+ Utils.hex_to_bin(node_id),
171
+ reward_per,
172
+ Utils.hex_to_bin(external_id),
173
+ node_name,
174
+ website,
175
+ details
176
+ ]
177
+ end
178
+
179
+ def add_staking(key,node_id,typ,amount) # (1002)
180
+ send key,[1002,
181
+ Utils.hex_to_bin(node_id),
182
+ typ,
183
+ Platon::Formatter.new.to_von(amount)
184
+ ]
185
+ end
186
+
187
+ # 撤销质押(一次性发起全部撤销,多次到账)
188
+ def cancel_staking(key,node_id) #(1003)
189
+ send key,[1003,
190
+ Utils.hex_to_bin(node_id)
191
+ ]
192
+ end
193
+
194
+ # 发起委托,委托已质押节点,委托给某个节点增加节点权重来获取收入
195
+ def delegate(key,typ,node_id,amount) #(1004)
196
+ send key,[1004,typ,Utils.hex_to_bin(node_id),amount]
197
+ end
198
+
199
+ # 减持/撤销委托(全部减持就是撤销)
200
+ def reduce_delegate(key,staking_block_num,node_id,amount) #(1005)
201
+ send key,[1005,staking_block_num,Utils.hex_to_bin(node_id),amount]
202
+ end
203
+
204
+ ## 查询当前结算周期的验证人队列,返回101个
205
+ def get_epoch_validators(block_param="latest") #(1100)
206
+ call [1100],block_param
207
+ end
208
+
209
+ ## 查询当前共识周期的验证人队列,返回25个
210
+ def get_round_validators(block_param="latest") #(1101)
211
+ call [1101],block_param
212
+ end
213
+
214
+ ## 查询实时候选人列表,返回全部。包含当前验证人
215
+ def get_current_candidates(block_param="latest") #(1102)
216
+ call [1102],block_param
217
+ end
218
+
219
+ def get_delegate_nodeids_by_addr(address,block_param="latest") #(1103)
220
+ call [1103, Utils.bech32_to_bin(address)],block_param
221
+ end
222
+
223
+ # 查询单个委托信息
224
+ def get_address_delegate_info(staking_block_num, address, node_id, block_param="latest")
225
+ call [1104, staking_block_num, Utils.bech32_to_bin(address), Utils.hex_to_bin(node_id)],block_param
226
+ end
227
+
228
+ #
229
+ def get_node_delegate_info(node_id,block_param="latest")
230
+ res = call([1105,Utils.hex_to_bin(node_id)],block_param)
231
+ # format_res_values res,["Shares","Released","ReleasedHes","RestrictingPlan","RestrictingPlanHes","DelegateTotal","DelegateTotalHes","DelegateRewardTotal"]
232
+ end
233
+
234
+ def get_block_reward(block_param="latest")
235
+ call [1200],block_param
236
+ end
237
+
238
+ def get_staking_reward(block_param="latest")
239
+ call [1201],block_param
240
+ end
241
+
242
+ # 提交文本提案
243
+ def submit_proposal(key,verifier,pIDID,other=nil)#2000
244
+ send key,[2000,Utils.hex_to_bin(verifier),pIDID],other
245
+ end
246
+ # 提交升级提案
247
+ def update_proposal(key, verifier,pIDID, new_version,end_voting_rounds,other=nil) #2001
248
+ send key,[2001,Utils.hex_to_bin(verifier), pIDID, new_version,end_voting_rounds],other
249
+ end
250
+
251
+ # 提交取消提案
252
+ def cancel_proposal(key,verifier,pIDID,end_voting_rounds,to_be_canceled_proposal_id,other=nil)#2005
253
+ send key,[2005,Utils.hex_to_bin(verifier), pIDID, end_voting_rounds , to_be_canceled_proposal_id],other
254
+ end
255
+
256
+ # 给提案投票
257
+ def vote_proposal(key,verifier,proposal_id,option,program_version,version_sign,other=nil)#2003
258
+ send key,[2003,Utils.hex_to_bin(verifier),Utils.hex_to_bin(proposal_id),option,program_version,Utils.hex_to_bin(version_sign)],other
259
+ end
260
+
261
+ # 版本声明
262
+ def declare_version(key,verifier,program_version,version_sign) #2004
263
+ send key,[2004,Utils.hex_to_bin(verifier),program_version,Utils.hex_to_bin(version_sign)],other
264
+ end
265
+
266
+ # 查询提案列表
267
+ def get_proposals(block_param="latest") #2102
268
+ call [2102],block_param
269
+ end
270
+
271
+ # 提案查询
272
+ def get_proposal_info(proposal_id,block_param="latest") #2100
273
+ call [2100,Utils.hex_to_bin(proposal_id)],block_param
274
+ end
275
+
276
+ # 查询提案结果
277
+ def get_proposal_result(proposal_id,block_param="latest") #2101
278
+ call [2101,Utils.hex_to_bin(proposal_id)],block_param
279
+ end
280
+
281
+ # 查询节点的链生效版本
282
+ def get_version_in_effect(block_param="latest") #2103
283
+ call [2103],block_param
284
+ end
285
+
286
+ # 查询提案的投票人数
287
+ def get_votes_number(proposal_id,block_hash,block_param="latest") #2105
288
+ call [2105, Utils.hex_to_bin(proposal_id),Utils.hex_to_bin(block_hash)]
289
+ end
290
+
291
+ # 查询治理参数列表
292
+ def get_govern_params(module_name,block_param="latest") # 2106
293
+ call [2106, module_name],block_param
294
+ end
295
+
296
+ # 查询当前块高的治理参数值
297
+ def get_govern_param_value(module_name, name,block_param="latest") #2104
298
+ call [2104,module_name,name],block_param
299
+ end
300
+
301
+ # 举报双签
302
+ def report_duplicate_sign(key,duplicate_sign_type,data,other=nil)#3000
303
+ send key,[3000,duplicate_sign_type,data],other
304
+ end
305
+ # 查询节点被举报情况
306
+ def get_node_oversign(type,node_id,block_number,block_param="latest") #3001
307
+ call [3001,type,Utils.hex_to_bin(node_id),block_number],block_param
308
+ end
309
+
310
+ # 创建锁仓计划 4000
311
+ def create_restricting_plan(key,account,restricting_plans)
312
+ send key,[4000,
313
+ Utils.bech32_to_bin(account),
314
+ restricting_plans
315
+ ]
316
+ end
317
+
318
+ # 获取锁仓信息 4100
319
+ def get_restricting_info(account,block_param="latest")
320
+ call [4100, Utils.bech32_to_bin(account)],block_param
321
+ end
322
+
323
+ #################奖励接口
324
+ ## 提取委托奖励
325
+ # 5000
326
+ def withdraw_delegate_reward(key)
327
+ send key,[5000]
328
+ end
329
+
330
+ ## 查询未提取的委托奖励
331
+ def get_delegate_reward(address,node_ids=[],block_param="latest")
332
+ call [5100,Utils.bech32_to_bin(address),node_ids.map{|item| Utils.hex_to_bin(item)}],block_param
333
+ end
334
+
335
+ private
336
+ # def format_res_values(res,keys)
337
+ # keys.each do |key|
338
+ # res["Ret"][key] = res["Ret"][key].to_i(16)
339
+ # end
340
+ # res
341
+ # end
342
+
343
+ end
344
+ end