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{
enum State {OPEN, FILLED, CLOSED, CANCELED}
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;
nextBuyOrderId++;
}
}
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?