在區塊鏈 2.0 的年代,Ethereum 以太坊其中一個特點就是允許所有人在平台上透過智能合約 Smart Contract 作出各種 DApp 應用,其中最為人所熟悉的一種應用就是 Token 代幣,要理解 Token 代幣的概念很簡單。舉個例子,你到遊樂場,要先用現金兌換遊樂場的遊戲幣,才能透過這些遊戲幣去使用各種設施。同理,在區塊鏈的世界中,若要使用各種區塊鏈的服務,就很有可能要透過獲得各種 Token,從而獲得服務的使用權,這使得 Token 作為一種價值傳遞的媒介。也就是說,Token 在某程度上被視作貨幣的角色,一種無型的貨幣 -虛擬貨幣。目前在市場上充斥著大量各種各樣的虛擬貨幣,這類型的虛擬貨幣並沒有自己獨立的區塊鏈,而是依賴以太坊區塊鏈並運行於其之上。當然,創建一種虛擬貨幣有很多種方法,比如說比特幣、Zcash等等都有其自己的鏈,而它們都在自己的鏈上運行著各自的虛擬貨幣,並不說一定要使用智能合約並部署在以太坊上才叫虛擬貨幣。
Token 是以太坊上智能合約的其中一種應用,創建 Token 要編寫智能合約時,為了具備作為貨幣的必要特性,就要有交易處理,帳戶餘額記錄、兌換等貨幣"必備"的功能,而且當智能合約部署後,眾所周知,根據區塊鏈的特性,是不能再修改的,如果當中有任何的漏洞或錯誤,令到整個應用出現不能逆轉的缺陷和災難性的損失,故此對智能合約的準備性和安全性也是相當高。另外,在缺少一種標準(協議)的情況下,每一份 Token 的智能合約的內容都可以完全不一樣,這種 Token 之間的數據不能容易地進行交換,彼此形成"隔離",然而如果有一種規範、模板或指引,告訴你應該要如何標準化、安全地編寫一份作為"貨幣"應有各種性質的智能合約,亦可以令各 Token 的智能合約之間可以互通,那將是多麼方便和美好的事,故此,以太坊社區提出一種名為 ERC20 的協議(標準)。
ERC20
ERC 的全稱為 Ethereum Request for Comments ,而 20 是代號。
當你想創造一種 Token 時,ERC20 是一種協議(標準) ,能夠指引你應該如何編寫一份具有"貨幣"特性的智能合約,另外,亦可視為快速構建 Token 的"模板",毋須再"重複造輪子",省去了不少時間。
它定義了一份智能合約中必須具備的
6 個 function(函數)包括 totalSupply、balanceOf、allowance、transfer、approve、transferFrom 。
2個 event(事件)包括Transfer、Approval。
首先看一下這 2 個 function,有些 function 後面聲明了 constant,意思就是這個 function 是"只讀"的,並不會修改到智能合約的狀態,所以聲明了 constant 就說明讀取這類 function 並不需要消耗 Gas。反之,其他 function 後面沒有聲明 constant,就代表會修改到智能合約的狀態,故此,需要消耗 Gas,請鏈上的各位礦工幫你驗證"出塊"。
另外 2 個 event 則只用為重要的事件作記錄之用,如 Token 之間轉賬記錄,而不會影響智能合約運作,可以視為一般系統中的日誌 Log。
ERC20 開始時需要設定
Token 的名稱(name);
Token的代號(symbol):Token 的簡稱,通常會設定成 3 至 4 個字母,比如 ETH。
Token 支持小數點後的位數(decimals):Token 代幣能夠支持最小的單位,通常會設定成18,意思就是 Token 最多可至小數點後 18 位。
為了更好清楚地了解ERC20 ,就以官方的例子作解釋
mapping(address => uint256) balances
balances 就是指賬戶上 Token 的餘額,以 mapping 的形式儲存,如「賬戶地址:Token 數量」這種形式對應,若外界需要查找某個賬戶地址上的餘額,就只需要利用這個 mapping 查一下就可得知 Token 數量,簡單直接。
mapping(address => mapping (address => uint256)) allowed
allowed 就是指允許讓其他賬戶地址使用的 Token 數量,同樣以 mapping 的形式儲存,不一樣的是,這個是再"包"一層,使用兩層的 mapping 的形式儲存,如「賬戶地址A =>賬戶地址B => Token 數量」這種形式對應,意思也就是 賬戶地址A允許賬戶地址B使用賬戶地址A中指定的Token數量,有點像現實生活中的支票。
balanceOf(address tokenOwner)
顧名思義,就是直接獲取指定賬戶上 Token 的餘額。
transfer(address to, uint tokens)
利用這個 function 的賬戶地址作為 msg.sender,減去指定數量的Token( tokens),在指定賬戶地址(to)加上相應數量的Token( tokens),最後再以 事件 Transfer(msg.sender, to, tokens) 以Log記錄發送賬戶地址、指定賬戶地址、Token 數量。
transferFrom(address from, address to, uint tokens)
首先將 from 的賬戶地址中減去指定數量的Token( tokens),然後就使用上面的 allowed 的msg.sender 允許 from 的賬戶地址減去指定數量的Token( tokens),然後在 to的賬戶地址中加上相應數量的Token( tokens),最後再以 事件 Transfer(from, to, tokens) 以Log記錄發送賬戶地址、指定賬戶地址、Token 數量。
approve(address spender, uint tokens)
利用這個 function 的賬戶地址作為 msg.sender,授權指定地址 spender可以從 msg.sender 的賬戶地址中提款。同樣地,最後以Approval(msg.sender, spender, tokens) 以Log 記錄 msg.sender 的賬戶地址、指定賬戶地址、Token 數量。
另外還有兩個 function 官方的例子並沒提及,就是:
totalSupply()
Token 的發行總數,當到達 Token 發行數量的上限,智能合約就將會拒絕再發行新的 Token
allowance(address tokenOwner, address spender)
檢查尚可以從 tokenOwner 錢包提取的 Token 數量
例子
再引用官方的例子的說明:
Token Balance
假設這個智能合約目前有兩個地址分別擁有的 Token 如下:
balances[0x1111111111111111111111111111111111111111] = 100
balances[0x2222222222222222222222222222222222222222] = 200
由於這個地址太長,所以我就簡化了一下,設為
A: 0x1111111111111111111111111111111111111111
B: 0x2222222222222222222222222222222222222222
如果調用function balanceOf 則會回傳以下資訊:
tokenContract.balanceOf(A) 將會返回 100
tokenContract.balanceOf(B) 將會返回 200
Transfer Token Balance
如果 A 想要轉移 10 tokens 給 B,調用
tokenContract.transfer(B, 10)
將得到下列結果
balances[A] = 90
balances[B] = 210
Approve And TransferFrom Token Balance
如果 A 允許 B 擁有轉移 30 tokens ,則調用
tokenContract.approve(B, 30)
將得到下列結果
tokenContract.allowed[A][B] = 30
如果此時 B 想要轉移 A 的 20 tokens 給自己,則調用
tokenContract.transferFrom(A, B, 20)
將得到下列結果
tokenContract.balances[A] = 70
tokenContract.balances[B] = 230
tokenContract.allowed[A][B] = 10
總結
寫本文的目的,主要除了介紹 ERC20 這個協議(標準)外,另一樣更重要的是想令大家知道目前在市場上充斥大量可疑的 ICO,透過使用現有一些協議,如ERC20,毋須太高深的技術,發行各種"空氣幣"、"山寨幣"也只是短短十數分鐘內的事情,不信?看下這個網站上共有36,000種以上的 Token https://etherscan.io/tokens 。更甚者,還有一些網站 TokenFactory 能夠讓一般人只填入 Token 的名稱、代號、發行數量等基本資料,就可以自動生成一份智能合約,連代碼都不用編寫,直接就可以發佈到以太坊上,所以要發行一種新的 Token 門檻並不高,由此就希望各位自行考量一下那些 ICO 的真實程度了,並不是說所有 ICO 都是這樣,當中也有一些不錯的ICO項目,但更大部份的ICO 項目,各位可要小心一點了。
當然,刀刃有兩面,ERC20 很大程度上簡化、標準化大家發行 Token 不用"重複造輪子",發行簡單方便,而且只需符合標準就可以被很多交易所、錢包軟件集成,亦可以在這些交易所、錢包軟件上直接進行交易買賣。
最後,再次說明寫本文的目的是希望大家能夠了解發行 Token 是可以非常簡單的,所以勸告大家在進行購買一些 ICO 項目的 Token 時,可是要相當小心,再三留意項目的本質。