5

The code is as following, if Contract send ether to Contract Receiver, I will recevice: transact to Sender.send errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The constructor should be payable if you send value.

However, if I annotate line "addr = msg.sender;" "amount = msg.value;" everything is ok, and I will receive the event log

pragma solidity ^0.4.11; contract Receiver { address public addr; uint public amount; event log(address, uint); function() payable{ addr = msg.sender; amount = msg.value; log(msg.sender, msg.value); } function Receiver() public payable { addr = msg.sender; amount = msg.value; } } contract Sender{ function send(address addr, uint amount) payable{ addr.transfer(amount); } function getBalance() payable returns (uint) { return this.balance; } function Sender() payable{ } }

1 Answer 1

4

When calling a fallback function with either send() or transfer() on another contract (which is what is happening when you call send(address addr, uint amount) in the Sender contract) there is a restricted allowance of 2300 gas for security reasons. Unfortunately 2300 gas is not enough to do these instructions addr = msg.sender; amount = msg.value;.

In order to execute those instructions and receive Ether at the same time, you will need to create a payable named function, not fallback, in the Receiver contract which the Sender contract calls explicitly.

4
  • I have already tried this method, but the same error I got. pragma solidity ^0.4.11; contract Receiver{ uint public value; event log(address, uint256); function() payable public{ test(); } function test() payable{ value = msg.value; log(msg.sender, msg.value); } function Receiver() payable{} } contract Sender{ function send(address addr, uint amount){ addr.transfer(amount); } function Sender() payable{} } Jan 18, 2018 at 13:53
  • Replace addr.transfer(amount); with Receiver(addr).test.value(amount)();. This casts the addr to an instance on the Receiver contract then calls the function test() on that contract and sends the amount of ether with value(). This way you will no longer be calling the fallback function which restricts you to 2300 gas. See a few paragraphs down in this part of the doc for an explanation of .value()
    – willjgriff
    Jan 18, 2018 at 14:45
  • I find many ICO contract on Github interacts with storage variables or calls other function(I failed in the same way), for example Contract The fallback function interacts with balances; Therefore, these contracts contain errors? Jan 18, 2018 at 15:43
  • The 2300 gas restriction is applied when you use either send() or transfer() from within a contract to another contract, like your Sender contract does. If you send a transaction to the Receiver contract normally, from outside any smart contracts, there is no 2300 gas restriction.
    – willjgriff
    Jan 18, 2018 at 15:50

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.