1

Is it possible to return ether sent to a smart contract payable function, by using transfer to return funds to the sender?

I am experimenting with a use case where a contract keeps a list of buyers who have sent a sufficient quantity of ether, and return any excess ether as 'change'. I have a contract that looks a bit like the following:

pragma solidity '0.4.19';

contract Purchaseable {
  uint public price;
  address[] public buyers;

  function buy() public payable {
    require(msg.value >= price);

    // Keep a list of buyers who have transferred enough ether
    buyers.push(msg.sender);

    // Give the sender some change
    uint change = msg.value - price;
    // This line blows up with VM Exception: revert
    msg.sender.transfer(change); 
  }
}

However, the last line msg.sender.transfer blows up. It's hard to debug from there. Why doesn't this work?

One theory I have was that maybe it is impossible to transfer funds back to the sender as part of the same transaction. I can't find any documentation of what transfer actually does in reference to blocks and transactions to know if my approach is even supported. Is there a better way to part refund ether sent to a payable function?

  • attendees.push(msg.sender); you haven't defined attendees, you should write buyers there. – Aniket May 3 '18 at 11:27
  • So is it working now? – Aniket May 3 '18 at 13:36
  • Accepted answer was correct you spotted a typo. I was paraphrasing from some other code – Dan Garland May 3 '18 at 15:36
  • okay, no problem – Aniket May 4 '18 at 13:53
3

Is msg.sender a contract in this case? For a contract to receive ether by transfer or send, it should have a payable fallback function, which does not consume more that 2300 gas.

pragma solidity ^0.4.23;

contract Payable {

    // The fallback function has no name and should be payable
    function() public payable {
        emit GotPaid(msg.value);
    }

    event GotPaid(uint256 value);
}
  • Yes well deduced! It was being tested from a solidity unit test contract, and I didn't have a payable fallback function. I recall running into this before but it's not at all intuitive that this is the error from the 'VM Exception revert'. Makes sense now, – Dan Garland May 3 '18 at 13:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.