Erc-20
在部署時將 ERC20 發送到合約
我正在嘗試在合約部署上向合約本身發送一定數量的 ERC20。我正在使用 Hardhat 和 OpenZeppelin 契約。合約程式碼:
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; import "hardhat/console.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract Test { address private owner; IERC20 private _token; constructor( IERC20 token, uint256 tokenAmount ) { owner = msg.sender; _token = token; uint ownerBalance = _token.balanceOf(owner); console.log("Amount available: ", ownerBalance); console.log("Amount to transfer: ", tokenAmount); bool success = _token.approve(owner, tokenAmount); console.log("Is approved: ", success); uint allowance = _token.allowance(owner, address(this)); console.log("Allowance: ", allowance); _token.transferFrom(owner, address(this), tokenAmount); } }
部署腳本:
const hre = require("hardhat"); const { utils } = require("ethers"); async function main() { const tokenAddr = "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6"; // Contract address of deployed erc20 const tokenAmount = "100"; const Test = await hre.ethers.getContractFactory("Test"); const test = await Test.deploy( tokenAddr, utils.parseUnits(tokenAmount, 18) ); await test.deployed(); console.log("Contract deployed to:", test.address); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
部署失敗:
ProviderError: Error: VM Exception while processing transaction: reverted with reason string 'ERC20: insufficient allowance'
但是從日誌中你可以看到批准是成功的:
console.log: Amount available: 10000000000000000000000 Amount to transfer: 100000000000000000000 Is approved: true Allowance: 0
有些東西不見了。我不知道是什麼
您不能將 transferFrom 函式用於建構子。原因是此功能使用批准 + 轉移將令牌(在這種情況下)從您的帳戶轉移到智能合約。批准()函式需要兩個欄位:
- 花費者:將花費您的代幣的人的地址;
- 金額:“花費者”可以花費多少代幣。
對於第一個參數,您必須輸入有關您的智能合約的地址,如果您沒有部署它,您將無法知道它的地址!出於這個原因(在這種情況下),您不能將 transferFrom() 呼叫到智能合約建構子中。
如果要解決此問題,可以實現一個函式,在其中呼叫 transferFrom() 函式。例如,你可以看到這個智能合約程式碼:
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; import "hardhat/console.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract Test { address private owner; IERC20 private token; constructor(address _tokenAddress) { // NOTE: You pass the address about token to send to smart contract token = IERC20(_tokenAddress); } // NOTE: Remember to call before 'approve()' function and then this function function transferMyTokenToThisSmartContract(uint _amount) public { token.transferFrom(msg.sender, address(this), _amount); } }