Как валидировать платежи ERC-20 в контракт?

Я пишу смарт-контракт, который будет что-то делать, пока пользователь, запрашивающий эту функцию, заплатил правильную сумму. Если сумма указана в ETH, я могу легко сделать это с помощью простого оператора require, подобного этому:

function doSomething() public payable {
    require(msg.value == 1 ether);  // make sure they paid
    // if they paid, proceed with the action
}

Однако, если я захочу принимать другие токены ERC-20 вместо ETH, я не уверен, как я смогу это сделать в рамках своего контракта (т. е. без запуска собственного отдельного сервера, прослушивающего блокчейн и отслеживающего отдельные транзакции).

Поскольку все передачи токенов ERC-20 происходят внутри контракта для конкретного токена (а не внутри методов моих смарт-контрактов), как мой контракт узнает или подтвердит это:

  1. Переведена правильная сумма.
  2. Сумма была переведена с адреса А.
  3. Сумма была переведена на адрес Б.

Где A — мой смарт-контракт, а B — пользователь.

Ответы (2)

Некоторые токены ERC20 имеют функции approveи transferFrom. В этих случаях вы можете предоставить пользователю approveнесколько токенов к вашему контракту. Затем они могут вызвать функцию в вашем контракте, которая будет вызывать transferFromконтракт токена.

Это требует, чтобы пользователь выполнил как минимум две транзакции: одну для вызова approveконтракта токена и одну для вызова функции в вашем контракте, которая, в свою очередь, вызовет transferFromконтракт токена.

Если токен ERC20 не имеет approveи transferFrom, вам нужен отдельный сервер для прослушивания блокчейна и вызова вашего контракта.

ERC20, на мой взгляд, довольно плохо продуман, и он не был предназначен для решения этой ситуации. Вот почему существуют другие стандарты токенов, такие как ERC223: https://github.com/Dexaran/ERC223-token-standard

Если токены ERC223 перенесены в ваш контракт, контракт токена вызовет функцию tokenFallbackв вашем контракте. Это позволяет осуществить передачу, проверку и логику вашего контракта в рамках одной транзакции.

Получается, что нет реального способа сделать это с помощью одной транзакции, если это токен ERC-20 (в отличие от ERC223)? Похоже, approveи transferFromтехника - единственный вариант.
@adrianmc Если контракт токена не может доставить обратный вызов, вам нужно как минимум две транзакции.

Это можно сделать за одну транзакцию. Вы должны использовать approveAndCall. Используя эту функцию, пользователь одобрит несколько токенов и вызовет ваш контракт в одной и той же транзакции. Таким образом, ваш контракт получит уведомление о передаче токена. Это, конечно, подразумевает, что контракт реализуется, approveAndCallно есть вероятность, что это реализовано, потому что approveAndCallэто находится в определении стандартного токена ERC20.

Надеюсь это поможет