how to pass parameters from Django view to contract function using web3.py

Viewed 937

I have a contract which has a payout function with three inputs:

function payout(uint256[] ids, address[] recipients, uint256[] amounts) public authorized {    
require(ids.length == recipients.length && ids.length == amounts.length);
for (uint i = 0; i < recipients.length; i++) {
    Payout(ids[i], recipients[i].send(amounts[i]));
  }
}

and a function is defined in views.py which calls that:

q=Question.objects.filter()
ids = []
adds = []
for cur in q:
        for a in cur.answer.all():
            ids = a.user.id
            adds = a.user.user_wallet_address
            bounty_for_answering(ids, adds, cur.ether)
return redirect('/')

and bounty_for_answering() is:

def bounty_for_answering(ids, usersWalletAddress, bountyAmount):
amount_in_wei = w3.toWei(bountyAmount, 'ether')
nonce=w3.eth.getTransactionCount(usersWalletAddress)
txn_dict = contract_instance.functions.payout(ids, usersWalletAddress, bountyAmount).buildTransaction({
    'gas': 30000,
    'gasPrice': w3.toWei('40', 'gwei'),
    'nonce': nonce,
    'chainId': 3
})

signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key)

txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)

txn_receipt = w3.eth.getTransactionReceipt(txn_hash)

count = 0
while tx_receipt is None and (count < 30):
    time.sleep(10)

    tx_receipt = w3.eth.getTransactionReceipt(txn_hash)

    print(tx_receipt)

if tx_receipt is None:
    return {'status': 'failed', 'error': 'timeout'}

which user_wallet_address is a MetaMask wallet address.

The problem is that I do not know how to pass input arguments to bounty_for_answering and I get this error:

Could not identify the intended function with name payout, positional argument(s) of type (<class 'list'>, <class 'list'>, <class 'set'>) and keyword argument(s) of type {}. Found 1 function(s) with the name payout: ['payout(uint256[],address[],uint256[])'] Function invocation failed due to no matching argument types.

1 Answers

The error is telling you that an incorrect type is being passed to the contract method. Without the definition of bounty_for_answering() it's hard to be really specific, but here is error message repeated, with the relevant parts highlighted:

Could not identify the intended function with name payout, positional argument(s) of type (<class 'list'>, <class 'list'>, <class 'set'>) and keyword argument(s) of type {}. Found 1 function(s) with the name payout: ['payout(uint256[],address[],uint256[])'] Function invocation failed due to no matching argument types.

A python set is unordered, but the contract function expects an ordered list as a third argument. Chances are very good that order matters in the contract function, so you probably need to do some work to order the values before passing them into the contract method invocation.

Related