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.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +69 -0
- data/LICENSE.txt +21 -0
- data/README.md +216 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/doc/zh-cn.md +1762 -0
- data/lib/bech32.rb +82 -0
- data/lib/platon.rb +77 -0
- data/lib/platon/abi.rb +32 -0
- data/lib/platon/address.rb +62 -0
- data/lib/platon/client.rb +175 -0
- data/lib/platon/contract.rb +351 -0
- data/lib/platon/contract_event.rb +24 -0
- data/lib/platon/contract_initializer.rb +54 -0
- data/lib/platon/decoder.rb +99 -0
- data/lib/platon/deployment.rb +49 -0
- data/lib/platon/encoder.rb +120 -0
- data/lib/platon/explorer_url_helper.rb +0 -0
- data/lib/platon/formatter.rb +142 -0
- data/lib/platon/function.rb +36 -0
- data/lib/platon/function_input.rb +13 -0
- data/lib/platon/function_output.rb +14 -0
- data/lib/platon/gas.rb +9 -0
- data/lib/platon/http_client.rb +55 -0
- data/lib/platon/initializer.rb +0 -0
- data/lib/platon/ipc_client.rb +45 -0
- data/lib/platon/key.rb +105 -0
- data/lib/platon/key/decrypter.rb +113 -0
- data/lib/platon/key/encrypter.rb +128 -0
- data/lib/platon/open_ssl.rb +267 -0
- data/lib/platon/ppos.rb +344 -0
- data/lib/platon/railtie.rb +0 -0
- data/lib/platon/secp256k1.rb +7 -0
- data/lib/platon/sedes.rb +40 -0
- data/lib/platon/segwit_addr.rb +66 -0
- data/lib/platon/singleton.rb +39 -0
- data/lib/platon/solidity.rb +40 -0
- data/lib/platon/transaction.rb +41 -0
- data/lib/platon/tx.rb +201 -0
- data/lib/platon/utils.rb +180 -0
- data/lib/platon/version.rb +5 -0
- data/lib/tasks/platon_contract.rake +27 -0
- data/platon-ruby-logo.png +0 -0
- data/platon.gemspec +50 -0
- 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
|
data/lib/platon/ppos.rb
ADDED
@@ -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
|