Solidity

具有支付功能的契約可以一次性接收 ERC20 代幣?

  • November 10, 2020

我正在嘗試使用接收 ERC20 令牌(即:DAI)的函式編寫智能合約,但呼叫此函式的事務總是失敗。

假設我首先將 ERC20 合約地址記錄在一個可以處理多個代幣的映射中,但對於這個範例,我只是將“DAI”作為 tokenName 並在 Ropsten 中分配其 DAI 合約地址:

contractAddressERC20[tokenName] = 0xaD6D458402F60fD3Bd25163575031ACDce07538D;

我也在使用 OpenZeppelin 的 ERC20 介面:

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

然後,我有這個功能來接收 ERC20 代幣。例如,我將傳遞 ‘DAI’ 作為 tokenName 和 1 DAI (1000000000000000000)

function depositERC20Token(string memory tokenName, uint256 amount) public {
   IERC20(contractAddressERC20[tokenName]).approve(address(this), amount);
   IERC20(contractAddressERC20[tokenName]).transferFrom(_msgSender(), address(this), amount);
   emit DepositERC20Token(tokenName, _msgSender(), amount);
}

但是,呼叫此函式總是失敗。不確定使用者是否應該直接從 DAI 合約中呼叫“approve”函式,然後僅使用“transferFrom”從我的合約中呼叫“depositERC20Token”。難道不能從我的契約中進行“批准”和“轉帳”嗎?如果沒有,使用者應該執行 2 個事務,從使用者體驗的角度來看,這不是很好。

呼叫此契約時,有沒有辦法一次性完成批准和轉移?我聽說過 ERC777,但如果可能的話,我更願意保持 ERC20 標準。

*_msgSender() 等價於 msg.sender,在 OpenZeppelin 的 Context.sol 中定義

通過approve(someAccount, someAmount)在合約功能中執行,您正在批准從該合約someAccount轉移至。someAmount

因此,通過approve(address(this), someAmount)在合約函式中執行,您正在批准該合約從其自身轉移代幣!

顯然,它不允許你再執行transferFrom(someOtherAccount, ..., ...),因為合約沒有被批准從someOtherAccount.

而且你無論如何都不希望它允許這樣做,因為如果它允許,那麼整個 ERC20 模型作為一個金融系統將毫無價值,因為你可以批准並從任何你想要的賬戶轉移。

簡而言之,您需要在approve 此合約之外呼叫,使用您希望此合約從中轉移代幣的帳戶。

引用自:https://ethereum.stackexchange.com/questions/90041