From feb41ee377332f88dd7dce141f86f06d18f98da1 Mon Sep 17 00:00:00 2001 From: Gerald Bauer Date: Sat, 7 Jan 2023 17:37:22 +0100 Subject: [PATCH] up --- abicoder/test/helper.rb | 12 +++ abicoder/test/test_abi.rb | 2 +- abicoder/test/test_basic_abi.rb | 74 --------------- abicoder/test/test_coder.rb | 151 ------------------------------- abicoder/test/test_encoding.rb | 76 ---------------- abicoder/test/test_fixtures.rb | 51 +++++++++++ abicoder/test/test_spec.rb | 146 +++++++++++++++++++++++++++++- abicoder/test/test_tuples.rb | 52 ----------- abicoder/test/test_utils.rb | 78 +++++++++++++++- test/abicoder/basic.yml | 154 ++++++++++++++++++++++++++++++++ 10 files changed, 436 insertions(+), 360 deletions(-) delete mode 100644 abicoder/test/test_basic_abi.rb delete mode 100644 abicoder/test/test_coder.rb delete mode 100644 abicoder/test/test_encoding.rb create mode 100644 abicoder/test/test_fixtures.rb delete mode 100644 abicoder/test/test_tuples.rb create mode 100644 test/abicoder/basic.yml diff --git a/abicoder/test/helper.rb b/abicoder/test/helper.rb index 1732db8..ce2f75e 100644 --- a/abicoder/test/helper.rb +++ b/abicoder/test/helper.rb @@ -11,6 +11,9 @@ def hexdigest() self.unpack('H*').first; end end def hex( hex ) # convert hex(adecimal) string to binary string + ## note: strip all whitespaces + hex = hex.gsub( /[ \t\n\r]/, '' ) + if ['0x', '0X'].include?( hex[0,2] ) ## cut-of leading 0x or 0X if present [hex[2..-1]].pack('H*') else @@ -19,6 +22,15 @@ def hex( hex ) # convert hex(adecimal) string to binary string end +require 'yaml' + +def read_yml( path ) + txt = File.open( path, 'r:utf-8' ) { |f| f.read } + YAML.load( txt ) +end + + + ## our own code require 'abicoder' diff --git a/abicoder/test/test_abi.rb b/abicoder/test/test_abi.rb index f3e1a9d..290672a 100644 --- a/abicoder/test/test_abi.rb +++ b/abicoder/test/test_abi.rb @@ -22,7 +22,7 @@ def encode_int8( arg ) encode_int( arg, 8 ); end def encode_bytes( arg, length=nil ) ABI.encoder.encode_bytes( arg, length ); end def encode_address( arg ) ABI.encoder.encode_address( arg ); end -BYTE_ZERO = "\x00".b +BYTE_ZERO = "\x00".b.freeze def zpad( bin ) ## note: same as builtin String#rjust !!! l=32 diff --git a/abicoder/test/test_basic_abi.rb b/abicoder/test/test_basic_abi.rb deleted file mode 100644 index 4a92b51..0000000 --- a/abicoder/test/test_basic_abi.rb +++ /dev/null @@ -1,74 +0,0 @@ -## -# to run use -# ruby -I ./lib -I ./test test/test_basic_abi.rb - -### -# try the (few) official ethereum abi tests in: -# https://github.com/ethereum/tests/tree/develop/ABITests -# for now only available one dataset (that incl. three fixtures) -# - https://github.com/ethereum/tests/blob/develop/ABITests/basic_abi_tests.json - -require 'helper' - - -class TestBasicAbi < MiniTest::Test - - def assert_bin( exp, bin ) ## note: always check for BINARY encoding too - assert bin.encoding == Encoding::BINARY - assert_equal exp, bin - end - - -def test_single_integer - types = ['uint256'] - args = [98127491] - data = hex'0000000000000000000000000000000000000000000000000000000005d94e83' - - assert_bin data, ABI.encode( types, args ) - assert_equal args, ABI.decode( types, data ) - assert_equal args, ABI.decode( types, ABI.encode( types, args )) -end - - -def test_integer_and_address - ## note: address gets decoded as a hex(adecimal string) without leading 0x - ## e.g. 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' - - types = [ 'uint256', 'address' ] - args = [ 324124, - 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' - ] - data = hex'000000000000000000000000000000000000000000000000000000000004f21c' + - '000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd826' - - assert_bin data, ABI.encode( types, args ) - assert_equal args, ABI.decode( types, data ) - assert_equal args, ABI.decode( types, ABI.encode( types, args )) -end - -def test_githubwiki - types = ['uint256', - 'uint32[]', - 'bytes10', - 'bytes'] - args = [291, - [1110,1929], - '1234567890'.b, - 'Hello, world!'.b] - data = hex'0000000000000000000000000000000000000000000000000000000000000123'+ - '0000000000000000000000000000000000000000000000000000000000000080'+ - '3132333435363738393000000000000000000000000000000000000000000000'+ - '00000000000000000000000000000000000000000000000000000000000000e0'+ - '0000000000000000000000000000000000000000000000000000000000000002'+ - '0000000000000000000000000000000000000000000000000000000000000456'+ - '0000000000000000000000000000000000000000000000000000000000000789'+ - '000000000000000000000000000000000000000000000000000000000000000d'+ - '48656c6c6f2c20776f726c642100000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) - assert_equal args, ABI.decode( types, data ) - assert_equal args, ABI.decode( types, ABI.encode( types, args )) -end - - -end ## class TestBasicAbi \ No newline at end of file diff --git a/abicoder/test/test_coder.rb b/abicoder/test/test_coder.rb deleted file mode 100644 index 13b9c35..0000000 --- a/abicoder/test/test_coder.rb +++ /dev/null @@ -1,151 +0,0 @@ -## -# to run use -# ruby -I ./lib -I ./test test/test_coder.rb - - -require 'helper' - - -class TestCoder < MiniTest::Test - - - def assert_bin( exp, bin ) ## note: always check for BINARY encoding too - assert bin.encoding == Encoding::BINARY - assert_equal exp, bin - end - - -def test_encode - - types = [ 'uint256', 'string' ] - args = [ 1234, 'Hello World' ] - data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) - - - types = [ 'uint256[]', 'string' ] - args = [ [1234, 5678] , 'Hello World' ] - data = hex'0000000000000000000000000000000000000000000000000000000000000040'+ - '00000000000000000000000000000000000000000000000000000000000000a0'+ - '0000000000000000000000000000000000000000000000000000000000000002'+ - '00000000000000000000000000000000000000000000000000000000000004d2'+ - '000000000000000000000000000000000000000000000000000000000000162e'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) - - types = [ 'uint256', '(uint256,string)'] - args = [1234, [5678, 'Hello World']] - data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000162e'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) -end - - -def test_decode - types = [ 'uint256', 'string' ] - args = [1234, 'Hello World'] - data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_equal args, ABI.decode( types, data ) - - - types = [ 'uint256[]', 'string' ] - args = [[1234, 5678], 'Hello World'] - data = hex'0000000000000000000000000000000000000000000000000000000000000040'+ - '00000000000000000000000000000000000000000000000000000000000000a0'+ - '0000000000000000000000000000000000000000000000000000000000000002'+ - '00000000000000000000000000000000000000000000000000000000000004d2'+ - '000000000000000000000000000000000000000000000000000000000000162e'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_equal args, ABI.decode( types, data ) - - - types = [ 'uint256', '(uint256,string)'] - args = [1234, [5678, 'Hello World']] - data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000162e'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_equal args, ABI.decode( types, data ) - - - types = ['uint256', '(address,uint256)[]', 'string'] - args = [66, - [['18a475d6741215709ed6cc5f4d064732379b5a58', 1]], - 'QmWBiSE9ByR6vrx4hvrjqS3SG5r6wE4SRq7CP2RVpafZWV'] - data = hex'0000000000000000000000000000000000000000000000000000000000000042'+ - '0000000000000000000000000000000000000000000000000000000000000060'+ - '00000000000000000000000000000000000000000000000000000000000000c0'+ - '0000000000000000000000000000000000000000000000000000000000000001'+ - '00000000000000000000000018a475d6741215709ed6cc5f4d064732379b5a58'+ - '0000000000000000000000000000000000000000000000000000000000000001'+ - '000000000000000000000000000000000000000000000000000000000000002e'+ - '516d57426953453942795236767278346876726a715333534735723677453453'+ - '52713743503252567061665a5756000000000000000000000000000000000000' - assert_equal args, ABI.decode( types, data ) -end - - -def test_codec - tests = [ - { types: ['uint256'], - args: [98127491] }, - { types: [ 'uint256', 'string' ], - args: [1234, - 'Hello World'] }, - { types: [ 'uint256[]', 'string' ], - args: [ [1234, 5678] , - 'Hello World' ] }, - ## note: address gets decoded as a hex(adecimal string) without leading 0x - ## e.g. 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' - { types: [ 'uint256', 'address' ], - args: [ 324124, - 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' ] }, - { types: ['uint256', - 'uint32[]', - 'bytes10', - 'bytes'], - args: [291, - [1110,1929], - '1234567890'.b, - 'Hello, world!'.b] }, - ### tuples - { types: [ 'uint256', '(uint256,string)'], - args: [1234, - [5678, 'Hello World']] }, - { types: ['uint256', '(address,uint256)[]', 'string'], - args: [66, - [['18a475d6741215709ed6cc5f4d064732379b5a58', 1]], - 'QmWBiSE9ByR6vrx4hvrjqS3SG5r6wE4SRq7CP2RVpafZWV'] }, - ] - - - tests.each do |test| - types = test[:types] - args = test[:args] - assert_equal args, ABI.decode( types, ABI.encode( types, args )) - end -end - - -end ## class TestCoder - diff --git a/abicoder/test/test_encoding.rb b/abicoder/test/test_encoding.rb deleted file mode 100644 index 6261a06..0000000 --- a/abicoder/test/test_encoding.rb +++ /dev/null @@ -1,76 +0,0 @@ -## -# to run use -# ruby -I ./lib -I ./test test/test_encoding.rb - - -require 'helper' - - -class TestEncoding < MiniTest::Test - -BYTE_ZERO = "\x00".b.freeze -BYTE_ONE = "\x01".b.freeze - - -def assert_bin( exp, bin ) ## note: always check for BINARY encoding too - assert bin.encoding == Encoding::BINARY - assert_equal exp, bin -end - - -def test_lpad - bin = ABI.encoder.lpad_int( 0 ) - pp bin - assert_bin BYTE_ZERO*32, bin - - bin = ABI.encoder.lpad_int( 1 ) - pp bin - assert_bin BYTE_ZERO*31+BYTE_ONE, bin -end - -def test_lpad_hex - bin = ABI.encoder.lpad_hex( '00' ) - pp bin - assert_bin BYTE_ZERO*32, bin - - bin = ABI.encoder.lpad_hex( '01' ) - pp bin - assert_bin BYTE_ZERO*31+BYTE_ONE, bin - - bin = ABI.encoder.lpad_hex( 'FF'*32 ) - pp bin - assert_bin "\xFF".b*32, bin -end - - -def test_lpad - bin = ABI.encoder.lpad( BYTE_ZERO ) - pp bin - assert_bin BYTE_ZERO*32, bin - - bin = ABI.encoder.lpad( BYTE_ONE ) - pp bin - assert_bin BYTE_ZERO*31+BYTE_ONE, bin - - bin = ABI.encoder.lpad( "\0xff".b*33 ) - pp bin - assert_bin "\0xff".b*33, bin -end - -def test_rpad - bin = ABI.encoder.rpad( BYTE_ZERO ) - pp bin - assert_bin BYTE_ZERO*32, bin - - bin = ABI.encoder.rpad( BYTE_ONE ) - pp bin - assert_bin BYTE_ONE+BYTE_ZERO*31, bin - - bin = ABI.encoder.rpad( "\0xff".b*33 ) - pp bin - assert_bin "\0xff".b*33, bin -end - - -end # class TestEncoding - diff --git a/abicoder/test/test_fixtures.rb b/abicoder/test/test_fixtures.rb new file mode 100644 index 0000000..8b1f88e --- /dev/null +++ b/abicoder/test/test_fixtures.rb @@ -0,0 +1,51 @@ +## +# to run use +# ruby -I ./lib -I ./test test/test_fixtures.rb + + +require 'helper' + + + + +class TestFixtures < MiniTest::Test + +def assert_bin( exp, bin ) ## note: always check for BINARY encoding too + assert bin.encoding == Encoding::BINARY + assert_equal exp, bin +end + + + +def test_basic + + tests = read_yml( '../test/abicoder/basic.yml' ) + puts " #{tests.size} test(s) in /test/abicoder/basic.yml" + pp tests + + tests.each do |test| + types = test['types'] + args = test['args'] + hex = test['data'] + +=begin + ## quick hack for bytes / bytes10 etc. + ## change encoding to BINARAY / ASCII_8BIT + ## not really possible with yaml fixtures + args = types.zip(args).map do |(type,arg)| + arg = arg.b if ['bytes', 'bytes10'].include?( type ) + arg + end +=end + if hex + data = hex( hex ) ## convert hex string to binary string + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + end + assert_equal args, ABI.decode( types, ABI.encode( types, args )) + end +end + + +end ## class TestFixtures + diff --git a/abicoder/test/test_spec.rb b/abicoder/test/test_spec.rb index af6e2a4..0a9e0ab 100644 --- a/abicoder/test/test_spec.rb +++ b/abicoder/test/test_spec.rb @@ -5,6 +5,17 @@ ### # try the examples from the official abi spec # see https://docs.soliditylang.org/en/develop/abi-spec.html +# +# plus try the (few) official ethereum abi tests in: +# https://github.com/ethereum/tests/tree/develop/ABITests +# for now only available one dataset (that incl. three fixtures) +# - https://github.com/ethereum/tests/blob/develop/ABITests/basic_abi_tests.json +# +# +# plus some more from the ethabi (rust) +# see https://github.com/rust-ethereum/ethabi/blob/master/ethabi/src/encoder.rs +# https://github.com/rust-ethereum/ethabi/blob/master/ethabi/src/decoder.rs +# require 'helper' @@ -26,6 +37,7 @@ def test_baz ## baz(uint32,bool) data = hex'0000000000000000000000000000000000000000000000000000000000000045'+ '0000000000000000000000000000000000000000000000000000000000000001' assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) assert_equal args, ABI.decode( types, ABI.encode( types, args )) end @@ -38,6 +50,7 @@ def test_bar ## bar(bytes3[2]) data = hex'6162630000000000000000000000000000000000000000000000000000000000' + '6465660000000000000000000000000000000000000000000000000000000000' assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) assert_equal args, ABI.decode( types, ABI.encode( types, args )) end @@ -72,6 +85,7 @@ def test_sam ## sam(bytes,bool,uint256[]) # ... assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) assert_equal args, ABI.decode( types, ABI.encode( types, args )) end @@ -93,6 +107,7 @@ def test_f ## f(uint256,uint32[],bytes10,bytes) '48656c6c6f2c20776f726c642100000000000000000000000000000000000000' assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) assert_equal args, ABI.decode( types, ABI.encode( types, args )) end @@ -138,14 +153,137 @@ def test_g ## g(uint256[][],string[]) # 9 - count for [3] - 0x1 # 10 - encoding of 3 - assert_bin data, ABI.encode( types, args ) + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) +end + + +#################### +## from ethereum tests +## +def test_single_integer + types = ['uint256'] + args = [98127491] + data = hex'0000000000000000000000000000000000000000000000000000000005d94e83' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) +end + + +def test_integer_and_address + ## note: address gets decoded as a hex(adecimal string) without leading 0x + ## e.g. 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' -## fix: decoding error!!!! - is now workng??? -# Expected: [[[1, 2], [3]], ["one", "two", "three"]] -# Actual: [[[1, 2], [3]], "\x00\x00\x00"] + types = [ 'uint256', 'address' ] + args = [ 324124, + 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' + ] + data = hex'000000000000000000000000000000000000000000000000000000000004f21c' + + '000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd826' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) +end +def test_githubwiki + types = ['uint256', + 'uint32[]', + 'bytes10', + 'bytes'] + args = [291, + [1110,1929], + '1234567890'.b, + 'Hello, world!'.b] + data = hex'0000000000000000000000000000000000000000000000000000000000000123'+ + '0000000000000000000000000000000000000000000000000000000000000080'+ + '3132333435363738393000000000000000000000000000000000000000000000'+ + '00000000000000000000000000000000000000000000000000000000000000e0'+ + '0000000000000000000000000000000000000000000000000000000000000002'+ + '0000000000000000000000000000000000000000000000000000000000000456'+ + '0000000000000000000000000000000000000000000000000000000000000789'+ + '000000000000000000000000000000000000000000000000000000000000000d'+ + '48656c6c6f2c20776f726c642100000000000000000000000000000000000000' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) +end + + + + +def test_hello + ## sample from ether.js abicoder docu + types = [ 'uint256', 'string' ] + args = [ 1234, 'Hello World' ] + data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ + '0000000000000000000000000000000000000000000000000000000000000040'+ + '000000000000000000000000000000000000000000000000000000000000000b'+ + '48656c6c6f20576f726c64000000000000000000000000000000000000000000' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) + + + ## sample from ether.js abicoder docu + types = [ 'uint256[]', 'string' ] + args = [ [1234, 5678] , 'Hello World' ] + data = hex'0000000000000000000000000000000000000000000000000000000000000040'+ + '00000000000000000000000000000000000000000000000000000000000000a0'+ + '0000000000000000000000000000000000000000000000000000000000000002'+ + '00000000000000000000000000000000000000000000000000000000000004d2'+ + '000000000000000000000000000000000000000000000000000000000000162e'+ + '000000000000000000000000000000000000000000000000000000000000000b'+ + '48656c6c6f20576f726c64000000000000000000000000000000000000000000' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) +end + + +def test_tuples + + ## sample from ether.js abicoder docu + types = [ 'uint256', '(uint256,string)'] + args = [1234, [5678, 'Hello World']] + data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ + '0000000000000000000000000000000000000000000000000000000000000040'+ + '000000000000000000000000000000000000000000000000000000000000162e'+ + '0000000000000000000000000000000000000000000000000000000000000040'+ + '000000000000000000000000000000000000000000000000000000000000000b'+ + '48656c6c6f20576f726c64000000000000000000000000000000000000000000' + + assert_bin data, ABI.encode( types, args ) assert_equal args, ABI.decode( types, data ) assert_equal args, ABI.decode( types, ABI.encode( types, args )) + + + ##### + ## reported encoding bug from eth.rb + ## see https://github.com/q9f/eth.rb/issues/102# + types = ['uint256', '(address,uint256)[]', 'string'] + args = [66, + [["18a475d6741215709ed6cc5f4d064732379b5a58", 1]], + "QmWBiSE9ByR6vrx4hvrjqS3SG5r6wE4SRq7CP2RVpafZWV"] + data = hex'0000000000000000000000000000000000000000000000000000000000000042'+ + '0000000000000000000000000000000000000000000000000000000000000060'+ + '00000000000000000000000000000000000000000000000000000000000000c0'+ + '0000000000000000000000000000000000000000000000000000000000000001'+ + '00000000000000000000000018a475d6741215709ed6cc5f4d064732379b5a58'+ + '0000000000000000000000000000000000000000000000000000000000000001'+ + '000000000000000000000000000000000000000000000000000000000000002e'+ + '516d57426953453942795236767278346876726a715333534735723677453453'+ + '52713743503252567061665a5756000000000000000000000000000000000000' + + assert_bin data, ABI.encode( types, args ) + assert_equal args, ABI.decode( types, data ) + assert_equal args, ABI.decode( types, ABI.encode( types, args )) end end ## class TestSpec diff --git a/abicoder/test/test_tuples.rb b/abicoder/test/test_tuples.rb deleted file mode 100644 index 81bf181..0000000 --- a/abicoder/test/test_tuples.rb +++ /dev/null @@ -1,52 +0,0 @@ -## -# to run use -# ruby -I ./lib -I ./test test/test_tuples.rb - - -require 'helper' - - -class TestTuples < MiniTest::Test - - - def assert_bin( exp, bin ) ## note: always check for BINARY encoding too - assert bin.encoding == Encoding::BINARY - assert_equal exp, bin - end - - -def test_encode - - types = [ 'uint256', '(uint256,string)'] - args = [1234, [5678, 'Hello World']] - data = hex'00000000000000000000000000000000000000000000000000000000000004d2'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000162e'+ - '0000000000000000000000000000000000000000000000000000000000000040'+ - '000000000000000000000000000000000000000000000000000000000000000b'+ - '48656c6c6f20576f726c64000000000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) - assert_equal args, ABI.decode( types, ABI.encode( types, args )) - - - types = ['uint256', '(address,uint256)[]', 'string'] - args = [66, - [["18a475d6741215709ed6cc5f4d064732379b5a58", 1]], - "QmWBiSE9ByR6vrx4hvrjqS3SG5r6wE4SRq7CP2RVpafZWV"] - data = hex'0000000000000000000000000000000000000000000000000000000000000042'+ - '0000000000000000000000000000000000000000000000000000000000000060'+ - '00000000000000000000000000000000000000000000000000000000000000c0'+ - '0000000000000000000000000000000000000000000000000000000000000001'+ - '00000000000000000000000018a475d6741215709ed6cc5f4d064732379b5a58'+ - '0000000000000000000000000000000000000000000000000000000000000001'+ - '000000000000000000000000000000000000000000000000000000000000002e'+ - '516d57426953453942795236767278346876726a715333534735723677453453'+ - '52713743503252567061665a5756000000000000000000000000000000000000' - - assert_bin data, ABI.encode( types, args ) - assert_equal args, ABI.decode( types, ABI.encode( types, args )) -end - - -end # class TestTuples \ No newline at end of file diff --git a/abicoder/test/test_utils.rb b/abicoder/test/test_utils.rb index 7a636ec..2fd13ca 100644 --- a/abicoder/test/test_utils.rb +++ b/abicoder/test/test_utils.rb @@ -15,8 +15,9 @@ require 'helper' +BYTE_ZERO = "\x00".b.freeze +BYTE_ONE = "\x01".b.freeze -BYTE_ZERO = "\x00".b def lpad(x, l, symbol ) return x if x.size >= l @@ -33,9 +34,29 @@ def lpad(x, l, symbol ) pp "hello".rjust(20, BYTE_ZERO ) #=> "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000hello" +bin = BYTE_ZERO * 32 +pp bin +puts bin.encoding +puts bin.frozen? + +bin = [BYTE_ZERO,BYTE_ZERO,BYTE_ZERO,BYTE_ZERO].join +pp bin +puts bin.encoding +puts bin.frozen? + + + + class TestUtils < MiniTest::Test + + def assert_bin( exp, bin ) ## note: always check for BINARY encoding too + assert bin.encoding == Encoding::BINARY + assert_equal exp, bin + end + + def test_lpad assert_equal "hello", "hello".ljust( 4, BYTE_ZERO, ) assert_equal "hello", lpad( "hello", 4, BYTE_ZERO ) @@ -44,4 +65,57 @@ def test_lpad lpad( "hello", 20, BYTE_ZERO ) end -end \ No newline at end of file + + def test_lpad32_int + bin = ABI.encoder.lpad_int( 0 ) + pp bin + assert_bin BYTE_ZERO*32, bin + + bin = ABI.encoder.lpad_int( 1 ) + pp bin + assert_bin BYTE_ZERO*31+BYTE_ONE, bin + end + + def test_lpad32_hex + bin = ABI.encoder.lpad_hex( '00' ) + pp bin + assert_bin BYTE_ZERO*32, bin + + bin = ABI.encoder.lpad_hex( '01' ) + pp bin + assert_bin BYTE_ZERO*31+BYTE_ONE, bin + + bin = ABI.encoder.lpad_hex( 'FF'*32 ) + pp bin + assert_bin "\xFF".b*32, bin + end + + + def test_lpad32 + bin = ABI.encoder.lpad( BYTE_ZERO ) + pp bin + assert_bin BYTE_ZERO*32, bin + + bin = ABI.encoder.lpad( BYTE_ONE ) + pp bin + assert_bin BYTE_ZERO*31+BYTE_ONE, bin + + bin = ABI.encoder.lpad( "\0xff".b*33 ) + pp bin + assert_bin "\0xff".b*33, bin + end + + def test_rpad32 + bin = ABI.encoder.rpad( BYTE_ZERO ) + pp bin + assert_bin BYTE_ZERO*32, bin + + bin = ABI.encoder.rpad( BYTE_ONE ) + pp bin + assert_bin BYTE_ONE+BYTE_ZERO*31, bin + + bin = ABI.encoder.rpad( "\0xff".b*33 ) + pp bin + assert_bin "\0xff".b*33, bin + end +end # class TestUtils \ No newline at end of file diff --git a/test/abicoder/basic.yml b/test/abicoder/basic.yml new file mode 100644 index 0000000..25f401a --- /dev/null +++ b/test/abicoder/basic.yml @@ -0,0 +1,154 @@ +### +## test (fixtures) for the abi coder + +# single_integer test from ethereum abitests +# see https://github.com/ethereum/tests/blob/develop/ABITests/basic_abi_tests.json +- types: ['uint256'] + args: [98127491] + data: '0000000000000000000000000000000000000000000000000000000005d94e83' + +## integer_and_address sample test from ethereum abitests +## note: address gets decoded as a hex(adecimal string) without leading 0x +## e.g. 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' +- types: [ 'uint256', 'address' ] + args: [ 324124, 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826' ] + data: '000000000000000000000000000000000000000000000000000000000004f21c + 000000000000000000000000cd2a3d9f938e13cd947ec05abc7fe734df8dd826' + +## githubwiki sample test from ethereum abitests +- types: ['uint256','uint32[]','bytes10','bytes' ] + args: [291, [1110,1929], '1234567890', 'Hello, world!'] + data: '0000000000000000000000000000000000000000000000000000000000000123 + 0000000000000000000000000000000000000000000000000000000000000080 + 3132333435363738393000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000000e0 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000456 + 0000000000000000000000000000000000000000000000000000000000000789 + 000000000000000000000000000000000000000000000000000000000000000d + 48656c6c6f2c20776f726c642100000000000000000000000000000000000000' + +## sample teest from ethers.js abicoder docu +- types: [ 'uint256', 'string' ] + args: [1234, 'Hello World'] + data: '00000000000000000000000000000000000000000000000000000000000004d2 + 0000000000000000000000000000000000000000000000000000000000000040 + 000000000000000000000000000000000000000000000000000000000000000b + 48656c6c6f20576f726c64000000000000000000000000000000000000000000' + +## sample teest from ethers.js abicoder docu +- types: [ 'uint256[]', 'string' ] + args: [ [1234, 5678] , 'Hello World' ] + data: '0000000000000000000000000000000000000000000000000000000000000040 + 00000000000000000000000000000000000000000000000000000000000000a0 + 0000000000000000000000000000000000000000000000000000000000000002 + 00000000000000000000000000000000000000000000000000000000000004d2 + 000000000000000000000000000000000000000000000000000000000000162e + 000000000000000000000000000000000000000000000000000000000000000b + 48656c6c6f20576f726c64000000000000000000000000000000000000000000' + + +#### +### tuples + +## sample from ethers.js abicoder docu +- types: [ 'uint256', '(uint256,string)'] + args: [1234, [5678, 'Hello World']] + data: '00000000000000000000000000000000000000000000000000000000000004d2 + 0000000000000000000000000000000000000000000000000000000000000040 + 000000000000000000000000000000000000000000000000000000000000162e + 0000000000000000000000000000000000000000000000000000000000000040 + 000000000000000000000000000000000000000000000000000000000000000b + 48656c6c6f20576f726c64000000000000000000000000000000000000000000' + + +## reported encoding bug from eth.rb +## see https://github.com/q9f/eth.rb/issues/102# +- types: ['uint256', '(address,uint256)[]', 'string'] + args: [66, [['18a475d6741215709ed6cc5f4d064732379b5a58', 1]], + 'QmWBiSE9ByR6vrx4hvrjqS3SG5r6wE4SRq7CP2RVpafZWV'] + data: '0000000000000000000000000000000000000000000000000000000000000042 + 0000000000000000000000000000000000000000000000000000000000000060 + 00000000000000000000000000000000000000000000000000000000000000c0 + 0000000000000000000000000000000000000000000000000000000000000001 + 00000000000000000000000018a475d6741215709ed6cc5f4d064732379b5a58 + 0000000000000000000000000000000000000000000000000000000000000001 + 000000000000000000000000000000000000000000000000000000000000002e + 516d57426953453942795236767278346876726a715333534735723677453453 + 52713743503252567061665a5756000000000000000000000000000000000000' + + +################# +# try the examples from the official abi spec +# see https://docs.soliditylang.org/en/develop/abi-spec.html + + +## baz(uint32,bool) +- types: ['uint32', 'bool'] + args: [69,true] + data: '0000000000000000000000000000000000000000000000000000000000000045 + 0000000000000000000000000000000000000000000000000000000000000001' + + +## bar(bytes3[2]) +- types: ['bytes3[2]'] + args: [['abc','def']] + data: '6162630000000000000000000000000000000000000000000000000000000000 + 6465660000000000000000000000000000000000000000000000000000000000' + + +## sam(bytes,bool,uint256[]) +- types: ['bytes','bool','uint256[]'] + args: ['dave', true, [1,2,3]] + data: '0000000000000000000000000000000000000000000000000000000000000060 + 0000000000000000000000000000000000000000000000000000000000000001 + 00000000000000000000000000000000000000000000000000000000000000a0 + 0000000000000000000000000000000000000000000000000000000000000004 + 6461766500000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000003 + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000003' + +## f(uint256,uint32[],bytes10,bytes) +- types: ['uint256','uint32[]','bytes10','bytes'] + args: [0x123, + [0x456, 0x789], + '1234567890', + 'Hello, world!'] + data: '0000000000000000000000000000000000000000000000000000000000000123 + 0000000000000000000000000000000000000000000000000000000000000080 + 3132333435363738393000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000000e0 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000456 + 0000000000000000000000000000000000000000000000000000000000000789 + 000000000000000000000000000000000000000000000000000000000000000d + 48656c6c6f2c20776f726c642100000000000000000000000000000000000000' + +## g(uint256[][],string[]) +- types: ['uint256[][]','string[]'] + args: [[[1, 2], [3]], + ['one', 'two', 'three']] + data: '0000000000000000000000000000000000000000000000000000000000000040 + 0000000000000000000000000000000000000000000000000000000000000140 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000040 + 00000000000000000000000000000000000000000000000000000000000000a0 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000003 + 0000000000000000000000000000000000000000000000000000000000000003 + 0000000000000000000000000000000000000000000000000000000000000060 + 00000000000000000000000000000000000000000000000000000000000000a0 + 00000000000000000000000000000000000000000000000000000000000000e0 + 0000000000000000000000000000000000000000000000000000000000000003 + 6f6e650000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000003 + 74776f0000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000005 + 7468726565000000000000000000000000000000000000000000000000000000' + +