Search code examples
pythonethereumweb3py

web3.py: sending ether to a smart contract


I'm using web3.py to interact with a private Ethereum blockchain. I'd like to call the following function in a smart contract:

    uint256 public cookiePrice;

    function feed(string memory message) public payable {
        require(cookiePrice <= msg.value);
        applyFeeding(msg.sender, message);
    }

I am trying to call it like so:

    price = contract.functions.cookiePrice().call()
    txn = contract.functions.feed("my message").buildTransaction({
      'chainId': 13999911119,
      'gas': 70000,
      'value': price,
      'gasPrice': w3.toWei('8', 'gwei'),
      'nonce': int(time.time())
    })
    signed_txn = w3.eth.account.sign_transaction(txn, private_key=private_key)
    w3.eth.sendRawTransaction(signed_txn.rawTransaction)

This seems to succeed, in that sendRawTransaction returns the hash of the transaction (as described in the docs). But I can see on the chain that the call didn't actually take effect.

Is there something obvious missing from the code above? Also, how can I get the return of sendRawTransaction to help me debug?


Solution

  • Your transaction was probably never mined because your nonce was way too high. The nonce for an account starts at 0 and increases by exactly 1 for each sent transaction.

    You can use w3.eth.getTransactionCount to get the correct nonce for the account you're using.