【劉文彬】探路以太坊
原文連結:醒者呆的部落格園,https://www.cnblogs.com/Evsward/p/ethereum.html
關鍵字:以太坊,加密貨幣,crowdsale,geth,console,web3.js
以太坊簡介
一句話簡介:以太坊是一個基於功能齊全的程式語言構建的眾多去中心化區塊鏈應用的平臺。
下面來解讀一下這句話:
- 平臺:首先以太坊是一個平臺,這個平臺上面有很多應用。
- 應用:這些應用是是去中心化的,基於區塊鏈技術。所以這些應用可以實現永不停歇,因為它是分散式的,去中心化的,基於P2P網路的,這些應用被管理在以太坊錢包上面。
- 錢包:以太坊錢包,本質上以太坊錢包也是其中一個應用,它是一個閘道器,可以管理所有基於以太坊平臺的應用,它可以讓你持有或者保護以太幣或其他建立在以太坊上的加密資產。以太坊錢包也可以實現直接對智慧合約的寫入、部署以及使用。
- 區塊鏈:以太坊區塊鏈是一條強大的,分享型的,全球性的基礎設施,用來證明財產的歸屬者以及財產的交易流向。通過這一條鏈,可以實現眾多應用,開發者可以建立交易所、儲存債務登記以及證實各種允諾等應用玩法。這些應用可以對各種實體期貨進行交易,避免中間人攻擊以及交易對方欺騙。
- 智慧合約:這些應用是使用一個功能齊全的程式語言構建的,這個語言指的是智慧合約,而智慧合約無疑是採用Go語言開發的。智慧合約是這些應用的“驅動”,通過智慧合約,應用可以完全按照程式設計所寫去執行,而不會涉及downtime,審查,欺騙以及第三方干擾。
關於以太坊錢包,官方有一句話是 It allows you to hold and secure other crypto-assets built on Ethereum, 以太坊允許你持有和保護基於以太坊的加密資產,那麼第一個問題這個加密資產是否可以自行建立?加密資產是否也可以是類似於以太幣的電子貨幣?是的是的,完全可以,下面我們將具體介紹。
加密貨幣
使用智慧合約的一種新語言Solidity,設計併發行你自己的加密貨幣。
上面講到了各種實體期貨以及以太幣等資產,那麼如果我想在以太坊平臺上建立一個應用,應用內部的交易使用我自己的加密貨幣呢?這個加密貨幣可以代表真實世界的商品。這種加密貨幣會呼叫以太坊統一的虛擬幣介面,從而讓基於自定義貨幣的合同均可以相容以太坊錢包,其他合同和交易也均採用這套介面。接著,對於你發行的加密貨幣是可以設定一個固定的總數或者一個基於某寫規則而浮動的數量。在以太坊中,你可以:
- 構建一種貨幣可以交易,同時可設定他們的發行量。
- 構建一箇中心化銀行來發行貨幣。
- 設計一種基於難題的加密貨幣。
請參考詳細開發文件
眾募
如果你已經有想法並準備在以太坊上面做點什麼,但是缺乏啟動資金。同樣可以使用以太坊,建立一個合同來募集貢獻者的資金直到達成某種目標。根據成果,這筆錢要麼被髮放到專案擁有者手裡要麼原路返還給貢獻者們。所有的過程不需要中間的仲裁人,票據交換所或者不確信的對他人的信任。對了,你甚至可以使用上面你自己建立的加密貨幣來追蹤對貢獻者的報酬。通過以太坊,你可以:
- 通過預售一件產品募集到一筆資金,哪怕這個產品還僅是在雛形階段。
- 通過出售一個區塊鏈組織裡的虛擬分享來募集資金。
- 拍賣有限數量的物品。
請參考詳細開發文件
眾籌crowdfund和眾募crowdsale的區別?
Crowdfunding簡單點就是你有個想法,然後通過團購和預售(一些實際商品或者一些承諾把你名字放在電影啥的等)的方式募集專案資金。
crowdsale 也叫ICO (Initial Coin Offering)是很多區塊鏈專案, 在專案正式推出之前銷售token,旨在為這個專案的開發籌集資金,也可以拿來測試大眾對產品的興趣。在許多情況下,在crowdsale買了token後會被拿到公開市場上購買和出售,會獲得獨立於應用程式自己的市場價值。這也是吸引早期adopter的一種方法,他們相信這個token的價值,有升值空間. 還有和Crowdfunding不一樣的是,crowdsale能夠讓那些投資者很快將持有的token在數字貨幣交易所中進行交易。而且token流動性極強的優勢也會導致專案估值產生更好的溢價。區塊鏈行業中最有名的Crowdsale是2014年9月的以太坊,大概籌集了價值1800萬美元的比特幣。
引用自[知乎](https://www.zhihu.com/question/55920197/answer/147711837)
民主
實際上就是一個投票系統。
建立一個自治組織,有規則來約束如何花錢以及幫助你或者其他投資者做決定。
現在,你有了自己的想法和有擔保的資金,也有了自己發行的貨幣,你可能是時候需要僱傭一個可信的財務官來幫助你管理賬戶,組織董事會以及一堆的文書工作。然而,你可以將這些工作全都交給以太坊智慧合約,它將收集你的支持者們的提議書,並通過一個完全透明可信的投票流程提交他們。
這相當於你擁有了一個機器人來幫助你打理一切,這其中最重要的一個好處就是:
可以免疫外部影響,只會依照你自己編寫的程式程式碼堅決執行。而且因為以太坊網路的去中心化特性,你將能夠獲得7*24小時百分百的全時線上服務保證。
通過以太坊,你可以實現:
- 一個虛擬的組織,組員們可以公平投票來處理問題。
- 一個透明的協會基於股東們的投票。
- 你自己的國家,擁有一個不變的憲法。
- 一個更好的協商民主。
以太坊環境搭建
這裡通過github下載原始碼進行搭建,ethereum地址:
git clone https://github.com/ethereum/go-ethereum && cd go-ethereum
構建geth命令:
make geth
構建所有工具:
make all
完整工具包包括:abigen bootnode ethereumwallet evm faucet geth mist puppeth rlpdump swarm wnode
安裝工具
sudo ln -s $PWD/build/bin/* /usr/local/bin/
將編譯好的所有工具軟連線到/usr/local/bin目錄下,該目錄本身就在PATH環境變數下,所以我們可以在任意位置使用這些剛剛編譯好的工具了。
每次對工具的編譯,尤其是geth,都是除錯的方式。
geth(go ethereum)
以太坊主要的命令列客戶端工具。它是以太坊網路(可以是私有、公有或者測試網路)的一個入口點。能夠作為一個完整的節點(預設)、存檔節點(儲存所有歷史狀態)或一個輕型節點(檢索存活資料)。它可以被其他程序通過在JSON RPC在HTTP、WebSocket或IPC傳輸協議頂端暴露端點,作為進入以太坊網路的閘道器。
abigen(ABI生成器)
ABI(Application Binary Interface) 應用二進位制介面,在以太坊生態系統中,它是一個標準的用來與合約互動的方式。互動包括區塊鏈外部以及合約之間的互動。資料依據它的型別會被編碼,正如本規範中的描述那樣。編碼不是自我描述,因此需要一個模式來解碼。
原始碼生成以太坊合約定義轉變為易於使用,編譯時型別安全的Go包。它可以操作在以太坊Solidity用於擴充功能。然而它也接受Solidity原始檔,讓開發更加流水線化。記住abigen就是與Solidity相關的工具命令。Solidity上面也提到過,是設計併發行自己的加密貨幣的一種語言。
bootnode(輕型引導節點)
精簡版的以太坊客戶端實現,只加入網路節點發現協議,但不能執行其他更高級別的應用協議了。它可以被用作一個輕型的引導節點,旨在私有網路中尋找節點。
evm(以太坊虛擬機器)
開發者工具版本的以太坊虛擬機器。通過一個可配置的環境和執行模式,能夠執行位元組碼片段。它的目的在於允許完全孤立不影響其他,細粒度地除錯操作碼。例如evm --code 60ff60ff --debug
gethrpctest(geth rcp test工具)
開發實用工具,支援我們的以太坊/RPC測試套件。這些套件能夠校驗基線符合以太坊JSON RPC規範。詳情請參閱測試套件的readme。
rlpdump(RLP轉儲)
轉儲請參考之前的一篇博文
開發實用工具,可將二進位制RLP(遞迴長度字首)轉儲(以太坊協議網路以及共識使用的資料編碼)至使用者友好的分層表示(例如,rlpdump --hex CE0183FFFFFFC4C304050583616263)
swarm
swarm 是一個分散式儲存平臺和內容分發服務。
swarm守護程式和工具。這是一個swarm網路的入口點。通過swarm --help可以檢視命令列選項以及子命令。 詳情參見swarm文件
puppeth
一個CLI(Command Line Interface for batch scripting,命令列介面)的嚮導程式,旨在建立一個新的以太坊網路。
geth詳解
geth是以太坊最主要的一個客戶端命令列互動介面,由以太坊原始碼編譯而成,直接執行在客戶端終端(我們一般都會將geth命令放到PATH裡,在任何位置都可以使用該命令)。
geth都可以幹嘛呢?下面看一下geth都有什麼子命令。
- account: 賬戶管理
- attach: 連線到JavaScript互動環境
- bug: 開啟一個新視窗報告geth庫的bug
- console: 開啟一個JavaScript互動環境
- copydb: 從一個目標蓮資料資料夾拷貝到本地的鏈上
- dump: 從儲存中刪除掉一個指定的區塊
- dumpconfig: 顯示配置值
- export: 匯出區塊鏈到檔案
- import: 從檔案匯入區塊鏈
- init: 通過一個嚮導初始化一個新的創世區塊(genesis block!)
- js: 執行一個指定的JavaScript檔案
- license: 展示許可資訊
- makecache: 生成ethash校驗快取(用於測試),ethash是以太坊的計劃性的PoW(工作量證明)演算法。
- makedag: 生成ethash挖礦DAG(用於測試),DAG是一個比特幣的擴容方案
- monitor: 監控使節點權值視覺化
- removedb: 除去區塊鏈和狀態資料庫
- version: 列印版本號
- wallet: 管理以太坊預售錢包
上面提到了一個重要的資訊:JavaScript互動環境。
JavaScript互動環境
console命令可以進入一個JavaScript互動環境,也可以使用geth --exec選項加入要執行的JavaScript命令在外部執行。
這裡主要介紹直接進入JavaScript控制檯的操作,在這個控制檯中,你可以使用web3.js的方法通過JSON RPC呼叫所有的以太坊API
- web3.js 是以太坊原始碼中提供的一套基於JS的SDK,開發者可以在終端JavaScript控制檯亦可以在自己的瀏覽器網頁中呼叫web3.js,可以執行以太坊所有的相關操作。
- geth自己的管理API,是在JavaScript控制檯中可以直接使用並且自帶命令提示的一套工具。
注意:管理API實際上只是web3.js的部分成員的外露而已,這些成員包括admin,debug,miner,personal,txpool五個命令,實際上對應的就是web3.(admin,debug,miner,personal,txpool)。
JSON-RPC
JSON-RPC是一個無狀態輕量級的RPC遠端程式呼叫協議。web3.js是通過該協議直接呼叫了原始碼的api方法。
由此可知,我們不必太關心已封裝好的JSON-RPC協議的內容(除非你想了解細節),在使用geth console的時候:
- 如果涉及到admin,debug,miner,personal,txpool五個命令,可以檢視geth管理API即可。
實際上我們只要看web3.js的文件就足夠了,因為geth管理API也包含在其中。
除了介紹的這些子命令外,geth命令以及各種子命令都有自己的選項屬性,下面簡介一些geth命令使用的選項組合。
建立在以太坊主網的完整節點
目前為止,使用者希望通過一種互動手段在以太坊主網上面進行一些操作,例如建立賬戶,轉賬,部署與呼叫智慧合約。對於這些個別的用法,使用者並不在意歷史資料,所以我們可以快速同步到當前網路中去,命令如下:
geth --fast --cache=512 console
這條命令可以做以下三件事:
- –fast: 使用fast模式開啟geth的客戶端互動控制檯。fast模式下,只會下載與轉賬相關的區塊,而不是完全下載所有的區塊鏈歷史。
- –cache: 將資料庫的記憶體限額調到512MB,可以顯著增加同步時間,尤其是機械硬碟使用者。這個引數是可選的,512的值你也可以設定高一些或者低一些,建議在512MB - 2GB之間。
- console: 啟動geth內建的可互動的JavaScript控制檯,進入該控制檯,你可以呼叫所有的web3.js的函式(它與geth自己的API)。
通過下面的命令你可以隨時加入一個已經在執行的geth例項:
geth attach
建立在以太坊測試網路的完整節點
面向開發者,如果你想試試建立一個以太坊合約,你肯定需要用假的貨幣交易來測試你的程式碼,直到你將你的合約真正釋出到以太坊主網上。換句話說,你不會加入以太坊主網,而是你想讓你的節點加入一個測試網路,這個測試網路的環境與以太坊主網是完全一樣的,只是使用的是假的以太幣。加入測試網路的命令如下:
geth --testnet --fast --cache=512 console
引數fast和cache,子命令console在上面主網路都介紹過,這些內容在測試網路與主網路完全一樣。下面仔細研究一下–testnet引數,它會重新配置你的geth例項。
- 正常主網路的會使用預設地址:/.ethereum,而測試網路使用的預設地址為:/.ethereum/testnet。
注意這裡面在使用geth attach的時候,linux需要改為geth attach
- 不會連線到以太坊主網路上,客戶端將連線到測試網路,測試網路使用的是不同的P2P嚮導節點,不同的網路ID以及不同的genesis狀態。
原始碼api
經過檢視,原始碼的api位置有很多,包括:
- node/api.go
- eth/api.go
- eth/downloader/api.go
- eth/filters/api.go
- consensus/clique/api.go
- contracts/chequebook/api.go
- internal/debug/api.go
- whisper/whisperv2/api.go
- whisper/whisperv5/api.go
- whisper/whisperv6/api.go
- swarm/api/api.go
- internal/ethapi/api.go
通過這些api檔案,我們可以找到所有的web3.js(開放了一部分給geth管理API)呼叫的相關方法。
測試環境
- github下載相應版本原始碼,make all或者僅make geth
- 本地找一個位置統一管理本地node(例如我的是work/node/lwbtestnode目錄)
- geth --datadir node0(自定義節點名) account new ,通過這條命令連續建立兩個node
- 本地採用剛剛建好的node進入測試網路,geth --datadir node0 --testnet --fast --cache=512 console,(注意,當你啟動第二個節點的console的時候,會提示你埠已佔用,此時要再加入一個引數–port 30001指定一個其他的埠號即可)
- 現在兩個節點都在本地以太坊測試環境啟動了console,讓我們先來檢視各自的一些資訊並相互新增peer,admin.nodeInfo.enode命令檢視當前節點的enode資訊,在另一個節點的console也查出該資訊,然後使用admin.addPeer(“剛查到的另一個節點的enode”),然後使用命令net來檢視peer數量,為1即正確。
- 然後再查一下當前節點的eth資訊,以太幣餘額命令為:web3.fromWei(eth.getBalance(eth.accounts[0])),wei是以太幣最小的單位,如果要轉換成以太幣,需要使用web3.fromWei函式來處理。
- 經過以上操作,兩個新節點已經互為peer,同時他們的餘額都是0,下面讓其中一個進行挖礦工作:miner.start(),可以看到隨著挖礦順利進行,另一個console中也在不斷地同步(共識)區塊訊息。
- 停止挖礦,檢視當前節點的餘額,已經不再是0了,我這邊是停在了80個以太幣(這個以太幣都是測試用的,不是真的以太幣),另一個節點由於沒有挖礦餘額還是0。
- 下面我們來做轉賬操作,轉賬操作是在餘額為80的賬戶裡做:
var sender = eth.accounts[0]
var receiver = "另一個節點的eth.accounts[0]"
var amount = web3.toWei(9,"ether") //轉9個以太幣,但是是通過Wei來做
personal.unlockAccount(eth.accounts[0]) //交易前先將轉賬傳送賬戶解鎖
eth.sendTransaction({from:sender, to:receiver, value:amount})// 正式轉賬事務提交
- 此時轉賬事務已提交但未生效,所以我們檢視兩個節點的餘額仍未發生變化。
- 下面繼續挖礦,(注意,挖礦是記賬的機制,但挖礦不完全為了記賬,而記賬必須通過挖礦,所以挖礦是記賬的必要非充分條件)
- 當前狀態下,啟動挖礦的第一個區塊就應該包含了我們上面的轉賬記錄,所以不必挖礦太久即可停止。我們再看一下當前餘額為86。
為什麼不是80-9=71呢,是因為後來挖礦又產生了新的以太幣報酬,所以餘額反而增加了。
- 那麼如何驗證我們的轉賬是否正確呢?我們去看另一個原來餘額是0的節點,檢查當前餘額為9,說明它作為轉賬接收者已成功接到了以太幣。
總結
本文針對以太坊進行了初步的研究,包括背景概念,環境搭建,原始碼跟蹤,事務處理等。而關於挖礦原始碼實現、共識演算法,p2p網路原始碼以及釋出自己的web3介面,都是中級篇需要研究的內容。
參考資料
- 文中出現的各種連結。
相關文章和視訊推薦
圓方圓學院彙集大批區塊鏈名師,打造精品的區塊鏈技術課程。 在各大平臺都長期有優質免費公開課,歡迎報名收看。