代幣是怎樣演進(jìn)的
在前兩節(jié)的內(nèi)容我們從交易開始認(rèn)識(shí)比特幣及以太坊的基礎(chǔ)架構(gòu),隨后介紹了以太坊智慧合約運(yùn)作的概念。第三節(jié)我們將來(lái)回顧區(qū)塊鏈「代幣」演進(jìn)的歷史,并解析與之相關(guān)的技術(shù)。
既然要談代幣,就必須先厘清代幣的定義。用比喻來(lái)說(shuō)明的話,我們現(xiàn)實(shí)世界中有各國(guó)發(fā)行流通的法幣,如:臺(tái)幣(NTD)、美金(USD)。然而,有些公司為了便于平臺(tái)管理或流通便利性等因素,會(huì)發(fā)行在平臺(tái)流通的「代幣」,如:湯姆熊幣、Line Points。
在區(qū)塊鏈的世界里,其實(shí)也存在類似的概念,在公鏈上流通的加密貨幣如:比特幣(BTC)、以太幣(ETH),就像是各國(guó)的法幣,普遍被稱之為「協(xié)議代幣」(在比特幣/以太坊協(xié)議下流通的代幣)。
然而,在以太坊上我們可以透過(guò)智慧合約客制化來(lái)創(chuàng)造出類似于代幣性質(zhì)的產(chǎn)物,可稱之為「自定義代幣」,透過(guò)智慧合約來(lái)賦予代幣功能,類似我們傳統(tǒng)上理解的代幣。
「協(xié)議代幣」與「自定義代幣」我們都稱為加密貨幣(Cryptocurrency)。而「協(xié)議代幣」往往有自己的區(qū)塊鏈或類似的分散式帳本技術(shù),不需要任何其它區(qū)塊鏈就能獨(dú)立運(yùn)作。而「自定義代幣」則是利用現(xiàn)有的區(qū)塊鏈(絕大多數(shù)是Ethereum),透過(guò)智慧合約或其它方式來(lái)發(fā)行及運(yùn)行。
本文主要是以「自定義代幣」為主題來(lái)介紹。
2017 年的ICO 浪潮開啟了大發(fā)幣時(shí)代,人人都能在以太坊區(qū)塊鏈上發(fā)行自己的代幣。但其實(shí)在以太坊上線之前便已有區(qū)塊鏈代幣(以下簡(jiǎn)稱代幣)的存在。
區(qū)塊鏈代幣的起源:染色幣(Colored Coin)
代幣的歷史最早可以溯及到比特幣上的染色幣。但比特幣沒有智慧合約,要如何發(fā)幣呢?當(dāng)時(shí)鑄造Token的做法是:我們把1 Satoshi (10^-8個(gè)Bitcoin)重新定義為1 USD。
如此一來(lái),1 Bitcoin (100 Million Satoshi )的價(jià)值便變成了100M USD。然而這樣的做法必須具有公信力,因此鑄造的機(jī)構(gòu)應(yīng)該要抵押 100M的USD來(lái)?yè)?dān)保這100M的Satoshi具有等值100M USD的價(jià)值(但沒有機(jī)制保證鑄造機(jī)構(gòu)真的有抵押)。
于是我們會(huì)說(shuō)這些比特幣被染色了,因?yàn)樗淼牟辉偈潜忍貛诺膸っ鎯r(jià)值,而被賦予了新的價(jià)值意義,只是這個(gè)Token 透過(guò)比特幣的區(qū)塊鏈網(wǎng)絡(luò)來(lái)進(jìn)行流通。我發(fā)送給你100 Satoshi,其實(shí)是發(fā)送給你100 USD。
但這100M的染色幣要怎么跟其它比特幣來(lái)區(qū)隔呢?于是許多鑄造商會(huì)再利用一個(gè)比特幣外部的帳本來(lái)追蹤這100M Satoshi的交易紀(jì)錄,如此來(lái)確認(rèn)誰(shuí)手上具有這些被「染色」的Satoshi,他們有權(quán)利可以用這些Satoshi兌換為美金。
此外,在比特幣UTXO 的架構(gòu)下,若是同時(shí)交易了染色幣與比特幣,該怎么區(qū)分哪些是有染色的Satoshi 呢?一種可能的做法是:一筆交易的Output 中在前的錢堆是染色幣;在后的錢堆則是比特幣。
以上,便是最古早鑄造的Token的作法。這個(gè)作法主要的缺點(diǎn)是:當(dāng)你把這1顆Bitcoin染色,也代表你失去了這1 Bitcoin(因?yàn)檫@1 Bitcoin被當(dāng)作其它的用途了)。
并且當(dāng)你要交易300美金( 300 Satoshi )給別人時(shí),卻必須付出遠(yuǎn)大于300 Satoshi的手續(xù)費(fèi)給礦工,所以其實(shí)很少人這樣子鑄造。在2017年幣價(jià)突破天際后,便幾乎沒人再這樣鑄造了。
USDT 與Omni Layer
接下來(lái)的作法,便是由Tether 公司發(fā)行,赫赫有名的第一代USDT。第一代USDT 是建構(gòu)在比特幣上,采用Omni Layer 的技術(shù)。做法是在比特幣上發(fā)送交易,然而交易本身不是重點(diǎn),重點(diǎn)是在交易的OP_RETURN 中寫下訊息。
如:地址A給地址B 《10 USDT》,地址B便可以再給地址C 《4 USDT》、給地址D 《2 USDT》。如此不斷的接續(xù)下去,就像是把比特幣當(dāng)作便條紙來(lái)使用一般,僅是利用比特幣的OP_RETURN內(nèi)容會(huì)永久存在區(qū)塊鏈上的特性來(lái)記錄USDT的流通。
然而,若是一個(gè)地址A并沒有持有USDT,但他卻寫下了給B 《10 USDT》,這樣具有效力嗎?于是,Omni Layer便另外建立了一個(gè)Explorer來(lái)追蹤這些所有Bitcoin交易上OP_RETURN內(nèi)的Omni訊息,借以得知每個(gè)地址持有的USDT。若是有地址寫下了無(wú)效的交易訊息將被自動(dòng)濾掉。
以太坊ERC-20 Token
以上便是在比特幣上發(fā)行Token 常見的作法。接下來(lái)進(jìn)入到以太坊的世界,由于智能合約功能的出現(xiàn),一切都變得簡(jiǎn)單了些。ERC-20 Token 是至今最常見的代幣,那么ERC-20 是什么?ERC-20 Token 是怎么鑄造出來(lái)的呢?
ERC-20是以太坊上發(fā)行代幣的協(xié)定規(guī)范,約定發(fā)行的代幣必須包含的資訊(如發(fā)行幾顆)以及代幣具有的功能(如發(fā)送與接收)和限制(如一定時(shí)間內(nèi)能從錢包提領(lǐng)的上限)等,并且會(huì)在以太坊上建立資料庫(kù)來(lái)記錄每個(gè)地址持有的代幣數(shù)量。
舉例來(lái)說(shuō),我今天想要發(fā)行一個(gè)ERC-20 Token,取名叫Pelith Token。假設(shè)想發(fā)行一百萬(wàn)顆,要怎么做到呢?
用最直白的方式來(lái)說(shuō),就是要寫一個(gè)ERC-20 代幣發(fā)行規(guī)范的智能合約,并在發(fā)行量這段程式碼中寫一百萬(wàn)顆,接著把這個(gè)智能合約放入一筆交易的Input Data 中,交易的接收地址填為0x0,被礦工執(zhí)行部署完成后,一百萬(wàn)顆Pelith Token 便誕生了。
所以說(shuō),代幣的創(chuàng)造在技術(shù)上是非常容易的,無(wú)論想要發(fā)行一百萬(wàn)顆、一億顆、十億顆,其實(shí)都只是智能合約內(nèi)改個(gè)數(shù)字的差別,發(fā)行量的變動(dòng)成本趨近于零。
所以2017 年的ICO 浪潮,才會(huì)出現(xiàn)這么多各式各樣的shitcoin,只要寫個(gè)智能合約和白皮書,一個(gè)代幣就此誕生了,可以開始圈錢。??!不是,是募資。
真正的難處往往是代幣發(fā)行后實(shí)際的應(yīng)用場(chǎng)景搭建和社群行銷營(yíng)運(yùn),讓這個(gè)代幣被認(rèn)可、讓人愿意持有及應(yīng)用才是最大的困難點(diǎn)和成本之所在。
小結(jié)
1. 「協(xié)議代幣」往往有自己的區(qū)塊鏈或類似的分散式帳本技術(shù),而「自定義代幣」則是利用現(xiàn)有的區(qū)塊鏈來(lái)發(fā)行及運(yùn)行。
2. 早期比特幣上常見的代幣有改變單位定義的染色幣與把比特幣作為便條紙的Omni Layer 兩種做法。
3. 以太坊與智能合約的出現(xiàn)讓發(fā)行代幣在技術(shù)門檻上變得更簡(jiǎn)易且更有統(tǒng)一的規(guī)范,然而應(yīng)用場(chǎng)景搭建與社群行銷營(yíng)運(yùn)才是真正難處。
在上文中我們談到從比特幣開始到以太坊ERC-20 Token出現(xiàn)的自定義代幣發(fā)展史。下面將更著重在以太坊技術(shù)面的介紹,并在最后綜觀代幣演進(jìn)發(fā)展史給予一些觀點(diǎn)評(píng)論。
代幣轉(zhuǎn)移的成本
大家在第1節(jié)中應(yīng)該都了解到區(qū)塊鏈加密貨幣交易必須支付手續(xù)費(fèi)給礦工,那么既然「自定義代幣」要透過(guò)區(qū)塊鏈來(lái)進(jìn)行傳輸,當(dāng)我要發(fā)送代幣給別人,支付手續(xù)費(fèi)給礦工也是很合乎邏輯的。
接著要解釋的部分會(huì)用到許多第2節(jié)的概念,如果您還沒讀過(guò),建議您先去閱讀,否則可能會(huì)有些難消化。
假設(shè)我(A)要把10 個(gè)Pelith Token(自定義代幣)轉(zhuǎn)給B,其實(shí)是發(fā)生了什么事呢?我簡(jiǎn)單做了一張示意圖來(lái)說(shuō)明。(只做概念闡釋,省略了很多可以很復(fù)雜的中間細(xì)節(jié))
首先要知道,在區(qū)塊鏈上發(fā)行代幣不是真的發(fā)行硬幣或發(fā)行鈔票,而是建立了一個(gè)「類Excel帳本」來(lái)紀(jì)錄誰(shuí)擁有多少代幣。當(dāng)我們進(jìn)行代幣轉(zhuǎn)移時(shí),只是更改這個(gè)帳本上格子里的數(shù)字。
因此,當(dāng)我透過(guò)智慧合約創(chuàng)造了Pelith Token 時(shí),建立了一個(gè)類似Excel 的表格來(lái)追蹤所有Pelith Token 持有者的持有數(shù)量,并且這些資料會(huì)以某種形式儲(chǔ)存?zhèn)浞菰诿恳粋€(gè)節(jié)點(diǎn)中(對(duì),就是在全節(jié)點(diǎn)那200 G 左右里)。
當(dāng)我要把10個(gè)Pelith Token轉(zhuǎn)給B時(shí),我必須發(fā)送一筆接收對(duì)象為合約地址的交易,礦工看到便知道我是要對(duì)智慧合約進(jìn)行操作,不是一般發(fā)送Ether給別人的交易。并且在Input Data中呼叫我要操作動(dòng)作的function,輸入相對(duì)應(yīng)的參數(shù),大概會(huì)長(zhǎng)類似下面這樣:
我要call的funcTIon格式:
transferFrom(address _from, address _to, uint256 _value)
[從address _from傳送_value數(shù)量的代幣到_to錢包地址] 填入?yún)?shù):transferFrom(0xA??, 0xB??, 10)
→ transferFrom(0xA??, 0xB??, 10000000000000000000)
注:第三個(gè)參數(shù)uint256_value是10個(gè)Pelith Token,不過(guò)因?yàn)樵谝蕴簧蠜]有小數(shù)點(diǎn),所以進(jìn)入運(yùn)算時(shí)要以wei (10^-18,以太坊最小的單位)來(lái)進(jìn)行,因此在10后面要補(bǔ)上18個(gè)0。然后轉(zhuǎn)換成類似下面這個(gè)樣子:
0x23b872dd000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ac7230489e80000
再放入Input Data中。*(0xA??, 0xB??, 10)這一串funcTIon中的參數(shù)稱為“Payload”(裝載的貨物)
這些Bytecode 被礦工驗(yàn)證執(zhí)行后,更新了「帳本內(nèi)」對(duì)應(yīng)地址的Balance,隨后連同其它交易一起打包入新的區(qū)塊中。最先找到Nonce 獲得出塊權(quán)利的礦工廣播給其它節(jié)點(diǎn),直到各節(jié)點(diǎn)同步完成,并確認(rèn)區(qū)塊在最長(zhǎng)區(qū)塊鏈中,便正式驗(yàn)證我(A)把10 個(gè)Pelith Token 轉(zhuǎn)給B 了。
而以上這些動(dòng)作,其實(shí)跟交易一樣須繳些許的Ether 手續(xù)費(fèi)給礦工。當(dāng)你的ERC-20 Token 要轉(zhuǎn)移給一個(gè)新的地址持有時(shí)(假設(shè)B 過(guò)去未曾持有過(guò)Pelith Token),我們?cè)凇笌け局小贡惚仨氁嚅_一個(gè)格子來(lái)記錄并追蹤這個(gè)地址的Balance。
要「多開一個(gè)格子」的價(jià)格是20,000 gas ;「更改一個(gè)現(xiàn)有格子內(nèi)的數(shù)字」的價(jià)格是5,000 gas,在這筆交易中一共更改了A、B 兩格,故是10,000 gas。再加上交易的基本手續(xù)費(fèi)21,000 gas。我執(zhí)行了將10 Pelith Token 轉(zhuǎn)給B 的動(dòng)作,總共花費(fèi)了51,000 gas。
執(zhí)行操作的Gas 總花費(fèi)計(jì)算:
20,000 gas + 5,000*2 gas + 21,000 gas = 51,000 gas 手續(xù)費(fèi)(Eth)= Gas Used * Gas Price
51,000 gas * 10 Gwei(fast) = 510,000 Gwei = 0.00051 ETH = 0.1 USD
(以1 Ether = 200 USD 計(jì)算)
大約3 塊臺(tái)幣,便是更改一個(gè)格子大約需付出的手續(xù)費(fèi)。
至此,我們知道了轉(zhuǎn)移Token須付出的手續(xù)費(fèi)。如果轉(zhuǎn)移的量很大,其實(shí)金額也是有一定量的。并且,若你的Token Transfer交易無(wú)效,被彈掉時(shí)(例如你只有10個(gè)Token卻發(fā)了20個(gè)給別人),由于必須到礦工要改格子時(shí)才會(huì)觸發(fā)error,但礦工已執(zhí)行了這筆交易到觸發(fā)error為止的運(yùn)算。故雖然交易失敗,手續(xù)費(fèi)還是要付。
以太坊2.0 與無(wú)頭合約
最近隨著以太坊2.0 有越來(lái)越多的消息釋出,出現(xiàn)了一個(gè)新名詞:「無(wú)頭合約」。原本在智慧合約,當(dāng)我們從Input Data 呼叫合約中的funcTIon 后,合約中的程式碼便會(huì)執(zhí)行邏輯運(yùn)算去更新「帳本」內(nèi)的Balance。
然而,以太坊2.0的Phase 1并沒有EVM,無(wú)法執(zhí)行合約中的邏輯部分。因此發(fā)布的合約中的funcTIon 會(huì)長(zhǎng)下面這個(gè)樣子:
transferFrom(address _from, address _to, uint256 _value) {
}
原本1.0 的合約function 是長(zhǎng)這個(gè)樣子:
transferFrom(address _from, address _to, uint256 _value)returns (bool) {
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(_from, _to, _value);
return true;
}
這是什么意思呢?就是當(dāng)我們?cè)贗nput Data 中呼叫了合約中的function,但function 并不會(huì)真的去更新帳本上格子里的balance。因此這個(gè)合約只是個(gè)空殼,雖然看起來(lái)有東西,但實(shí)際上卻不會(huì)執(zhí)行動(dòng)作。
因此當(dāng)我們發(fā)送to 合約的交易,在Input Data 中輸入:
transferFrom(0xA??, 0xB??, 10)
合約并不會(huì)真的更新帳本(因?yàn)楦緵]有帳本的存在),也不會(huì)同步到其它的節(jié)點(diǎn)中。因此這些Input Data輸入的內(nèi)容只是被當(dāng)作一般的備注文字訊息被寫在to合約的交易中。于是呢,又回到了比特幣Omni Layer的做法,我必須要去爬這些所有的「便條紙」上的資訊,才會(huì)知道最新各地址的余額狀態(tài)。也因此,我們發(fā)送呼叫這個(gè)合約的交易,因?yàn)椴粫?huì)進(jìn)行邏輯執(zhí)行,所以實(shí)際上可以省下非常多的gas,只需要付出交易的基本手續(xù)費(fèi)21,000 gas加上些許的文字寫入gas費(fèi)用。
我們回顧到目前為止4節(jié) 的內(nèi)容,可以發(fā)現(xiàn)區(qū)塊鏈從1.0的比特幣,到2.0的以太坊,最大的升級(jí)便是智慧合約的功能,允許開發(fā)者可以客制化開發(fā)許多需要的功能。
結(jié)論
1. 在區(qū)塊鏈上發(fā)行代幣不是真的發(fā)行硬幣或發(fā)行鈔票,而是建立了一個(gè)「類Excel帳本」來(lái)紀(jì)錄誰(shuí)擁有多少代幣
2. 代幣轉(zhuǎn)移時(shí)必須發(fā)送一筆接收地址為合約地址的交易,并在Input Data中呼叫合約中的function 進(jìn)行操作,并付出相應(yīng)的運(yùn)算成本給礦工。
3. 以太坊2.0的Phase 1中由于沒有邏輯執(zhí)行的功能,因此智慧合約都成了「無(wú)頭合約」,讓以太坊2.0再次被當(dāng)作如Omni Layer般的「便條紙」來(lái)使用。
來(lái)源:動(dòng)區(qū)動(dòng)趨