transferring ethereum from the user of your smart contract is simple enough, you simply use msg.value and can use this within your contract's functions. But doing the same thing with tokens is a bit more tricky consider the following contract

pragma solidity ^0.4.24;
import "../node_modules/zeppelin-solidity/contracts/math/SafeMath.sol";
import "../node_modules/zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "../node_modules/zeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
contract TokenExchange{
  struct Order {
    uint id;
    State state;
    address buyer;
    address seller;
    uint antAmmount;
    uint daiAmmount;
  ERC20 public token1;
  ERC20 public token2;
  mapping (uint => Order) public globalOrders;      
  uint private nextOrderId;
  constructor () public {
      token1 = ERC20(0x1111111111111111111111111111111111111111); 
      token2 = ERC20(0x2222222222222222222222222222222222222222); 
  function createBuyOrder(uint _buyAmmount, uint _sellAmmount) external payable {
    uint deposit = _buyAmmount.div(2);    

    // How to transfer tokens from message sender to this contract

    Order memory newOrder = Order({
            id: 0, 
            state: State.OPEN, 
            buyer: msg.sender, 
            seller: 0x0000000000000000000000000000000000000000, 
            token1Ammount: _buyAmmount, 
            token2Ammount: _sellAmmount 
    globalOrders[nextBuyOrderId] = newOrder;

if we were dealing with eth we could simply require msg.sender to equal the deposit vaue. Also we cant use token.aprove() and transferFrom() within the function as this would be aproving the contracts balance and not msg.sender

so my question is this: how do I request the message sender to send the deposit to the contract and how do I test if the message sender has sent the required amount?

1 Answer 1


approve() and transferFrom() is a two-step process. You expect/require it to be coordinated on the user/client side.

Step 1. Client approves the contract to draw from their account.

Step 2. Client sends a transaction to the contract and the contract does a transferFrom() to attempt to access the tokens. Your contract would only be concerned with this part. It looks like it would fit right where your comment is.

You could also consider ERC223 if you are implementing a token. Such a token contract expects the receiver, if it is a contract, to implement a tokenFallback() that it will call when tokens are transferred to it.

Hope it helps.

  • 1
    Thank you! So my confusion was with the approve function. I thought there was a way to request the user to approve the transfer from within the contract.
    – AbuUsama
    Jul 23, 2019 at 9:15
  • examples are nice... 😢
    – lopezdp
    Jul 18, 2021 at 15:42

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.