Support ABI parsing of specs that use function types (#874)

See http://solidity.readthedocs.io/en/v0.4.21/types.html#function-types
This is a special case of `bytes24`, 24 bytes are right zero padded in
a 32 byte word.
This commit is contained in:
Daniel James 2018-04-16 20:44:29 -04:00 committed by feliam
parent bfffa78b5f
commit 2814723cc8
2 changed files with 24 additions and 0 deletions

View File

@ -461,6 +461,10 @@ class ABI(object):
elif ty.startswith('bytes') and 0 <= int(ty[5:]) <= 32:
size = int(ty[5:])
result = data[offset:offset + size]
elif ty == u'function':
# `function` is a special case of `bytes24`
size = 24
result = data[offset:offset + size]
elif ty == u'address[]':
dyn_offset = arithmetic_simplify(ABI.get_uint(data, 32, offset))
size = arithmetic_simplify(ABI.get_uint(data, 32, dyn_offset))

View File

@ -207,6 +207,26 @@ class EthAbiTests(unittest.TestCase):
self.assertEqual(name, 'func')
self.assertEqual(args, tuple())
def test_function_type(self):
# setup ABI for function with one function param
func_name = 'func'
spec = func_name+'(function)'
func_id = ABI.make_function_id(spec)
# build bytes24 data for function value (address+selector)
# calls member id lookup on 'Ethereum Foundation Tip Box' (see https://www.ethereum.org/donate)
address = ''.join(ABI.serialize_uint(0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359, 20))
selector = ABI.make_function_id('memberId(address)')
function_ref_data = address + selector
# build tx call data
call_data = ''.join([
func_id,
function_ref_data,
'\0'*8
])
name, args = ABI.parse(spec, call_data)
self.assertEqual(name, func_name)
self.assertEqual(args, (function_ref_data,))
class EthTests(unittest.TestCase):
def test_emit_did_execute_end_instructions(self):