ethereum / eth-abi

Ethereum ABI utilities for python
MIT License
248 stars 269 forks source link

Invalid pointer error when decoding transaction input #237

Closed kigawas closed 5 months ago

kigawas commented 5 months ago

What happened?

When decoding this successful transaction input (https://etherscan.io/tx/0xa139231454fd021dd227a94fff6a1b6260890bb95e5f5bf8517af36e228575e6), the following error occurred.

Code that produced the error

from eth_abi.abi import decode

decode(
    [
        "(address,uint256,uint256,address,address,address,uint256,uint256,uint8,uint256,uint256,bytes32,uint256,bytes32,bytes32,uint256,(uint256,address),bytes)"
    ],
    b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xb5=\x9d\x99\xec\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18P\xdd\x8f\xb92;\x01\xc3@\xd0\xeb\x1d\xa1\xec\x16\xcc\x8e\xe1\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x00P\x00\x00\xad\x10M}\xbd\x00\xe3\xae\n\\\x00V\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbcL\xa0\xed\xa7dz\x8a\xb7\xc2\x06\x1c.\x11\x8a\x18\xa96\xf1=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00cF\xe1\xd2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00co\xad\xcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x0cn\xbe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x89\xc7\xeeGK\xc5\x85\x00\x00\x00{\x02#\x00\x91\xa7\xed\x01#\x00r\xf7\x00j\x00M`\xa8\xd4\xe7\x1dY\x9b\x81\x04%\x0f\x00\x00\x00\x00\x00{\x02#\x00\x91\xa7\xed\x01#\x00r\xf7\x00j\x00M`\xa8\xd4\xe7\x1dY\x9b\x81\x04%\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xfa\xe2v\x93\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2k\x00\xc1\xf0\xdf\x000\x009\x00'\x14\x00\x00\xfa\xa7\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xfa\xe2v\x93\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8X\xdd\xc0D]\x811\xda\xc4\xd1\xde\x01\xf84\xff\xcb\xa5.\xf1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x04k\xd0\xfd\xa5\xb94\xa9n\xf4p\r\xa1\xb6N\x03\xe7E\x1ejn\xe4ZP\x04\xb98#\xff;\xaa\xe3K\x9f\x1cOfw\x81\xb5\xfe\xdd'\xdcg3\x9dO\xd3\xe4\xae*\x87;1P\x90\xe61(Ss/\x9a\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x0cn\xbe",
)

Full error output

Traceback (most recent call last):
  File "/Users/user/test-ethabi/repro.py", line 3, in <module>
    decode(
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/codec.py", line 162, in decode
    return cast(Tuple[Any, ...], decoder(stream))
                                 ^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 131, in __call__
    return self.decode(stream)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_utils/functional.py", line 47, in inner
    return callback(fn(*args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 226, in decode
    yield decoder(stream)
          ^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 131, in __call__
    return self.decode(stream)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 162, in decode
    value = self.tail_decoder(stream)
            ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 131, in __call__
    return self.decode(stream)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_utils/functional.py", line 47, in inner
    return callback(fn(*args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 224, in decode
    self.validate_pointers(stream)
  File "/Users/user/test-ethabi/.venv/lib/python3.12/site-packages/eth_abi/decoding.py", line 211, in validate_pointers
    raise InvalidPointer(
eth_abi.exceptions.InvalidPointer: Invalid pointer in tuple at location 608 in payload

Fill this section in if you know how this could or should be fixed

No response

eth-abi Version

5.1.0

Python Version

3.12.4

Operating System

osx

Output from pip freeze

cytoolz==0.12.3
eth-hash==0.7.0
eth-typing==4.3.1
eth-utils==4.1.1
eth_abi==5.1.0
parsimonious==0.10.0
regex==2024.5.15
toolz==0.12.1
typing_extensions==4.12.2
fselmo commented 5 months ago

@kigawas The inner tuple type is actually a list of tuple types, tuple[], which means it should be (uint256,address)[].

>>> from eth_utils import to_bytes
>>> from eth_abi import abi

>>> hex_data = (
...    "0x0000000000000000000000000000000000000000000000000000000000000020"
...    "000000000000000000000000000000000000000000000000000000000000000000"
...    "000000000000000000000000000000000000000000000000000000000000000000"
...    "00000000000000000000000000000000000000000003b53d9d99ecb80000000000"
...    "0000000000000000001850dd8fb9323b01c340d0eb1da1ec16cc8ee1a200000000"
...    "0000000000000000004c00500000ad104d7dbd00e3ae0a5c00560c000000000000"
...    "00000000000000bc4ca0eda7647a8ab7c2061c2e118a18a936f13d000000000000"
...    "000000000000000000000000000000000000000000000000056100000000000000"
...    "000000000000000000000000000000000000000000000000010000000000000000"
...    "000000000000000000000000000000000000000000000002000000000000000000"
...    "000000000000000000000000000000000000006346e1d200000000000000000000"
...    "000000000000000000000000000000000000636fadcd0000000000000000000000"
...    "000000000000000000000000000000000000000000360c6ebe0000000000000000"
...    "0000000000000000000000000589c7ee474bc5850000007b02230091a7ed012300"
...    "72f7006a004d60a8d4e71d599b8104250f00000000007b02230091a7ed01230072"
...    "f7006a004d60a8d4e71d599b8104250f0000000000000000000000000000000000"
...    "000000000000000000000000000000000200000000000000000000000000000000"
...    "000000000000000000000000000002400000000000000000000000000000000000"
...    "0000000000000000000000000002e0000000000000000000000000000000000000"
...    "000000000000000000000000000200000000000000000000000000000000000000"
...    "000000000018fae27693b400000000000000000000000000000000a26b00c1f0df"
...    "003000390027140000faa719000000000000000000000000000000000000000000"
...    "00000018fae27693b40000000000000000000000000000a858ddc0445d8131dac4"
...    "d1de01f834ffcba52ef10000000000000000000000000000000000000000000000"
...    "000000000000000041046bd0fda5b934a96ef4700da1b64e03e7451e6a6ee45a50"
...    "04b93823ff3baae34b9f1c4f667781b5fedd27dc67339d4fd3e4ae2a873b315090"
...    "e6312853732f9a1c00000000000000000000000000000000000000000000000000"
...    "000000000000360c6ebe"
... )

>>> abi.decode(
...     ["(address,uint256,uint256,address,address,address,uint256,uint256,uint8,uint256,uint256,bytes32,uint256,bytes32,bytes32,uint256,(uint256,address)[],bytes)"],
...     to_bytes(hexstr=hex_data),
... )

(('0x0000000000000000000000000000000000000000',
  0,
  68400000000000000000,
  '0x1850dd8fb9323b01c340d0eb1da1ec16cc8ee1a2',
  '0x004c00500000ad104d7dbd00e3ae0a5c00560c00',
  '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d',
  1377,
  1,
  2,
  1665589714,
  1668263373,
  b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
  24446860302761739304752683030156737591518664810215442929800781758303463785861,
  b'\x00\x00\x00{\x02#\x00\x91\xa7\xed\x01#\x00r\xf7\x00j\x00M`\xa8\xd4\xe7\x1dY\x9b\x81\x04%\x0f\x00\x00',
  b'\x00\x00\x00{\x02#\x00\x91\xa7\xed\x01#\x00r\xf7\x00j\x00M`\xa8\xd4\xe7\x1dY\x9b\x81\x04%\x0f\x00\x00',
  2,
  ((1800000000000000000, '0x0000a26b00c1f0df003000390027140000faa719'),
   (1800000000000000000, '0xa858ddc0445d8131dac4d1de01f834ffcba52ef1')),
  b"\x04k\xd0\xfd\xa5\xb94\xa9n\xf4p\r\xa1\xb6N\x03\xe7E\x1ejn\xe4ZP\x04\xb98#\xff;\xaa\xe3K\x9f\x1cOfw\x81\xb5\xfe\xdd'\xdcg3\x9dO\xd3\xe4\xae*\x87;1P\x90\xe61(Ss/\x9a\x1c"),)
kigawas commented 5 months ago

Thanks for explanation!