Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b235be5
ABI tuple parser
daoready Nov 29, 2018
8c4bb63
https://github.com/Bloxy-info/web3-eth
daoready Nov 29, 2018
c24a2f1
fix event with tuple parse
daoready Nov 29, 2018
24e20f2
Structures of tuples
astudnev Mar 31, 2019
ef34f18
Structures of tuples
astudnev Mar 31, 2019
8c0758c
array of tuples ABI parse
astudnev Apr 1, 2019
3988476
fixed tuple structures parse
astudnev Apr 2, 2019
4c1e8bc
fixed tuple structures parse
astudnev Apr 2, 2019
5724059
fixed tuple structures parse
astudnev Apr 2, 2019
2122429
Constructor arguments parsed in trial cycle if can not detect automat…
astudnev May 29, 2019
e3419c5
Fix for decoding wrong data set
astudnev Jul 3, 2019
85ac968
fixes for TRON compatibility
astudnev Aug 23, 2019
d3fbfb3
string[32] support
astudnev Aug 25, 2019
fdc9f47
string[32] support
astudnev Aug 25, 2019
a22a93d
trc token type
astudnev Aug 27, 2019
132d967
fix parser for dynamic types
astudnev Aug 28, 2019
84715b3
fix parser for fixed types
astudnev Sep 18, 2019
fe63311
debug module added
astudnev Mar 26, 2020
5c8f85a
bulk simulation for geth method hash
astudnev Mar 26, 2020
d7c586b
added properties for transaction
astudnev Mar 28, 2020
fb2f077
added properties for transaction
astudnev Mar 28, 2020
f50f170
Celo blockchain does not have difficulty on web3
astudnev Apr 24, 2020
9214ee9
suicide address field
astudnev Apr 24, 2020
1a67dbf
suicide address field
astudnev Apr 24, 2020
b98be95
suicide address field
astudnev Apr 24, 2020
7cbbed2
Added timeout for debug_module tracing
astudnev Apr 27, 2020
c645b5f
tracesByBlockNumber added
astudnev Jun 1, 2020
70144cf
parity_module.rb module added
astudnev Jun 1, 2020
9af1287
web3.eth call used instead of direct name
astudnev Jun 2, 2020
6aae6f7
JSON level up to 1500
astudnev Jun 18, 2020
e9ec838
Padding fixed size data with zeros added
astudnev Jul 23, 2020
7d3eec1
Fix utiliity
astudnev Aug 18, 2020
bf7b605
Fix utiliity
astudnev Aug 18, 2020
4318aac
Fix contsnat for views
astudnev Aug 28, 2020
a631f0d
Fixed tuple array parse
astudnev Dec 7, 2020
672f940
Fix exception when etherscan responds no status
qbonnard Apr 5, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/izetex/web3-eth. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
Bug reports and pull requests are welcome on GitHub at https://github.com/Bloxy-info/web3-eth. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.


## License
Expand Down
3 changes: 3 additions & 0 deletions lib/web3/eth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
require "web3/eth/log"
require "web3/eth/transaction_receipt"
require "web3/eth/eth_module"
require "web3/eth/debug/debug_module"
require "web3/eth/debug/transaction_call_trace"
require "web3/eth/trace_module"
require "web3/eth/parity_module"
require "web3/eth/etherscan"
require "web3/eth/rpc"
51 changes: 45 additions & 6 deletions lib/web3/eth/abi/abi_coder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,15 @@ def encode_primitive_type(type, arg)
end
end


def min_data_size types
types.size*32
end

##
# Decodes multiple arguments using the head/tail mechanism.
#
def decode_abi(types, data)
def decode_abi types, data, raise_errors = false
parsed_types = types.map {|t| Type.parse(t) }

outputs = [nil] * types.size
Expand All @@ -207,8 +212,17 @@ def decode_abi(types, data)
# If a type is static, grab the data directly, otherwise record its
# start position
if t.dynamic?

if raise_errors && pos>data.size-1
raise DecodingError, "Position out of bounds #{pos}>#{data.size-1}"
end

start_positions[i] = Utils.big_endian_to_int(data[pos, 32])

if raise_errors && start_positions[i]>data.size-1
raise DecodingError, "Start position out of bounds #{start_positions[i]}>#{data.size-1}"
end

j = i - 1
while j >= 0 && start_positions[j].nil?
start_positions[j] = start_positions[i]
Expand All @@ -217,7 +231,7 @@ def decode_abi(types, data)

pos += 32
else
outputs[i] = data[pos, t.size]
outputs[i] = zero_padding data, pos, t.size, start_positions
pos += t.size
end
end
Expand All @@ -230,36 +244,61 @@ def decode_abi(types, data)
j -= 1
end

# raise DecodingError, "Not enough data for head" unless pos <= data.size
if raise_errors && pos > data.size
raise DecodingError, "Not enough data for head"
end


parsed_types.each_with_index do |t, i|
if t.dynamic?
offset, next_offset = start_positions[i, 2]
outputs[i] = data[offset...next_offset]
if offset<=data.size && next_offset<=data.size
outputs[i] = data[offset...next_offset]
end
end
end

if raise_errors && outputs.include?(nil)
raise DecodingError, "Not all data can be parsed"
end

parsed_types.zip(outputs).map {|(type, out)| decode_type(type, out) }
end
alias :decode :decode_abi

def zero_padding data, pos, count, start_positions
if pos >= data.size
start_positions[start_positions.size-1] += count
"\x00"*count
elsif pos + count > data.size
start_positions[start_positions.size-1] += ( count - (data.size-pos))
data[pos,data.size-pos] + "\x00"*( count - (data.size-pos))
else
data[pos, count]
end
end

def decode_typed_data type_name, data
decode_primitive_type Type.parse(type_name), data
end

def decode_type(type, arg)
if %w(string bytes).include?(type.base) && type.sub.empty?
return nil if arg.nil? || arg.empty?
if type.kind_of?(Tuple) && type.dims.empty?
arg ? decode_abi(type.types, arg) : []
elsif %w(string bytes).include?(type.base) && type.sub.empty?
l = Utils.big_endian_to_int arg[0,32]
data = arg[32..-1]
data[0, l]
elsif type.dynamic?
l = Utils.big_endian_to_int arg[0,32]
raise DecodingError, "Too long length: #{l}" if l>100000
subtype = type.subtype

if subtype.dynamic?
raise DecodingError, "Not enough data for head" unless arg.size >= 32 + 32*l

start_positions = (1..l).map {|i| Utils.big_endian_to_int arg[32*i, 32] }
start_positions = (1..l).map {|i| 32+Utils.big_endian_to_int(arg[32*i, 32]) }
start_positions.push arg.size

outputs = (0...l).map {|i| arg[start_positions[i]...start_positions[i+1]] }
Expand Down
92 changes: 88 additions & 4 deletions lib/web3/eth/abi/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class <<self
# 256, 128x128, nil), array component (eg. [], [45], nil)
#
def parse(type)

return parse('uint256') if type=='trcToken'

if type =~ /^\((.*)\)((\[[0-9]*\])*)/
return Tuple.parse $1, $2.scan(/\[[0-9]*\]/)
end

_, base, sub, dimension = /([a-z]*)([0-9]*x?[0-9]*)((\[[0-9]*\])*)/.match(type).to_a

dims = dimension.scan(/\[[0-9]*\]/)
Expand All @@ -20,9 +27,7 @@ def parse(type)
case base
when ''
return parse 'address'
when 'string'
raise ParseError, "String type must have no suffix or numerical suffix" unless sub.empty?
when 'bytes'
when 'bytes', 'string'
raise ParseError, "Maximum 32 bytes for fixed-length string or bytes" unless sub.empty? || sub.to_i <= 32
when 'uint', 'int'
raise ParseError, "Integer type must have numerical suffix" unless sub =~ /\A[0-9]+\z/
Expand All @@ -37,7 +42,8 @@ def parse(type)
total = high + low

raise ParseError, "Fixed size out of bounds (max 32 bytes)" unless total >= 8 && total <= 256
raise ParseError, "Fixed high/low sizes must be multiples of 8" unless high % 8 == 0 && low % 8 == 0
raise ParseError, "Fixed high size must be multiple of 8" unless high % 8 == 0
raise ParseError, "Low sizes must be 0 to 80" unless low>0 && low<=80
when 'hash'
raise ParseError, "Hash type must have numerical suffix" unless sub =~ /\A[0-9]+\z/
when 'address'
Expand Down Expand Up @@ -115,4 +121,82 @@ def subtype
end

end

class Tuple < Type

def self.parse types, dims

depth = 0
collected = []
current = ''

types.split('').each do |c|
case c
when ',' then
if depth==0
collected << current
current = ''
else
current += c
end
when '(' then
depth += 1
current += c
when ')' then
depth -= 1
current += c
else
current += c
end

end
collected << current unless current.empty?

Tuple.new collected, dims.map {|x| x[1...-1].to_i}

end

attr_reader :types, :parsed_types
def initialize types, dims
super('tuple', '', dims)
@types = types
@parsed_types = types.map{|t| Type.parse t}
end

def ==(another_type)
another_type.kind_of?(Tuple) &&
another_type.types == types &&
another_type.dims == dims
end

def size
@size ||= calculate_size
end

def calculate_size
if dims.empty?
s = 0
parsed_types.each do |type|
ts = type.size
return nil if ts.nil?
s += ts
end
s
else
if dims.last == 0 # 0 for dynamic array []
nil
else
subtype.dynamic? ? nil : dims.last * subtype.size
end
end


end

def subtype
@subtype ||= Tuple.new(types, dims[0...-1])
end

end

end
24 changes: 24 additions & 0 deletions lib/web3/eth/block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@ def block_number
from_hex number
end

def block_difficulty
self.respond_to?(:difficulty) ? from_hex(difficulty) : 0
end

def block_gasLimit
self.respond_to?(:gasLimit) ? from_hex(gasLimit) : 0
end

def block_gasUsed
self.respond_to?(:gasUsed) ? from_hex(gasUsed) : 0
end

def block_nonce
self.respond_to?(:nonce) ? from_hex(nonce) : 0
end

def block_size
self.respond_to?(:size) ? from_hex(size) : 0
end

def block_totalDifficulty
self.respond_to?(:totalDifficulty) ? from_hex(totalDifficulty) : 0
end

end

end
Expand Down
Loading