Cómo solicitar tokens de msg.sender dentro de la función de contrato

transferir ethereum del usuario de su contrato inteligente es bastante simple, simplemente use msg.value y puede usar esto dentro de las funciones de su contrato. Pero hacer lo mismo con tokens es un poco más complicado, considere el siguiente contrato

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++;
  }
}

si estuviéramos tratando con eth, simplemente podríamos requerir que msg.sender iguale el valor del depósito. Además, no podemos usar token.aprove() y transferFrom() dentro de la función, ya que esto sería aprobar el saldo de los contratos y no msg.sender

entonces mi pregunta es la siguiente: ¿cómo solicito al remitente del mensaje que envíe el depósito al contrato y cómo pruebo si el remitente del mensaje ha enviado la cantidad requerida?

Respuestas (1)

approve()y transferFrom()es un proceso de dos pasos. Espera/requiere que se coordine en el lado del usuario/cliente.

Paso 1. El cliente aprueba el contrato para retirar de su cuenta.

Paso 2. El cliente envía una transacción al contrato y el contrato intenta transferFrom()acceder a los tokens. Su contrato sólo se referiría a esta parte. Parece que encajaría justo donde está tu comentario.

También podría considerar ERC223 si está implementando un token. Tal contrato de token espera que el receptor, si es un contrato, implemente un contrato tokenFallback()que llamará cuando se le transfieran los tokens.

Espero eso ayude.

¡Gracias! Entonces mi confusión fue con la función de aprobación. Pensé que había una forma de solicitar al usuario que aprobara la transferencia desde el contrato.
los ejemplos son buenos... 😢