7

If I have a function:

contract one {
      function buyTokens(address _beneficiary) public payable {
        require(msg.value == 1 ether);
       // do something...
      }
}

How do I call that function and also pay ether using solidity?

contract two {
    ...
    function doBuy(uint _amount) public {
       one.buyTokens(msg.sender, _amount);
    }

How do I set msg.value as part of the function call?

Mark Irvine
  • 183
  • 1
  • 1
  • 8

2 Answers2

10

If I understand your question correctly, you want to make a call from one contract to another contract's payable function and make an ETH transfer with it, if so you can do it with:

address.function{ value: amount }(arg1, arg2, arg3)

In your case:

function doBuy(uint _amount) public {
   contractOfTheBuyTokensFunction.buyTokens{ value: _amount }(msg.sender);
}
caffeinum
  • 142
  • 7
Nikolay Deshev
  • 304
  • 1
  • 6
3

Things like msg.sender and msg.value will stay constant for a single transaction, no matter how many different functions are called throughout the process. So you do not need to pass these values around, they are always available by default in each function's context.

So in this case, where you have one function which simply calls another, you could just do:

pragma solidity ^0.4.24;

contract test{

    mapping(address => bool) public buyers;

    function doBuy() public payable {
       buyTokens();
    }

    function buyTokens() private returns(address){
      require(msg.value == 1 ether);
      buyers[msg.sender] = true;
    }
}

A few things to note here, which is different than your code snippet.

  • You need to make doBuy() payable since it is the entry point for the second function, and ultimately it is the function that users call and send the Ether to.
  • You do not need to make buyTokens() payable, since it is not directly called by the user.
  • I made buyTokens() private because I suspect that the user is supposed to call doBuy() and not buyTokens()
  • You will see that buyTokens() has access to both msg.value and msg.sender even though it is never directly called or passed those values.
Shawn Tabrizi
  • 8,008
  • 4
  • 19
  • 38