web3-hpb 0.0.2

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.
@@ -0,0 +1,30 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ module Web3::Hpb::Abi
4
+ module Constant
5
+
6
+ BYTE_EMPTY = "".freeze
7
+ BYTE_ZERO = "\x00".freeze
8
+ BYTE_ONE = "\x01".freeze
9
+
10
+ TT32 = 2**32
11
+ TT40 = 2**40
12
+ TT160 = 2**160
13
+ TT256 = 2**256
14
+ TT64M1 = 2**64 - 1
15
+
16
+ UINT_MAX = 2**256 - 1
17
+ UINT_MIN = 0
18
+ INT_MAX = 2**255 - 1
19
+ INT_MIN = -2**255
20
+
21
+ HASH_ZERO = ("\x00"*32).freeze
22
+
23
+ PUBKEY_ZERO = ("\x00"*32).freeze
24
+ PRIVKEY_ZERO = ("\x00"*32).freeze
25
+ PRIVKEY_ZERO_HEX = ('0'*64).freeze
26
+
27
+ CONTRACT_CODE_SIZE_LIMIT = 0x6000
28
+
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ module Web3::Hpb::Abi
4
+
5
+ class DeprecatedError < StandardError; end
6
+ class ChecksumError < StandardError; end
7
+ class FormatError < StandardError; end
8
+ class ValidationError < StandardError; end
9
+ class ValueError < StandardError; end
10
+ class AssertError < StandardError; end
11
+
12
+ class UnknownParentError < StandardError; end
13
+ class InvalidBlock < ValidationError; end
14
+ class InvalidUncles < ValidationError; end
15
+
16
+ class InvalidTransaction < ValidationError; end
17
+ class UnsignedTransactionError < InvalidTransaction; end
18
+ class InvalidNonce < InvalidTransaction; end
19
+ class InsufficientStartGas < InvalidTransaction; end
20
+ class InsufficientBalance < InvalidTransaction; end
21
+ class BlockGasLimitReached < InvalidTransaction; end
22
+
23
+ class InvalidSPVProof < ValidationError; end
24
+
25
+ class ContractCreationFailed < StandardError; end
26
+ class TransactionFailed < StandardError; end
27
+
28
+ end
@@ -0,0 +1,90 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ module Web3::Hpb::Abi
4
+ class Type
5
+
6
+ class ParseError < StandardError;
7
+ end
8
+
9
+ class << self
10
+
11
+ def parse(type)
12
+ _, base, sub, dimension = /([a-z]*)([0-9]*x?[0-9]*)((\[[0-9]*\])*)/.match(type).to_a
13
+
14
+ dims = dimension.scan(/\[[0-9]*\]/)
15
+ raise ParseError, "Unknown characters found in array declaration" if dims.join != dimension
16
+
17
+ case base
18
+ when ''
19
+ return parse 'address'
20
+ when 'string'
21
+ raise ParseError, "String type must have no suffix or numerical suffix" unless sub.empty?
22
+ when 'uint', 'int'
23
+ raise ParseError, "Integer type must have numerical suffix" unless sub =~ /\A[0-9]+\z/
24
+
25
+ size = sub.to_i
26
+ raise ParseError, "Integer size out of bounds" unless size >= 8 && size <= 256
27
+ raise ParseError, "Integer size must be multiple of 8" unless size % 8 == 0
28
+ when 'fixed', 'ufixed'
29
+ raise ParseError, "Fixed type must have suffix of form <high>x<low>, e.g. 128x128" unless sub =~ /\A[0-9]+x[0-9]+\z/
30
+
31
+ high, low = sub.split('x').map(&:to_i)
32
+ total = high + low
33
+ raise ParseError, "Fixed size out of bounds (max 32 bytes)" unless total >= 8 && total <= 256
34
+ raise ParseError, "Fixed high/low sizes must be multiples of 8" unless high % 8 == 0 && low % 8 == 0
35
+ when 'hash'
36
+ raise ParseError, "Hash type must have numerical suffix" unless sub =~ /\A[0-9]+\z/
37
+ when 'address'
38
+ raise ParseError, "Address cannot have suffix" unless sub.empty?
39
+ when 'bool'
40
+ raise ParseError, "Bool cannot have suffix" unless sub.empty?
41
+ else
42
+ raise ParseError, "Unrecognized type base: #{base}"
43
+ end
44
+
45
+ new(base, sub, dims.map{ |x| x[1...-1].to_i })
46
+ end
47
+
48
+ def size_type
49
+ @size_type ||= new('uint', 256, [])
50
+ end
51
+ end
52
+
53
+ attr :base, :sub, :dims
54
+
55
+ def initialize(base, sub, dims)
56
+ @base = base
57
+ @sub = sub
58
+ @dims = dims
59
+ end
60
+
61
+ def ==(another_type)
62
+ base == another_type.base && sub == another_type.sub && dims == another_type.dims
63
+ end
64
+
65
+ def size
66
+ @size ||= if dims.empty?
67
+ if %w(string bytes).include?(base) && sub.empty?
68
+ nil
69
+ else
70
+ 32
71
+ end
72
+ else
73
+ if dims.last == 0 # 0 for dynamic array []
74
+ nil
75
+ else
76
+ subtype.dynamic? ? nil : dims.last * subtype.size
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ def dynamic?
83
+ size.nil?
84
+ end
85
+
86
+ def subtype
87
+ @subtype ||= self.class.new(base, sub, dims[0...-1])
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,224 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ require 'digest'
4
+ require 'digest/sha3'
5
+ require 'openssl'
6
+ require 'rlp'
7
+
8
+ module Web3::Hpb::Abi
9
+ module Utils
10
+
11
+ extend self
12
+
13
+ include Constant
14
+
15
+ ##
16
+ # Not the keccak in sha3, although it's underlying lib named SHA3
17
+ #
18
+ def keccak256(x)
19
+ Digest::SHA3.new(256).digest(x)
20
+ end
21
+
22
+ def keccak512(x)
23
+ Digest::SHA3.new(512).digest(x)
24
+ end
25
+
26
+ def keccak256_rlp(x)
27
+ keccak256 RLP.encode(x)
28
+ end
29
+
30
+ def sha256(x)
31
+ Digest::SHA256.digest x
32
+ end
33
+
34
+ def double_sha256(x)
35
+ sha256 sha256(x)
36
+ end
37
+
38
+ def ripemd160(x)
39
+ Digest::RMD160.digest x
40
+ end
41
+
42
+ def hash160(x)
43
+ ripemd160 sha256(x)
44
+ end
45
+
46
+ def hash160_hex(x)
47
+ encode_hex hash160(x)
48
+ end
49
+
50
+ def mod_exp(x, y, n)
51
+ x.to_bn.mod_exp(y, n).to_i
52
+ end
53
+
54
+ def mod_mul(x, y, n)
55
+ x.to_bn.mod_mul(y, n).to_i
56
+ end
57
+
58
+ def to_signed(i)
59
+ i > Constant::INT_MAX ? (i-Constant::TT256) : i
60
+ end
61
+
62
+ def base58_check_to_bytes(s)
63
+ leadingzbytes = s.match(/\A1*/)[0]
64
+ data = Constant::BYTE_ZERO * leadingzbytes.size + BaseConvert.convert(s, 58, 256)
65
+
66
+ raise ChecksumError, "double sha256 checksum doesn't match" unless double_sha256(data[0...-4])[0,4] == data[-4..-1]
67
+ data[1...-4]
68
+ end
69
+
70
+ def bytes_to_base58_check(bytes, magicbyte=0)
71
+ bs = "#{magicbyte.chr}#{bytes}"
72
+ leadingzbytes = bs.match(/\A#{Constant::BYTE_ZERO}*/)[0]
73
+ checksum = double_sha256(bs)[0,4]
74
+ '1'*leadingzbytes.size + BaseConvert.convert("#{bs}#{checksum}", 256, 58)
75
+ end
76
+
77
+ def ceil32(x)
78
+ x % 32 == 0 ? x : (x + 32 - x%32)
79
+ end
80
+
81
+ def encode_hex(b)
82
+ RLP::Utils.encode_hex b
83
+ end
84
+
85
+ def decode_hex(s)
86
+ RLP::Utils.decode_hex s
87
+ end
88
+
89
+ def big_endian_to_int(s)
90
+ RLP::Sedes.big_endian_int.deserialize s.sub(/\A(\x00)+/, '')
91
+ end
92
+
93
+ def int_to_big_endian(n)
94
+ RLP::Sedes.big_endian_int.serialize n
95
+ end
96
+
97
+ def lpad(x, symbol, l)
98
+ return x if x.size >= l
99
+ symbol * (l - x.size) + x
100
+ end
101
+
102
+ def rpad(x, symbol, l)
103
+ return x if x.size >= l
104
+ x + symbol * (l - x.size)
105
+ end
106
+
107
+ def zpad(x, l)
108
+ lpad x, BYTE_ZERO, l
109
+ end
110
+
111
+ def zunpad(x)
112
+ x.sub /\A\x00+/, ''
113
+ end
114
+
115
+ def zpad_int(n, l=32)
116
+ zpad encode_int(n), l
117
+ end
118
+
119
+ def zpad_hex(s, l=32)
120
+ zpad decode_hex(s), l
121
+ end
122
+
123
+ def int_to_addr(x)
124
+ zpad_int x, 20
125
+ end
126
+
127
+ def encode_int(n)
128
+ raise ArgumentError, "Integer invalid or out of range: #{n}" unless n.is_a?(Integer) && n >= 0 && n <= UINT_MAX
129
+ int_to_big_endian n
130
+ end
131
+
132
+ def decode_int(v)
133
+ raise ArgumentError, "No leading zero bytes allowed for integers" if v.size > 0 && (v[0] == Constant::BYTE_ZERO || v[0] == 0)
134
+ big_endian_to_int v
135
+ end
136
+
137
+ def bytearray_to_int(arr)
138
+ o = 0
139
+ arr.each {|x| o = (o << 8) + x }
140
+ o
141
+ end
142
+
143
+ def int_array_to_bytes(arr)
144
+ arr.pack('C*')
145
+ end
146
+
147
+ def bytes_to_int_array(bytes)
148
+ bytes.unpack('C*')
149
+ end
150
+
151
+ def coerce_to_int(x)
152
+ if x.is_a?(Numeric)
153
+ x
154
+ elsif x.size == 40
155
+ big_endian_to_int decode_hex(x)
156
+ else
157
+ big_endian_to_int x
158
+ end
159
+ end
160
+
161
+ def coerce_to_bytes(x)
162
+ if x.is_a?(Numeric)
163
+ int_to_big_endian x
164
+ elsif x.size == 40
165
+ decode_hex(x)
166
+ else
167
+ x
168
+ end
169
+ end
170
+
171
+ def coerce_addr_to_hex(x)
172
+ if x.is_a?(Numeric)
173
+ encode_hex zpad(int_to_big_endian(x), 20)
174
+ elsif x.size == 40 || x.size == 0
175
+ x
176
+ else
177
+ encode_hex zpad(x, 20)[-20..-1]
178
+ end
179
+ end
180
+
181
+ def normalize_address(x, allow_blank: false)
182
+ address = Address.new(x)
183
+ raise ValueError, "address is blank" if !allow_blank && address.blank?
184
+ address.to_bytes
185
+ end
186
+
187
+ def mk_contract_address(sender, nonce)
188
+ keccak256_rlp([normalize_address(sender), nonce])[12..-1]
189
+ end
190
+
191
+ def mk_metropolis_contract_address(sender, initcode)
192
+ keccak256(normalize_address(sender) + initcode)[12..-1]
193
+ end
194
+
195
+
196
+ def parse_int_or_hex(s)
197
+ if s.is_a?(Numeric)
198
+ s
199
+ elsif s[0,2] == '0x'
200
+ big_endian_to_int decode_hex(normalize_hex_without_prefix(s))
201
+ else
202
+ s.to_i
203
+ end
204
+ end
205
+
206
+ def normalize_hex_without_prefix(s)
207
+ if s[0,2] == '0x'
208
+ (s.size % 2 == 1 ? '0' : '') + s[2..-1]
209
+ else
210
+ s
211
+ end
212
+ end
213
+
214
+ def function_signature method_name, arg_types
215
+ "#{method_name}(#{arg_types.join(',')})"
216
+ end
217
+
218
+ def signature_hash signature, length=64
219
+ encode_hex(keccak256(signature))[0...length]
220
+ end
221
+
222
+
223
+ end
224
+ end
@@ -0,0 +1,32 @@
1
+ module Web3
2
+
3
+ module Hpb
4
+
5
+ class Block
6
+
7
+ include Web3::Hpb::Utility
8
+
9
+ attr_reader :raw_data
10
+
11
+ def initialize(block_data)
12
+ @raw_data = block_data
13
+
14
+ block_data.each do |k, v|
15
+ self.instance_variable_set("@#{k}", v)
16
+ self.class.send(:define_method, k, proc {self.instance_variable_get("@#{k}")})
17
+ end
18
+
19
+ @transactions = @transactions.collect { |t| Web3::Hpb::Transaction.new(t)}
20
+ end
21
+
22
+ def timestamp_time
23
+ Time.at(from_hex timestamp )
24
+ end
25
+
26
+ def block_number
27
+ from_hex(number)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,87 @@
1
+ module Web3
2
+ module Hpb
3
+
4
+ class CallTrace
5
+
6
+ include Web3::Hpb::Utility
7
+
8
+ attr_reader :raw_data
9
+
10
+ def initialize trace_data
11
+ @raw_data = trace_data
12
+
13
+ trace_data.each do |k, v|
14
+ self.instance_variable_set("@#{k}", v)
15
+ self.class.send(:define_method, k, proc {self.instance_variable_get("@#{k}")})
16
+ end
17
+
18
+ end
19
+
20
+ def value_wei
21
+ from_hex action['value']
22
+ end
23
+
24
+ def value_hpb
25
+ wei_to_hpb from_hex action['value']
26
+ end
27
+
28
+ def from
29
+ action['from']
30
+ end
31
+
32
+ def to
33
+ action['to']
34
+ end
35
+
36
+ def input
37
+ action['input'] || action['init']
38
+ end
39
+
40
+ def output
41
+ result && result['output']
42
+ end
43
+
44
+ def gas_used
45
+ result && from_hex(result['gasUsed'])
46
+ end
47
+
48
+ def method_hash
49
+ if input && input.length>=10
50
+ input[2...10]
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def creates
57
+ action && result && action['init'] && result['address']
58
+ end
59
+
60
+ # suffix # 0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20 <32 bytes swarm hash> 0x00 0x29
61
+ # look http://solidity.readthedocs.io/en/latest/metadata.html for details
62
+ def call_input_data
63
+ if creates && input
64
+ input[/a165627a7a72305820\w{64}0029(\w*)/,1]
65
+ elsif input && input.length>10
66
+ input[10..input.length]
67
+ else
68
+ []
69
+ end
70
+ end
71
+
72
+
73
+ def suicide?
74
+ type=='suicide'
75
+ end
76
+
77
+ def balance_hpb
78
+ wei_to_hpb action['balance'].to_i(16)
79
+ end
80
+
81
+ def success?
82
+ !raw_data['error']
83
+ end
84
+
85
+ end
86
+ end
87
+ end