¿Cómo crear una función Pagadera que solo acepte un token de cliente?

Tengo una pregunta para la que parece que no puedo encontrar una respuesta, espero que la comunidad pueda ayudar (y esta es mi primera publicación aquí, así que pido disculpas si esta es la pregunta incorrecta para hacer en primer lugar).

Estoy tratando de crear un contrato con una función Pagadera que solo acepta un token específico, no ETH, como pago. Soy dueño tanto del contrato de token como de este contrato que se creó específicamente para aceptar el pago de ese token en particular.

¿Es esto posible? Encontré esto como una posible solución:

Fuente: ¿ Cómo creo un crowdsale que solo acepta un token erc20 específico?

contract Crowdsale {

        address owner;  
        mapping(address => uint256) balances;
        function Crowdsale(){
            owner = msg.sender;
        }

        function acceptOnlyMyToken(address _yourTokenAddress, uint256 amount){
            address user = msg.sender;
            YourToken token = YourToken(_yourTokenAddress);

            //get the user's balance
            uint256 userBalance = token.balanceOf(user);
            //check user's balance
            if(userBalance >= amount){      
                token.transferFrom(user, owner, amount);        

            }

        }

    }

¿Es seguro asumir lo siguiente con el código anterior?

  1. Reemplazar YourToken token = YourToken(_yourTokenAddress);con YourToken token = YourToken(address(0xABCD...));"0xABCD" siendo la dirección de mi token que está en un contrato separado debería funcionar.
  2. Especificar require(msg.value == 100bajo la acceptOnlyMyToken(...)función me permitiría establecer el monto de pago específico requerido.

Además, no veo que esta función se llame "a pagar", ¿importa esto? La razón es porque quiero pasar variables como parte de la función para hacer el trabajo XYZ como parte de la lógica del contrato, por lo que recibo un pago por una cantidad específica de ese token.

¿Alguna idea?

Respuestas (1)

No se utiliza payablepara el tipo de transferencia sin protocolo. ERC20 no es un "protocolo" porque está definido en un contrato.

No hay forma de detectar tokens ERC20 que se transfieren a ciegas a un contrato. En el mejor de los casos, el contrato puede verificar su saldo pero no sabrá quién envió el dinero, por lo que esto no es bueno.

uint myTokenBalance = IERC20(<tokenAddress>).balanceOf(address(this));

Está buscando el patrón "aprobar y transferir de". Dice así:

  1. El usuario autoriza a su contrato a retirar del saldo de tokens del usuario.

  2. Luego, el usuario llama a una función en su contrato que intenta obtener los tokens.

El paso 2 se ve así:

function sendMe100() external {
  IERC20(<tokenAddress>).transferFrom(msg.sender, address(this), 100);
  // success
}

Lo anterior supone que el usuario ha autorizado la transferencia llamando primero a la approvefunción en el contrato ERC20 (paso 1), pero eso suele ser una preocupación inicial que no afecta a su contrato.

Espero eso ayude.