1

I'm trying to call a function with no parameters and send Ether to it. I'm using React, Hardhat, and Ethersjs. The smart contract looks like this.

pragma solidity ^0.7.6;

contract EtherCoinFlip {
    uint256 etherWinnings;

    struct EtherCoinFlipStruct {
        address payable betStarter;
        uint256 startingWager;
        address payable betEnder;
        uint256 endingWager;
        uint256 etherTotal;
        address payable winner;
        address payable loser;
    }

uint256 numCoinFlips = 300;
mapping(uint256 => EtherCoinFlipStruct) EtherCoinFlipStructs;

// Emit the event
event EtherCoinFlipped(uint256 indexed theCoinFlipID);

// Start the Ether coin flip
function newPureCoinFlip() public payable returns (uint256 coinFlipID) {
    coinFlipID = numCoinFlips++;
    EtherCoinFlipStructs[coinFlipID] = EtherCoinFlipStruct(
        msg.sender, //address payable betStarter;
        msg.value, // uint256 startingWager;
        msg.sender, // address payable betEnder;
        msg.value, // uint256 endingWager;
        0, // uint256 etherTotal;
        msg.sender, // address payable winner;
        msg.sender // address payable loser;
    );
    emit EtherCoinFlipped(coinFlipID);
}

event EtherCoinFinishedFlip(address indexed winner);


function endPureCoinFlip(uint256 coinFlipID)
    public
    payable
{
    require(coinFlipID == coinFlipID);
    EtherCoinFlipStruct memory c = EtherCoinFlipStructs[coinFlipID];
    c.betEnder = msg.sender;
    c.endingWager = msg.value;
    c.etherTotal = c.startingWager + c.endingWager;

    uint256 finalVerdict = block.number +
        block.timestamp +
        msg.value +
        block.difficulty +
        block.gaslimit +
        tx.gasprice +
        1;

    if ((finalVerdict % 2) == 0) {
        c.winner = c.betStarter;
    } else {
        c.winner = c.betEnder;
    }

    c.winner.transfer(c.etherTotal);

    emit EtherCoinFinishedFlip(c.winner);
}

}

The function in my App looks like this.

  async function startCoinFlip() {

if (typeof window.ethereum !== 'undefined') {
  await requestAccount()
  const provider = new ethers.providers.Web3Provider(window.ethereum);
  const signer = provider.getSigner();
  const contract = new ethers.Contract(ECFAddress, EtherCoinFlip.abi, signer);
  let tx = {
    to: ECFAddress,
    value: ethers.utils.parseEther(wager),
  }
  let tx2 = await signer.sendTransaction(tx);
  // call the coinFlip function and send the wager in ether to the contract
  const coinFlip = await contract.startCoinFlip()
  coinFlip.wait();
  tx2.wait();
  console.log(`You started the wager with ${wager} ETH`);
}
  }

I'm using state to transfer the wager variable like this.

  const [wager, setWager] = useState() // amount of ether to send to Eth coin flip

And it all comes together in the JSX like this.

  <h1>Ether Coin Flip</h1>
  <h3>Send your ETH to this contract with a 50/50 shot to double it!</h3>
  <button value={wager} onClick={startCoinFlip}>Start the coin flip!</button>
  <input onChange={e => setWager(e.target.value)} placeholder="Send your ETH"/>
  <br />

I've rewritten the smart contract. Changed the wager type. Send the Ether in a separate function. None worked. Here's the error I get.

Unhandled Rejection (Error): cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32000,"message":"execution reverted"}, method="estimateGas", transaction={"from":"0x0a337D5f4E3ba3f9eb413884d803dA8F1C8a9981","to":"0x16592Aecc7a43181889Ed6D6BDa8d813366B2381","value":{"type":"BigNumber","hex":"0x0de0b6b3a7640000"},"accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.4.5)

1 Answer 1

1

The way to pass the Ether value into the the function was to pass it in as an object.

The startCoinFlip function should look like this. Also had to convert the wager with the updatedWager variable a bit. Ethers.js only accepts strings in this case.

This actually has to do with the older version of Solidity in this case. Notice this contract is using 0.7.6 as opposed to something more recent.

  async function startCoinFlip() {
    if (typeof window.ethereum !== 'undefined') {
      await requestAccount()
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const signer = provider.getSigner();
      const contract = new ethers.Contract(ECFAddress, EtherCoinFlip.abi, signer);
      let updatedWager = ethers.utils.parseEther(wager.toString());
      const tx = await contract.newPureCoinFlip({ value: updatedWager });
      tx.wait();
      console.log(`You started the wager with ${ethers.utils.formatEther(updatedWager)} ETH`);
    }
  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.