0

I have a payble function that has some logic. I want that logic to be triggered only if the received amount is equal to the amount specified when the contract was created.

Solidity v0.7.6

receive() external payable {
  require(msg.value == requiredAmount,"Incorrect amount");

  logic();
}

The problem is that the transaction always fails when I send Ether through MetaMask, no matter how much Ether I sent. I tried checking the msg.value against a fixed amount, still the same issue:

receive() external payable {
  require(msg.value == 1 ether,"Incorrect amount"); // transaction always fails, even if I send exactly 1ETH.

  logic();
}

What's even more confusing to me is that I know the requiredAmount variable is set properly, because when I use if/else the code gets executed as expected:

receive() external payable {
  if (msg.value != requiredAmount) { // correctly sends back the Ether if the amount isn't equal to the requiredAmount variable
    (bool success,) = msg.sender.call{value: msg.value}("");
    require(success, "Failed to send Ether");
    emit MoneyReturned(msg.sender, msg.value);
  } else {
    logic();
  }
}

Does anyone have any idea why using require in the manner that I want doesn't seem to work for me?

3 Answers 3

0

So I just tested this in remix and it works perfectly fine, perhaps you got a function keyword wrong?

pragma solidity ^0.7.6;

contract test {
    event correctpaymentRecieved(string);
    function receive() external payable {
        require(msg.value == 1 ether, "Incorrect amount"); // transaction always fails, even if I send exactly 1ETH.
        emit correctpaymentRecieved("We got the correct amount of money");
    }
}

If I deploy that contract, then set message value to 1 ether in Remix, and then call the receive function checking the tx data I can see the correctpaymentRecieved Log is emited

2
  • Sorry, I should have specified that in the original message - I use MetaMask to send Ether to the smart contract. Does the code also work for you in that case? Commented Jun 1, 2021 at 11:25
  • I am using Remix to make the contract call, Metamask is most likely sending the ether to the contract (as its payable contract) rather than specifically calling the function. Remix is a much better testing environment though. Commented Jun 1, 2021 at 21:19
0

This seems to work for me:

modifier costs(uint _amount){
        require(msg.value >= _amount,
        'Not enough Ether provided!');
        _;
    }

function forceOwnerChange(address _newOwner) public payable costs(200 ether){
       
        owner = _newOwner;
    }

0

I believe there is a problem with the way you are interacting with the smart contract. If you are just "sending ether through metamask" to the address, you will not be triggering the receive() function. You should try interacting through etherscan, or any thing that lets you interact with the ETH network.

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.