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:
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.