ERC20 代幣 - 這個模板是一個正確的開始嗎?+ 未能向測試地址進行交易
我正在用我的電腦上打開的 Ganache 製作一個混音測試令牌。我將粘貼下面的程式碼,然後粘貼到問題和錯誤中。我通過線上組合一些範例並在它們出現時修復一些錯誤來到達這裡。
pragma solidity >=0.7.0 <0.9.0; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address tokenOwner) external view returns (uint256 balance); function allowance(address tokenOwner, address spender) external view returns (uint256 remaining); function transfer(address to, uint tokens) external returns (bool success); function approve(address spender, uint tokens) external returns (bool success); function transferFrom(address from, address to, uint256 tokens) external returns (bool success); event Transfer(address indexed from, address indexed to, uint256 tokens); event Approval(address indexed tokenOwner, address indexed spender, uint256 tokens); } // ---------------------------------------------------------------------------- // Safe Math Library // ---------------------------------------------------------------------------- contract SafeMath { function safeAdd(uint a, uint b) public pure returns (uint c) { c = a + b; require(c >= a); } function safeSub(uint a, uint b) public pure returns (uint c) { require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0); c = a / b; } } contract TTKN is IERC20, SafeMath { string public name; string public symbol; uint8 public decimals; // 18 decimals is the strongly suggested default, avoid changing it uint256 public _totalSupply; mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowed; /** * Constrctor function * * Initializes contract with initial supply tokens to the creator of the contract */ constructor() { name = "Test Token"; symbol = "TTKN"; decimals = 18; _totalSupply = 100000000000000000000000000; balances[msg.sender] = _totalSupply; emit Transfer(address(0), msg.sender, _totalSupply); } function totalSupply() public view returns (uint256) { return _totalSupply - balances[address(0)]; } function balanceOf(address tokenOwner) public view returns (uint256 balance) { return balances[tokenOwner]; } function allowance(address tokenOwner, address spender) public view returns (uint256 remaining) { return allowed[tokenOwner][spender]; } function approve(address spender, uint256 tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; emit Approval(msg.sender, spender, tokens); return true; } function transfer(address to, uint256 tokens) public returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(msg.sender, to, tokens); return true; } function transferFrom(address from, address to, uint256 tokens) public returns (bool success) { balances[from] = safeSub(balances[from], tokens); allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(from, to, tokens); return true; } }
所以部署工作,呼叫
totalSupply()
工作並顯示部署它的地址(所有者)擁有所有供應,很酷。balanceOf()
, 也很好。我可以通過transfer()
所有者轉移到我的 Ganache 測試網路上的其他帳戶。我從所有者轉移到 addr1,然後嘗試
transferFrom()
將 addr2 轉移到新的 addr2,我收到以下錯誤:顯然 addr1(0xD97…)有足夠的餘額將所需的金額發送到 addr2。在 Ganache,所有這些賬戶也有接近 100 ETH。點擊時出現以下錯誤
transferFrom()
:點擊發送時的控制台後果:
所以我在這裡有幾個問題,
- 一般來說,我的令牌啟動程式碼是否足夠?為了獲得創建令牌、發送令牌的準系統功能,我應該更改什麼?
- 上面的錯誤:為什麼 addr2 不能發送到 addr3
transferFrom()
?所有者地址也不能呼叫此函式- 這些
allowance
程式碼是什麼?它來自我正在使用的模板程式碼,但我不理解這個特定部分。真的有必要嗎?我只是希望能夠發送硬幣,我認為 Metamask 或類似的東西會要求使用者確認。- 像這樣的新代幣如何獲得“錢包”?例如,現在我無法在 Ganache 中查看任何這些地址的代幣餘額,我所能做的就是使用重新混合工具。我想我可以製作一個網站並
web3
用來與我的契約進行互動。如果/當這個合約最終部署到主網時,擁有 Exodus 錢包的人如何將這個代幣添加到他們的錢包中?- 錢包和地址:其他 ERC20 代幣有其代幣的唯一地址,但現在我可以看到 Ganache,它只是使用預設的乙太坊地址。對於這個合約(代幣),使用者肯定應該有一個特定於我的代幣的新地址嗎?
非常感謝乙太坊社區,真的很棒!
- 乍一看,你的程式碼應該足夠了。
您應該了解 OpenZeppelin 庫——它們為您提供實現和“即插即用”模板以實現常見功能,例如 ERC20 令牌。
當然,嘗試編寫自己的程式碼並沒有錯,我只是提一下,以防你不知道。
approve
打電話之前你打電話了transferFrom
嗎?在正常轉賬中,使用者可以向您的合約發送資金。但是,如果您希望您的合約從使用者那裡提取資金怎麼辦?
這就是津貼機制的目的。它有 2 個步驟:首先使用者呼叫 .approve(account, amount)。這允許“帳戶”花費“數量”的使用者代幣。然後,賬戶會呼叫 .transferFrom(originalUser, toAccount, amount),它將金額從 originalUser 轉移到 toAccount。因此,您的交易可能失敗,因為您在 transferFrom 之前沒有呼叫批准。如果您只想進行正常傳輸,請使用 `transfer1.
- 不知道你對錢包問題的意思。您可以通過查詢已部署合約中的 balanceOf 方法來查看您的餘額,就像您已經做過的那樣。要將代幣添加到錢包,錢包需要代幣的合約地址。然後錢包會打電話
balanceOf
來查看使用者的餘額。- 不確定您所說的“預設乙太坊地址”是什麼意思,真的沒有這樣的東西。每個部署的合約(包括你的代幣)一旦部署就會有自己唯一的地址。