1

Im trying to run the following solidity-by-example on remix:

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

contract Payable {
// Payable address can receive Ether
address payable public owner;

// Payable constructor can receive Ether
constructor() payable {
    owner = payable(msg.sender);
}

// Function to deposit Ether into this contract.
// Call this function along with some Ether.
// The balance of this contract will be automatically updated.
function deposit() public payable {}

// Call this function along with some Ether.
// The function will throw an error since this function is not payable.
function notPayable() public {}

// Function to withdraw all Ether from this contract.
function withdraw() public {
    // get the amount of Ether stored in this contract
    uint amount = address(this).balance;

    // send all Ether to owner
    // Owner can receive Ether since the address of owner is payable
    (bool success, ) = owner.call{value: amount}("");
    require(success, "Failed to send Ether");
}

// Function to transfer Ether from this contract to address from input
function transfer(address payable _to, uint _amount) public {
    // Note that "to" is declared as payable
    (bool success, ) = _to.call{value: _amount}("");
    require(success, "Failed to send Ether");
}

}

Once deployed, when I call the "transfer" function using any of the remix' javascript VM addresses as the _to and the number 1 as _amount its reverting with the following:

revert The transaction has been reverted to the initial state. Reason provided by the contract: "Failed to send Ether".

I don't think it has to do with access but with how I am introducing the attributes. Can anyone point me the right way to do it? Thank you in advance!

3 Answers 3

1

One simple solution is to add this function to your code, to correctly receive tokens to the contract:

receive() external payable { }

I found sending ETH to the contract posed errors regardless of gas, which would be expected without the above function.

Second, you should consider that when you input the amount of ETH you send, unless specified otherwise in your code (ie _amount * 10**18) the amount of ETH sent does not have a decimal. This means that the input of "1" really means "0.000000000000000001 ETH"

1

tested this smart contract on remix (0.8.11+) was able to

  1. deposit 1 ether using deposit function
  2. transfer 1 ether to an EOA. Is the _to address a contract in your case? _to address contract can't receive ether without receiver fallback function

also _to address doesn't need to be payable,

function transfer(address  _to, uint _amount) public {}

as call invocation does not need the address to be payable

0

Your contract probably doesn't have enough ether to send to another account. When deploying, make sure it received enough amount so that later, when calling the transfer function, it can perform the transfer.

4
  • Still doesn't work :( Thank you for your answer anyways João! Feb 10, 2022 at 18:33
  • I got it to work by: 1. Adding the payable word in the function as suggested by the first comment, i.e function transfer(address payable _to, uint _amount) public payable { 2. Specifying value when setting the deploy config of the contract and also putting that same value in the attribute of the function transfer. I wonder why is it doing that? Is there a way to bypass the value up in remix deployment and use the one specified in the contract? Feb 10, 2022 at 19:35
  • To send ether from the contract to another address, this contract needs to have at least that amount. So you must send more (or equal) ether to the contract than the contract has. Did you check if you sent more ether to the contract than the amount of ether you are trying to transfer to another account? Feb 10, 2022 at 22:18
  • By the way, sorry about my answer, I misunderstood your initial question. If you don't want to receive ether through the transfer function, it doesn't need to be payable. I will edit my answer. Feb 10, 2022 at 22:29

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.