5

Since the ethereum Python library has been deprecated in May 2019, the ContractTranslator.encode_abi function is probably not the best way to turn Python argument lists into calldata strings. In particular, it doesn't support functions with the same name but different argument lists.

What is a better way to do this? I've been digging into web3.py _utils but they don't have a single reusable function for this. Any alternatives to use in Python?

I'm looking for a function with an equivalent signature to this:

def encode_abi(abi, function_name: str, args: List[Any]) -> bytes:

2 Answers 2

12

With Brownie

Brownie allows you to generate calldata using the ContractTx.encode_input method:

>>> token
<Token Contract object '0x79447c97b6543F6eFBC91613C655977806CB18b0'>

>>> token.transfer.encode_input(accounts[0], 1000)
0xa9059cbb0000000000000000000000000d36bdba474b5b442310a5bfb989903020249bba00000000000000000000000000000000000000000000000000000000000003e8

It handles function overloading with the OverloadedMethod class:

>>> erc223.transfer
<OverloadedMethod object 'ERC223Token.transfer'>

>>> erc223.transfer['address,uint']
<ContractTx object 'transfer(address,uint256)'>

>>> erc223.transfer['address', 'uint256', 'uint256']
<ContractTx object 'transfer(address,uint256,uint256)'>

With eth-abi

If you prefer not to use a framework, eth-abi provides several encoding methods:

>>> import eth_abi

>>> eth_abi.encode_abi(['address', 'uint256'], (web3.eth.accounts[0], 1000)).hex()
0xa9059cbb0000000000000000000000000d36bdba474b5b442310a5bfb989903020249bba00000000000000000000000000000000000000000000000000000000000003e8

Disclosure: I am the lead developer for Brownie.

2
  • Thanks a lot for the answer, ultimately both approaches are not ideal because they imply already knowing what the function signature is. I'd want to go from a list of arguments in Python to infer which overloaded function needs to be used and then encoding on the back of that. This is what web3.py seems to be doing.
    – Peteris
    Commented Feb 1, 2020 at 17:44
  • I've edited the question to clarify this explicitly and state what the signature was for the old ContractTranslator.encode_abi.
    – Peteris
    Commented Feb 1, 2020 at 17:50
2

Web3 provides a Contract.encodeABI class method: https://web3py.readthedocs.io/en/stable/contracts.html#web3.contract.Contract.encodeABI.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.