依照預告,這次要來實作ERC20代幣,沒看過之前智能合約的介紹的話可以先去看一下之前的文章: (1) https://noise.cash/post/jgmg36rhn05wx (2) https://noise.cash/post/r6v7389f5k67z 在解釋實作程式碼之前先來介紹什麼是ERC20,所謂的ERC20就是一種智能合約的標準協議,只要合約內的函數介面滿足其規定所需要的條件,那麼就可以被視為一種有代幣功能的智能合約,而具體的條件就是需要含有totalSupply、balanceOf、allowance、transfer、approve、transferFrom這些函數,除此之外一般還需要設定合約的狀態變數name、symbol、decimals 在實作上我們可以直接複製其他人寫好的範例,不用自己重新寫出全部內容,這裡使用的範例來源是: https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v2.0.0/contracts/token/ERC20 首先複製這三個檔案到我們的Remix編譯器上,全都放到同一個資料夾之下就好: ERC20.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/ERC20.sol IERC20.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/IERC20.sol SafeMath.sol - https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/SafeMath.sol 之後創造我們的代幣合約TestToken.sol: https://github.com/vcckvv/SmartContract/blob/gh-pages/TestToken/TestToken.sol ----------------------------------- pragma solidity ^0.4.19; import "./ERC20.sol"; contract TestToken is ERC20 { string public name = "TestToken"; string public symbol = "TEST"; uint8 public decimals = 2; uint256 public INITIAL_SUPPLY = 88888; constructor() public { _mint(msg.sender, INITIAL_SUPPLY); } function mint() public { _mint(msg.sender, 800); } } ------------------------------------ (噪音顯示程式碼的空白縮排會有問題,所以上面的程式碼是用全形空白去顯示縮排,要複製程式碼請去網頁裡複製) -------------------------------- import "./ERC20.sol"; 這一行用來引用其他的sol程式碼檔案,因為會使用到ERC20這個contract ------------------------------------ contract TestToken is ERC20 { 這一行就像是C++中的繼承功能,也就是說TestToken會繼承ERC20的變數和函數,這樣做的話大部份的函數都不用重寫 ------------------------------------ string public name = "TestToken"; string public symbol = "TEST"; uint8 public decimals = 2; uint256 public INITIAL_SUPPLY = 88888; name就是代幣的完整名字,而symbol就代幣的縮寫代碼,INITIAL_SUPPLY代表一開始鑄造的代幣數量 decimals則是指代幣數量的小數點位置,比如這裡設定為2,擁有數量88888則實際上會顯示888.88;如果設定為3,擁有數量88888則實際上會顯示88.888 在變數後面加上public修飾詞,代表會自動生成相應的合約的讀取函數:name()、symbol()、decimals()、INITIAL_SUPPLY(),這樣的話我們就不用再另外寫變數的讀取函數 ------------------------------------ constructor() public { _mint(msg.sender, INITIAL_SUPPLY); } constructor()只在創造合約時呼叫,而msg.sender代表呼叫這個函數的帳戶位址,所以此時的msg.sender就是創造者的帳戶位址 _mint會進行代幣的鑄造,會把一開始的代幣全部移到msg.sender的帳戶之中 ------------------------------------ function mint() public { _mint(msg.sender, 800); } 這個函數是用來製作水龍頭功能的鑄造代幣函數,每次鑄造固定給予8.00個代幣 由於_mint()是無法公開呼叫的internal函數,TestToken繼承這種函數後無法讓它公開呼叫,所以我們要再弄一個public函數來進行鑄造,此時的msg.sender就是呼叫這個函數的使用者帳戶位址 ------------------------------------ 接著把這個合約發布到goerli測試鏈上:https://goerli.etherscan.io/address/0x63e1ddeb828ed1634b3165f56e2f31950b4d0b93#code 然後在MetaMask的goerli測試鏈的Assets頁面的下面中點選Import tokens連結,Token Contract Address輸入合約位址0x63e1ddeb828ed1634b3165f56e2f31950b4d0b93,接著Token Symbol和Token Decimal應該會自動填上,之後按Add Custom Token按鈕,再按下Import Tokens按鈕就可以看到一開始鑄造的888.88 TEST代幣了,如圖一 鑄造自己的ERC20代幣就講解到這裡,下一篇來講解怎麼利用這個代幣合約來寫一個水龍頭網站
2 comments
天書r
這個算是很簡單的合約,其實看不懂也可以照抄然後改改名字跟參數就好,大部份的ERC20代幣和NFT的智能合約差不多都是這樣