5

I want to encode the parameters needed to call a contract method. In web3js I would use web3.eth.abi.encodeParameters(types, values); I need to do the same in python I found a function called encodeABI() which takes arguments: fn_name, args=None, kwargs=None, data=None Unfortunately the documentation for this method is missing. So my question is how to encode these parameters using web3py?

2
  • 1
    The arguments you describe seem straightforward. What did you try, and where did you run into trouble?
    – user19510
    Commented Jan 5, 2019 at 10:50
  • I did not try this yet, because there is no documentation for this method I would like to know what stays for args, kwargs and why I need to specify the function name when in web3js it's not needed Commented Jan 5, 2019 at 14:39

4 Answers 4

8

You can use the eth-abi library.

>>> from eth_abi import encode_abi
>>> encode_abi(['bytes32', 'bytes32'], [b'a', b'b']) 
b'a\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\x00b\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'

In eth-abi v4 the syntax is simply:

from eth_abi import encode
encode(['bytes32', 'bytes32'], [b'a', b'b'])
>>> from eth_abi import encode_abi
>>> encode_abi(['bytes32', 'bytes32'], [b'a', b'b']) 
b'a\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\x00b\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'
6

It seems that you should do:

my_contract.encodeABI (fn_name='my_method', args=[arg1, arg2, ...])

This is similar to Web3js:

myContract.methods.myMethod.encodeABI (arg1, arg2, ...)

See details in documentation.

1

Use contract.selector

Example:

For get contract use this code:

def getInfo(abi, address):
    api = w3.eth.contract(address=address, abi=abi)
    return api

def contractFunction(address, param1, param2):
    abi = """
            json abi code   
          """
    return getInfo(abi, address).functions.contractFunction(param1, param2)

And when you make sign transactions, in data you may use this code:

'data': str(contractFunction(contract, param1, param2).selector)
  + param1.rjust(64, '0')
  + param2.rjust(64, '0') 

There contract is first 4 symbols of hash contract function with parameter, and other symbols is symbols, appended to 64 symbols with 0

0

I needed to encode web3.py contract constructor arguments to verify contract programmatically on Etherscan.

Was really missing the JS web3.eth.abi.encodeParameters() function and the closest alternative to it really seems to be as @kclowes says eth-abi library. I also found that contract.encodeABI(fn_name='my_method', args=[]) doesn't work for constructors. 4 years later and still no functions in web3.py itself. In the end, after hours of research & trial and error, this worked for me:

import eth_abi
import json

...

def GetEncodedConstructorArgs(functionArgs):
  abiJSON = json.loads(contractAbiAsString)
  constructorABI = None
  for item in abiJSON:
    #if item['name'] == 'MyFunction': # if you need to find function by name
    if item['type'] == 'constructor': # if you need to find constructor, as it has no name
      constructorABI = item
  argumentTypes = []
  for functionArgument in constructorABI['inputs']:
    argumentTypes.append(functionArgument['type'])
  argumentValues = list(functionArgs.values())
  encodedArgs = eth_abi.abi.encode(argumentTypes, argumentValues).hex()
  return encodedArgs

Declare constructor/function parameters & use them

functionArgs = {
  'name': 'Token Name',
  'symbol': 'TTSMBL',
}

encodedArgs = GetEncodedConstructorArgs(functionArgs)

And if you want to avoid supplying functionArgs again for the actual function call, then instead of doing this:

contract.functions.MyFunction(name='Token Name', symbol='TTSMBL')

You can simply unpack them:

contract.functions.MyFunction(**functionArgs)

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.