platon 0.2.7

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