1. 程式人生 > >理解ERC-20 token合約

理解ERC-20 token合約

在這裡插入圖片描述
ERC-20最初作為一種嘗試,旨在為以太坊(Ethereum)上的token合約提供一個特徵與介面的共同標準,並且,它現在已經被證明是非常成功的了。ERC-20有很多好處,包括允許錢包顯示數以百計不同token的賬戶餘額;建立一個交易工具,只需提供token合約的地址就可以將更多token列入表中。建立ERC-20相容token的好處很多,以至於在今天,很少有其他token合約用其他方式建立。

Token合約是什麼?

現在仍存在著大量關於“token合約到底是什麼”的爭論。本質上來說,一個token合約就是一個包含了一個對賬戶地址及其餘額的對映的智慧合約(Smart Contract)。賬戶餘額表示一種由合約建立者定義的值:一個token合約也許使用餘額來表示物理物件,或是表示另一種貨幣價值,還可以表示持有人的名譽。餘額的單位通常被稱為token。
在這裡插入圖片描述

當token從一個賬戶被轉移到另一個賬戶的時候,token合約更新兩個賬戶的餘額。比如,一筆從 0x2299…3ab7 到 0x1f59…3492 的10個token的轉賬將導致餘額列表如下圖所示進行更新:
在這裡插入圖片描述

如果該token合約允許的話,變更一種token的總供給可能有兩種辦法。token的總供給可以通過鑄造新token來增加。舉個例子,鑄造出100個token到地址 0x4ba5…ae22 將導致餘額如下圖所示進行更新:
在這裡插入圖片描述

token的總供給也可以通過“銷燬”現有的token來減少。比如, 0x4919…413d 銷燬了50個token,這將導致餘額如下圖所示更新:
在這裡插入圖片描述

銷燬token的另一種方式是將token傳送到一個未建立私鑰的地址,通常來說就是0地址。這會使得這些token不可用,在這方面,它與銷燬token有同樣的效果,但並沒有減少token的總數。比如, 0x93f1…1b09 用此種方式銷燬了50個token將導致如下圖所示的餘額:
在這裡插入圖片描述

簡單的token合約在一個從地址到餘額的對映中儲存上述資訊。當更多複雜的情景出現時,比如發放股息,替代性結構或者增補性結構常常要變得更強悍。但是,不管那些操作上的細節的話,對外部可見的token餘額總是像上面的圖示那樣的。

一個ERC-20 token合約的定義

一個ERC-20 合約是通過合約的地址以及它可用的token總供給來定義的,但它通常還提供一些非必須的東西,也是為使用者提供更多細節。它們包括該token的名字、標誌、小數位。這些中的每一個都會包括在下面的細節中。

在深入到細節之前,理解這件事情是重要的:token合約沒有一箇中心化的登記處,因此無法保證特定名字和符號的唯一性。一旦你已經建立了一個token合約,你應該請求將它加入公共站點,比如:Etherscan,MyEtherWallet 以及 CoinMarketCap。當然,確保符合網站上的說明可以最大化你的申請被接受的機會。

Token合約的名字乃是該token合約應該被知道的完整名稱,比如“My Token”。名字的長度沒有限制,但完整名稱在一些錢包應用中更容易顯示不完全,所以,最好讓名字短一點。

Token合約的標誌乃是該token合約應該被知道的符號,比如“MYT”。廣義上,它是股票程式碼的對應物,而且,雖然沒有嚴格的長度限制,但它在長度上常常是3或4個字母。

小數位常常是混淆的來源,但經過合理的解釋這是非常容易理解的。小數位意味著一個token的可切分性,從0個小數位(即完全不可切分)到18位小數(幾乎是連續的),如果需要,可以有更多的小數位。從技術上來說,小數位的意義在於顯示token價值在螢幕上的時候小數點後面跟著的位數。小數位存在的理由是以太坊並不處理有小數的數字,只顯示整數的數字價值。考慮下面兩個例子:

第一個例子是LicenseToken,一個為給定軟體產品顯示軟體許可分配的token合約;持有一個LicenseToken,使用者就可以使用該軟體。而持有小於1個的LicenseToken則沒有任何意義,所以token建立者將小數位設為0。一些LicenseToken的持有人賬戶餘額如下。
在這裡插入圖片描述

可以看到,在這裡有100份許可,主要被一個賬戶所持有。當用戶購買一份許可的時候,一個token將從持有賬戶轉賬到購買者賬戶。而許可驗證者可以檢視一個特定的賬戶是否真的持有一個LicenseToken,然後做出相應的行動。

第二個例子是GoldToken,一個表示物理黃金所有權的token合約。合約建立者希望每單位表示1千克黃金的單位,但同樣希望允許使用者以克的級別(但不能更低)持有和交易黃金。因為以太坊並不支援小數因此1個token必須表示1克黃金,以及,為了向外界表示1000克作為單一的1Kg單位,小數位要設定成3(因為 10^3 克也就是1千克黃金才是token合約建立者希望顯示為1token的單位)。一些GoldToken的持有者可以用影象表示在下方。
在這裡插入圖片描述

在這裡你可以看到總共有50Kg的黃金被表示出來(每token 1克乘以50,000個token)。

但是,如果小數位被設成3,使用者的情形就會像下面這樣:
在這裡插入圖片描述

可以看到,將小數位設定成3在字面上就意味著在顯示GoldToken餘額的時候,應該有3位數跟在小數點後面。

小數位經常被稱為是一個人性化的元素,因為它允許token合約定義他們希望餘額怎樣顯示給使用者。GoldToken並不在內部處理小數位,也從不將小數位用在它自己的計算中因為一切都是用克來計算的,但它允許使用者使用黃金的共通單位(千克)而不是在合約中使用的單位(克)。

正如在上述GoldToken中顯示的,可切分性的觀念允許token合約顯示非常小的小數值,並且token也常常把小數位設成18,以給予token一個近乎連續的價值範圍。

總結一下,在決定要取幾個小數位時,下述規則是應該被遵循的:

token合約表示的是一個不可切分的物體嗎?(如果是)那麼將小數位設為0

token合約表示的是一個有特定小數位的物體嗎?那麼將小數位設定到那個數字

如果上述兩者都不是,請設定小數位為18

重要的是要知道小數位對合約建立的影響。被建立的Token數量應該等於token的全部數量,要求是10^小數位的倍數。正如在GoldToken例子中可以看到的,token建立者希望建立token來表示50千克的黃金,但因為3位小數,他們必須發行50,000 token(50×10^3)來做成這件事。

總供給是定義一個ERC-20 token合約的最後一個東西,並且,正如我們提到過的,它是唯一的強制引數。雖然在ERC-20說明書中並沒有明確提到,但總供給的概念是簡單的:總供給等於所有餘額的和。上面的例子中一直顯示著總供給,所以這裡就無需贅述了。

一個ERC-20 token合約的功能

ERC-20 token合約擁有一系列的功能,允許使用者發現使用者的餘額,也允許餘額經過驗證從一個賬戶轉賬到另一個賬戶。下面來描述一下這些功能。

balance()函式提供了被一個給定地址持有的token的數量。記住,任何人都可以查到任何地址的餘額,正如所有資料在區塊鏈上都是公開的。

從一個地址傳送token到另一個地址有兩種辦法。tranfer()函式可以從資訊傳送者那裡直接轉一些token到林一個地址。記住,人們不會查驗接收地址,因此確保接收者按預期的方式行動是傳送者的責任。

雖然用transfer()來發送toke給另一個使用者是很棒的,但當token要被用來為一個智慧合約中的函式進行支付的時候,它就起不了作用了。這是因為,當智慧合約執行的時候,它沒辦法獲得哪個地址轉賬到哪裡的細節,因此也就無法保證呼叫這個合約的使用者已經支付了啟動合約要求數量的資金。

想象一下,有一個合約Doer被部署在網路上。Doer擁有一個函式dosomething(),它要求10Dotoken來執行。Joe希望呼叫dosomething(),也有50Dotoken在他的賬戶上。Joe怎樣能夠支付給Doer以致後者可以成功執行dosomething()呢?

approve()和transferFrom()是兩個方程,它們使用一個兩步過程,可以解決上面的問題。第一步,一個token持有者給另一個地址(常常是一個智慧合約)批准從本地轉出一個最大特定數量的token,也就是所謂的配額(allowence)。Token持有者使用approve()來提供這些資訊。
在這裡插入圖片描述

在上述例子中,第二行顯示,地址為 0x1f59…3492 的Joe已經允許地址為 0xd8f0…c028 的Doer從Joe的賬戶中轉出25個token。

一旦一個許可被建立,智慧合約就可以從一個使用者的配額中佔用許可數量的token,作為該合約執行的一部分。繼續這個例子。Joe現在可以呼叫dosomething(),而dosomething()可以使用transferFrom()以從Joe的賬戶中獲得10個Dotoken, 然後開始它的工作。如果Joe的賬戶上沒有10個token,或者配額低於10個token,dosomething()就會當機。

allowance()函式提供了允許從一個給定地址提取到另一個給定地址的token的數量。記住,任何人都可以查到任何地址的餘額,正如所有資訊在區塊鏈上都是公開的。重要的是知道,配額是“軟性”的,因為所有單獨的或者累積的配額可以超過一個地址的餘額。在上面展示的表格中,持有者 0x2299…3ab7 許可了最高500個token的轉出,但他的餘額,如上所示,只有90個token。任何使用allowance()的合約,在計算可用的token數量的時候,都必須額外考慮使用者的餘額。

一個ERC-20 token合約中的事件

ERC-20定義了在合約採取了相關行動的時候,兩類事件是必須被觸發的。第一類事件是Transfer(),就是放出從一個地址轉移到另一個地址的token轉移的細節。第二類事件是Approval(),就是放出從一個地址許可轉移token到另一個地址的細節。這些可以被用來跟蹤地址餘額和配額的變更,而無需查詢區塊鏈。

鑄造token會發出了一個帶有o地址的Transfer()事件作為源。

當token被銷燬的時候,沒有事件會發出。因為這一點,ERC-20 token 合約常常通過transfer()傳送token到0地址來銷燬token,代替真正的銷燬。

超越ERC-20

ERC-20提供了一個良好的基礎來構建token合約,但也並不是沒有問題。ERC-223協議提供了額外的特性和安全措施,但與ERC-20並不相容。Token合約的建構在今天還要繼續遵循ERC-20,而開發者應該跟蹤 ERC-223協議,併為它做出貢獻。

原文連結:https://medium.com/@jgm.orinoco/understanding-erc-20-token-contracts-a809a7310aa5

作者:Jim McDonald

翻譯&校對:阿劍 & Elisa

稿源:以太坊愛好者(https://ethfans.org/ajian1984/articles/686)