简体   繁体   中英

Sending both ether and calling function on smart contract using Web3

So there's an ERC20 contract with an additional fallback function. I am trying to send ether to the contract as well as send tokens in same transaction. I am not sure if this is possible but I have found some examples of sending custom data to a contract. I have following code:

async getTransaction(sender: string, receiver: string, value: string, amount: string, gasPrice: number) {
    let data = this.tokenContract.methods.transfer(receiver, amount).encodeABI();
    let gas = await this.web3.eth.estimateGas({
      value,
      data,
      from: sender,
       to: this.CONTRACT_ADDRESS
    });
    let nonce = await this.getNonce(sender);
    return {
      value,
      // data,
      from: sender,
      to: this.CONTRACT_ADDRESS,
      gas: this.web3.utils.toHex(Math.trunc(gas)),
      gasPrice: this.web3.utils.toHex(Math.trunc(gasPrice * 1e9)),
      chain: this.web3.utils.toHex(1337),
      nonce,
      hardfork: "MUIRCLACIER"
    }
}

It only works to send tokens when value is 0. If value is positive it fails at the gas estimation step with the error below. It only works if data field is removed from gas estimation and transaction, it sends the specified value successfully.

The question, is it technically possible to do both: send ether and invoke a function on the contract in a single transaction?

{
  "message": "VM Exception while processing transaction: revert",
  "code": -32000,
  "data": {
    "stack": "RuntimeError: VM Exception while processing transaction: revert\n    at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n    at module.exports (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)",
    "name": "RuntimeError"
  }
}
Error: Internal JSON-RPC error.
{
  "message": "VM Exception while processing transaction: revert",
  "code": -32000,
  "data": {
    "stack": "RuntimeError: VM Exception while processing transaction: revert\n    at Function.RuntimeError.fromResults (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n    at module.exports (/Applications/Ganache.app/Contents/Resources/static/node/node_modules/ganache-core/lib/utils/gas/guestimation.js:142:32)",
    "name": "RuntimeError"
  }
}

is it technically possible to do both: send ether and invoke a function on the contract in a single transaction?

Yes. The function receiving ETH needs to be have the payable modifier.

function foo() external payable {
    // the received amount is in the global variable `msg.value`
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM