2

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.

TylerH
  • 20,799
  • 66
  • 75
  • 101
yasaman.h
  • 81
  • 8

1 Answers1

1

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.

carver
  • 2,229
  • 12
  • 28
  • Would you tell me how can I do that, please? – yasaman.h Sep 19 '18 at 19:52
  • I can't, there's not enough information about what the contract method is supposed to do, and the most critical line of `bounty_for_answering()` has question marks in it. There are now several questions combined in here, which makes it not very helpful for other readers on the site. I recommend that you work with whoever wrote the contract to understand exactly what all the arguments to the function `payout()` should be (especially the last argument), and then come back to write that answer in the question. – carver Sep 20 '18 at 16:41
  • The main problem here is how to pass uint256[] and address[] from view to `bounty_for_answering` and `contract_instance.functions.payout`! I could not find my answer anywhere till now... also I changed last argument to and received same error again – yasaman.h Sep 21 '18 at 20:18
  • i believe your problem is more due to the types within the `list` that don't map to the contract's ABI `uint256`. what type(s) does your python `list` contain? – jopasserat Oct 02 '19 at 15:02