Solidity
ERC20Token - 眾籌,沒有足夠的代幣進行轉賬
我正在嘗試創建一個 ICO 契約(Crowdsale),這將促進 ERC20Token 的銷售。在遷移契約時,我遇到了一個錯誤
“SAMTokenSale”命中了 require 或 revert 語句,原因如下:
- 沒有足夠的代幣進行轉移
在 TokenSale 合約的建構子中,我正在初始化一些東西,並將一些預定義數量的代幣轉移到智能合約中。這就是失敗的地方。但是契約的管理員擁有初始總供應量。所以這不應該失敗,種類卡在這個問題上。這是程式碼
- ERC20Token.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ERC20Interface { function totalSupply() external view returns (uint); function balanceOf(address account) external view returns (uint); function transfer(address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint amount) external returns (bool); function transferFrom(address sender,address recipient,uint amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } contract SAMToken is ERC20Interface { string public name; string public symbol; uint8 public decimals; uint public totalSupply; address public admin; mapping(address => uint) public balances; mapping(address => mapping(address=>uint)) public allowances; constructor(){ name = 'SAM Token'; symbol = "SAM"; decimals = 18; totalSupply = 1000000 * 10 ** 18; // 1 million Tokens admin = msg.sender; balances[msg.sender] = totalSupply; } function transfer(address recipient, uint amount) external override returns(bool) { require(balances[msg.sender] >= amount, 'not enough tokens for transfer'); balances[msg.sender] -= amount; balances[recipient] += amount; emit Transfer(msg.sender, recipient, amount); return true; } function transferFrom(address sender, address recipient, uint amount) external override returns(bool) { uint allowed = allowances[sender][msg.sender]; require(allowed >= amount && balances[sender] >=amount, 'allowance too low'); allowances[sender][msg.sender] -= amount; balances[sender] -= amount; balances[recipient] += amount; emit Transfer(sender, recipient, amount); return true; } function approve(address spender, uint amount) external override returns(bool){ require(spender != msg.sender); allowances[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function burn(uint amount) external returns(bool){ require(balances[msg.sender] >= amount, 'not enought tokens to burn'); balances[msg.sender] -= amount; totalSupply -= amount; emit Transfer(msg.sender, address(0), amount); return true; } function allowance(address owner, address spender) external override view returns(uint){ return allowances[owner][spender]; } function balanceOf(address account) external override view returns(uint){ return balances[account]; } }
- 代幣銷售合約
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {SAMToken} from './SAMToken.sol'; contract SAMTokenSale { address admin; SAMToken public tokenContract; uint public tokenPrice; uint public tokenSold; uint tokensForSale = 100; // 100 tokens for sale event Sell(address _address, uint _amount); constructor(SAMToken _tokenContract, uint _tokenPrice){ admin = msg.sender; tokenContract = _tokenContract; tokenPrice = _tokenPrice; tokenContract.transfer(address(this), tokensForSale); //sending tokens to the smart contract initially } function buyTokens(uint _tokenAmount) external payable { require(msg.value == tokenPrice * _tokenAmount); require(_tokenAmount <= tokenContract.balanceOf(address(this)),'not enough tokens left for sale'); require(tokenContract.transfer(msg.sender, _tokenAmount)); //immediate release, which should not be the case tokenSold +=_tokenAmount; emit Sell(msg.sender, _tokenAmount); } function endSale() external onlyAdmin() { // transfer all the un-sold tokens back to admin tokenContract.transfer(admin, tokenContract.balanceOf(address(this))); //destroy the sale contract and transfer all ether balance to admin selfdestruct(payable(admin)); } modifier onlyAdmin(){ require(msg.sender == admin, 'only admin can do this'); _; } }
由於管理員擁有所需數量的令牌,因此有點迷失了為什麼在轉移功能上出現此錯誤。任何幫助都感激不盡。
謝謝,山姆
問題在於
transfer()
您建議的功能。特別是,當您部署 SAMTokenSale 並呼叫它時tokenContract.transfer(address(this), tokensForSale);
,它會呼叫 SAMToken 中的transfer()
函式,但msg.sender
它是 SAMTokenSale 的地址(不是 SAMToken 的地址!)。然後當它檢查這個條件時require(balances[msg.sender] >= amount, 'not enough tokens for transfer');
給出錯誤,因為它正在控制 SAMTokenSale 的餘額!要解決此錯誤,請嘗試從您的 metamask 錢包向 SAMTokenSale 發送一定數量的 SAMToken 或更改transfer()
函式中的邏輯(我不推薦您的方法)