2

I am trying to deposit Ether on a smart contract. Looking at the documentation my approach first looked like this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.0.8;

contract SendEther {

    function deposit(uint256 amount) public payable {
        require(msg.value == amount);
    }
}

However, that failed with the following error message:

[vm]

from: 0x5c6...21678

to: SendEther.deposit(uint256) 0xe63...4ddf5

value: 0 wei

data: 0xb6b...03039

logs: 0

hash: 0x50c...acc83

status false Transaction mined but execution failed

transaction hash 0x50cb8aab1042aef79e8bf285346213a1edfa106b2a7421ee159da82b693acc83

from 0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678

to SendEther.deposit(uint256) 0xe63D12C600b87F5da3C32C7cB3C1b1A84944ddf5 gas 3000000 gas transaction cost 21614 gas execution cost 21614 gas input 0xb6b...03039 decoded input { "uint256 amount": "12345" } decoded output {} logs [] val 0 wei

transact to SendEther.deposit errored: VM error: revert.

revert The transaction has been reverted to the initial state.

Note: The called function should be payable if you send value and the value you send should be less than your current balance.

Debug the transaction to get more information.

Then I tried to use the transfer or call method to send Ether.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SendEther {

    receive() external payable {}

    function sendViaTransfer(address payable to, uint256 amount) public payable {
        to.transfer(amount);
    }
}

Which resulted in this error:

[vm]

from: 0x147...C160C

to: SendEther.sendViaTransfer(address,uint256) 0x70c...a304B

value: 0 wei

data: 0xd27...004d2

logs: 0

hash: 0xc29...0cf23

status false Transaction mined but execution failed

transaction hash 0xc296ba642bca2e19c304a9e28381b3b523fdb86a94fcbc19e14ad5847a20cf23

from 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C

to SendEther.sendViaTransfer(address,uint256) 0x70c001c84C723e3EfbF852D3e6AdaEb69A8a304B

gas 3000000 gas

transaction cost 29070 gas

execution cost 29070 gas

input 0xd27...004d2

decoded input {

"address to": "0x70c001c84C723e3EfbF852D3e6AdaEb69A8a304B",

"uint256 amount": "1234"

}

decoded output {}

logs []

val 0 wei

transact to SendEther.sendViaTransfer errored: VM error: revert.

revert The transaction has been reverted to the initial state.

Trying to use "call" or "send" results in the same error.

What am I doing wrong?

3
  • the first one looks like it should work (i.e. accept Eth on that contract) but according to the error output, you didn't send any Eth when you called it i.e. value: 0 wei. Are you using remix?
    – sola24
    Sep 5, 2022 at 18:15
  • Yes, I am using remix.
    – rajohs
    Sep 5, 2022 at 19:05
  • make sure you set an amount to send in remix before you execute a function
    – sola24
    Sep 6, 2022 at 6:34

2 Answers 2

1

the log says message value is 0. Make sure to set VALUE in remix before clicking on the functions so it sends value

set value to send when calling function

1
  • yeah, that was my mistake. Thank you
    – rajohs
    Sep 6, 2022 at 16:39
0

First, for the first example, I don't think you need to require(msg.value == amount). msg.value is the eth value sent to this contract. The amount parameter is not doing much there. And this function will revert if the msg.value sent is not the same as the amount. But anyways, doing this is redundant. But make sure that if you send an amount parameter of 5, then you should send 5 weis as well so this function does not fail.

function deposit(uint256 amount) public payable {
        require(msg.value == amount);
    }

The second example look fine. But your contract needs to have at least amount of balance or you should send a balance (msg.value) the same as the amount parameter.

function sendViaTransfer(address payable to, uint256 amount) public payable {
        to.transfer(amount);
    }

I wrote some code with all the ways you can receive and send ether, with some comments, It might be helpful for you. All of the example work. Just remember to ether have enough balance in your SendEther contract before trying to send ether to another address, or send enough ether to that contract so it can use the msg.value and send that amount.

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Receiver {
    receive() external payable {}

    fallback() external payable {}

    function receiveBalance() public payable {}

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

    //.. Other functionalities here (withdraw, etc).
}

contract SendEther {

    address public owner = msg.sender;

    // Maybe you want to control who can withdraw the balance from this contract.
    modifier onlyOnwer() {
        require(msg.sender == owner);
        _;
    }

    function deposit(uint256 amount) public payable {
        require(msg.value == amount); // No need to send or check an amount here.
    }

    function deposit_v2() public payable {
        // We have the option to do nothing here. As long as the function is `payable`, we receive the eth.
    }

    // If you want to only receive eth without doing any special logic, then you can use `receive` and/or `fallback`.
    receive() external payable {}

    fallback() external payable {}

    // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
    function sendViaTransfer(address payable to, uint256 amount) public payable onlyOnwer {

        // Maybe you want to check that this contract has enough balance to send the requested amount.
        require(address(this).balance >= amount, "Not enough balance in the contract.");

        to.transfer(amount);
    }

    // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
    function sendViaTransfer_v2(address payable to) public payable onlyOnwer {
        to.transfer(msg.value);
    }

    // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
    function sendViaSend(address payable to, uint256 amount) public payable onlyOnwer {

        // Maybe you want to check that this contract has enough balance to send the requested amount.
        require(address(this).balance >= amount, "Not enough balance in the contract.");

        bool success = to.send(amount);
        require(success, "Error sending eth");

    }

    // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
    function sendViaSend_v2(address payable to) public payable onlyOnwer {
        bool success = to.send(msg.value);
        require(success, "Error sending eth");
    }

    // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
    function sendViaCall(address payable to, uint256 amount) public payable onlyOnwer {

        // Maybe you want to check that this contract has enough balance to send the requested amount.
        require(address(this).balance >= amount, "Not enough balance in the contract.");

        (bool success, ) = to.call{value: amount}("");
        require(success, "Error sending eth");

    }

    // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
    function sendViaCall_v2(address payable to) public payable onlyOnwer {
        (bool success, ) = to.call{value: msg.value}("");
        require(success, "Error sending eth");
    }

    // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
    function sendViaCustomFunction(address payable to, uint256 amount) public payable onlyOnwer {

        // Maybe you want to check that this contract has enough balance to send the requested amount.
        require(address(this).balance >= amount, "Not enough balance in the contract.");

        Receiver(to).receiveBalance{value: amount}();

    }

    // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
    function sendViaCustomFunction_v2(address payable to) public payable onlyOnwer {
        Receiver(to).receiveBalance{value: msg.value}();
    }

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

}
1
  • I tried your examples, but they throw the same error. Except for the deposit function, but I am still depositing 0 wei.
    – rajohs
    Sep 5, 2022 at 19:06

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.