I'm writing a 2 Player Game. Rules:

  • Player 1 must place a bet (and send some ether to the contract).

  • Then, Player 2 must match the bet placed by Player 1, and send the same exact amount of ether to the contract as well.

Right now, my constructor works well. It allows Player 1 to send ether to my contract.

I know I can add a parameter to matchBet() and require that msg.value equals the contract balance.

But is there a way to make Player 2 match Player 1's bet, without any parameters?

I would like:

  1. Player2 calls matchBet() without any parameters
  2. matchBet() reads address(this).balance
  3. matchBet() pulls address(this).balance from Player 2 to the Smart Contract.
    constructor() public payable {
        require(msg.value > 0, "Player 1 must bet a positive amount");
        assert(address(this).balance == msg.value); // Contract balance should == Player 1's bet
    function matchBet() external payable {
        require(msg.sender != players[0].addr, "Player 1 can't match his own bet.");
        //require(msg.value == address(this).balance, "Player 2 must match Player 1's bet");

I found this: How is it possible for a contract to automatically charge an amount to an external account? but that question is a bit old.

Maybe in the meantime a solution was created?

1 Answer 1


Smart contracts cannot "pull" Ether from an external address. All transactions have to be sent by the user itself. You can however use wrapped ETH, which is essentially Ether wrapped as an ERC-20 token, where 1 ETH equals 1 WETH.

Both users have to convert their ETH into WETH first. You can make a flow for this on your dApp's website. Then, have both players approve a transaction for the WETH, so your contract can use ERC-20's transferFrom to transfer the tokens.

Your Answer

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

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