[Ethereum] Contract deploy error with web3.py: Incorrect argument count

erc-20web3.py

I am trying to deploy ERC20 based token with web3.py. I successfully compiled the solidity contract, but get an error when I deploy. The exception is raised in this line:

tx_hash = contract.deploy(transaction={'from': w3.eth.accounts[2], 'gas': 410000}) 

The full deployment script:

   import json
    from web3 import Web3, HTTPProvider,TestRPCProvider
    from solc import compile_source, compile_files
    from web3.contract import ConciseContract

    compiled_sol = compile_files(["DappToken.sol"])
    # print(compiled_sol.keys())
    contract_interface = compiled_sol['DappToken.sol:DappToken']
    # print(contract_interface['bin'])
    # print(contract_interface)

    # web3.py instance
    w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:7545"))
    # print(contract_interface['abi'])
    # Instantiate and deploy contract
    contract = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
    print(contract)
    # Get transaction hash from deployed contract
    # candidates = 'hello world'
    print(w3.eth.accounts[2])
    tx_hash = contract.deploy(transaction={'from': w3.eth.accounts[2], 'gas': 410000})
    # print(tx_hash)
    # Get tx receipt to get contract address
    tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    print(tx_receipt)
    contract_address = tx_receipt['contractAddress']

    # Contract instance in concise mode
    abi = contract_interface['abi']
    contract_instance = w3.eth.contract(address=contract_address, abi=abi, ContractFactoryClass=ConciseContract)



    contract_instance.functions.transfer({'to': w3.eth.accounts[1]}, 250000, {'form': w3.eth.accounts[0]})

The exception:

Traceback (most recent call last):
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_intregrate_sol.py", line 21, in <module>
    tx_hash = contract.deploy(transaction={'from': w3.eth.accounts[2], 'gas': 410000})
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_eth/lib/python3.6/site-packages/web3/utils/decorators.py", line 57, in wrapper
    return to_wrap(*args, **kwargs)
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_eth/lib/python3.6/site-packages/web3/contract.py", line 323, in deploy
    deploy_transaction['data'] = cls._encode_constructor_data(args, kwargs)
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_eth/lib/python3.6/site-packages/web3/utils/decorators.py", line 16, in _wrapper
    return self.method(objtype, *args, **kwargs)
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_eth/lib/python3.6/site-packages/web3/contract.py", line 763, in _encode_constructor_data
    arguments = merge_args_and_kwargs(constructor_abi, args, kwargs)
  File "/home/anupam/Documents/workspace/Ethereum_Blockchain/py_intregreat_sol/py_eth/lib/python3.6/site-packages/web3/utils/abi.py", line 182, in merge_args_and_kwargs
    len(args) + len(kwargs),
TypeError: Incorrect argument count.  Expected '1'.  Got '0'
  1. Why do I get this error?
  2. Where are the mistakes in the code?

Best Answer

Try the newer constructor API

I require argument in the constructor

To supply an argument to the constructor, I find the newer constructor API to be more pleasant. Let's say the constructor takes the number of initial tokens, which you want to be 1000. That can be done with:

contract.constructor(1000).transact({'from': w3.eth.accounts[2], 'gas': 410000})

Why didn't this approach work?

  1. Why do I get this error? The error is telling you that you need to supply an argument to the constructor. No arguments were supplied.
  2. Where are the mistakes in the code?

In the old constructor API (the one used in the question), the appropriate way to pass in arguments would be:

contract.deploy(args=[1000], transaction={'from': w3.eth.accounts[2], 'gas': 410000})

Note that this syntax is deprecated, and will likely be removed in Web3.py v5.