Solidity Remix – Why Cannot Ether be Sent to This Smart Contract?

etherremixsolidity

Currently have this smart contract written in Remix.

I deploy the contract using the JavaScript VM on the topmost account

Then I switch accounts and then call the function like so:

enter image description here

To send 4 ether from the account to the smart contract. However, my transaction fails.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

/**
 * @title PayableContract
 * @dev send ether to a smart contract 
 */
contract PayableContract {
    constructor() {} 

    event PaymentReceived(address indexed _sender, uint _before, uint _after);

    function getContractBalance() public view returns (uint256) {
        return address(this).balance; 
    }

    function sendPaymentToContract(uint _amount) payable external 
    {
        uint beforeBalance = getContractBalance();
        payable(address(this)).transfer(_amount);
        uint afterBalance = getContractBalance();
        emit PaymentReceived(msg.sender, beforeBalance, afterBalance);
    }
    
    receive() payable external {}
}

After I call the function, I expect to see my balance go from 100 ether on the left part of the Remix IDE to 95.999… (100 ether – 4 – gas costs). However, the 4 ether does not get withdrawn, but only the gas costs.

I get that the transfer() function is bad for safety reasons. I just did it for clarity. I also understand that this is suboptimal and bad code since I can just use msg.value instead. However, I am wondering why exactly this doesn't work. It seems like it should.

Best Answer

Well, what you pass is an argument to the function only. It has no value in solidity. As you mentioned, you can remove the argument and use msg.value. If you want to represent the value in your argument, you have to use the same amount both in your argument and the "VALUE" section of the remix.

If you don't use the pass VALUE, your function argument will not have a value.

Here is an example.

Related Topic