區塊鏈之以太坊初體驗——以太坊平臺學習總結

各種媒體和技術專家也對該技術的應用前景、對應用領域顛覆性的意義進行了大量的報道和描述,區塊鏈技術會像互聯網技術同樣改變現有傳統領域。業界也不乏技術實踐的先行者,像R3區塊鏈聯盟、以太坊等,在平臺實現、技術應用方面已經有了不少的嘗試。javascript

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


近期,由於工做須要,對以太坊、區塊鏈等技術和概念進行了學習和研究。本文是做者對前一段時間學習、工做實踐和同事交流的一個知識整理。
前端


區塊鏈DISCOVERY

區塊鏈是一種基於點對點(peer-to-peer)網絡、分佈式的共享帳簿技術。java

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


通俗地理解,區塊鏈就是一個公共的、去中心化的數據庫,每一個節點(full node)上都保存有一份全量的如出一轍的數據,在一筆交易數據提交到區塊鏈網絡時,各個節點(node,也叫礦工)開始基於該交易信息進行數據塊的計算,只有第一個被計算出並按照某種共識機制得其餘的節點確認的數據塊勝出,從而被添加到鏈上,該過程也叫算力競爭。後續數據塊的計算都會基於前一個塊的數據的hash值進行。
node


而區塊鏈技術被寄予厚望的緣由正是,該技術的應用能夠改變目前中心化的交易機制(目前,我的和組織的交易行爲都是基於一個可信任的、中心化的機構來開展的,好比跨境結算,須要經過國際清算銀行等中間機構才能完成交易),幫助人們構建一種可信任的、去中心化的交易機制,交易當事方不須要通過第三方機構而直接完成交易。git


這樣下降交易的複雜度和中間費用,提升商業效率。同時,區塊鏈經過分佈式存儲、公私鑰加密等技術保證了交易數據的安全、可追溯、不可篡改性。github


以太坊DISCOVERY

以太坊是一個基於區塊鏈技術的開源平臺,經過它能夠很是容易地構建去中心化的應用(Dapp)。在底層,以太坊基於區塊鏈技術,實現了數據的去中心化、分佈式存儲和信息交換的信任問題。同時,以太坊實現了一個叫Ethereum Virtual Machine(EVM)的運行時環境,相似JVM,它的主要工做是執行智能合約(該概念下面會介紹)的字節碼。
web

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


在以太坊中也有挖礦的概念,每一筆交易只有經過網絡中的礦工進行挖礦才能提交到以太坊區塊鏈中。數據庫


  • 以太幣express

相似比特幣,以太坊平臺上的數字貨幣,英文縮寫ETH。npm


  • Gas

用戶提交給EVM執行交易或智能合約時,須要支付的費用,由以太幣按必定的比例轉而來,當用戶中的以太幣不足以支付Gas時,EVM會中止執行提交的交易或者智能合約。


  • 帳戶

在以太坊中有兩類帳戶:

  1. 外部帳戶(externally owned account,EOA)

    用戶能夠經過地址和私鑰對帳戶進行操做。EOA能夠在以太坊控制檯中經過命令來建立,或者經過IPC方式由外部調用api來建立;


  2. 智能合約(smart contract)

    它在以太坊中的做用有:

    1)維護數據存儲

    2)實現複雜的訪問控制策略

    3)爲其餘合約提供方法調用。

    可是智能合約沒法本身執行其中的邏輯或者方法,只能由EOA或者其餘合約發起調用。

    在以太坊平臺,智能合約的編程語言有Solidity(文件擴展名以.sol結尾)和Serpent(文件擴展名以.se結尾),但目前如今最流行並且最穩定的要算是Solidity。


  • 帳戶在區塊鏈中的存儲結構

以太坊帳戶的全部信息也存儲在在區塊鏈的結構中,以下圖: 


不一樣於比特幣,在以太坊的區塊鏈結構中,不只包含了對前一個區塊的引用信息、區塊號、交易和時間戳等信息,它還包含了全部以太坊帳戶的信息,存儲在以「STATE_ROOT」爲根節點的一棵Patricia樹(「a specialized kind of Merkle tree」)上。該根節點的值是對整棵數上保存的數據進行hash計算得出。


從圖中能夠看出,每一個帳戶節點中包含四類信息:

  1. NONCE--記錄從該帳戶發起的交易數;

  2. BALANCE--記錄該帳戶餘額;

  3. CODEHASH--智能合約帳戶的代碼hash值並指向合約代碼,若是爲EOA則該值爲空;

  4. STORAGE_ROOT--另外一棵Patricia樹的根節點,智能合約帳戶的內部數據存儲空間,當合約帳戶調用suicide()方法時,該值將被置爲null。


智能合約開發環境搭建DISCOVERY

爲了便於智能合約的開發和測試,須要在本地電腦搭建一個以太坊開發環境。本文接下來將介紹如何使用Truffle+Testrpc來搭建環境。


Testrpc的介紹和使用

Testrpc是基於node.js開發的以太坊客戶端,整個blockchain的數據駐留在內存空間,testrpc能夠模擬一個geth客戶端的行爲,包括全部的RPC api,發送給testrpc的交易會被立刻處理而不須要等待挖礦時間,讓基於以太坊的開發測試工做更加方便快速。


Testrpc安裝。在命令行終端輸入「npm install -g ethereumjs-testrpc」,等待完成便可。


啓動Testrpc。輸入命令」testrpc」便可,啓動完成後,出現下圖信息:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


從中咱們能夠看到,testrpc在啓動時默認建立了多個帳號,並開放了rpc端口8545。


Truffle介紹

Truffle是一個基於以太坊的智能合約開發工具,支持對合約代碼的單元測試,很是適合TDD。同時它內置了智能合約編譯器,只要使用腳本命令就能夠輕鬆完成合約的編譯、動態庫連接、部署、測試等工做,大大簡化了智能合約的開發生命週期。


Truffle的安裝很是簡單,只要在終端輸入命令「sudo npm install -g truffle」,等待安裝完成便可。


使用Truffle開發智能合約的過程以下(如何編寫合約及solidity語法不在本文範圍):

  • 使用testrpc開啓一個以太坊節點

  • 建立一個工程目錄,並初始化

mkdir myProject

cd myProject

truffle init


初始化完成後,Truffle在工程目錄下默認會生成一個叫MetaCoin的智能合約demo及其測試文件,目錄結構以下:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


各目錄含義:

app/:存放前端javascript文件和stylesheets文件,在開發Dapps時使用;

contracts/:智能合約文件的存放目錄;

migrations/:存放部署腳本;

test/:存放智能合約測試文件;

truffle.js:truffle的主配置文件,在該文件中能夠指定以太坊客戶端地址和rpc端口,network_id等;


1. 編寫智能合約文件並編譯,好比有個Multiply.sol,將其放入contracts目錄下,執行命令「truffle complie」,代碼片斷以下:


2. 部署合約,執行命令「truffle deploy」,或者發佈合約到以太坊客戶端,在migrations目錄下增長部署文件,好比3_deploy_multiply.js 文件,修改truffle.js中相關rpc的配置,執行命令「truffle migrate」,終端打印以下信息,表示成功發佈;

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


3. 編寫測試文件,保存爲multiply.js,並放入test目錄下(代碼以下),執行命令「truffle test」:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


執行結果以下:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


智能合約的外部調用DISCOVERY

在某些應用場景下,爲了接入以太坊區塊鏈,業務系統須要調用以太坊客戶端的api,將用戶的交易數據發送給以太坊平臺。以太坊客戶端已經爲外部系統提供了RPC和IPC兩種api調用方式。


以RPC方式爲例,使用curl命令請求的格式以下:

調用客戶端命令:

假設咱們要調用客戶端命令eth.getBalance(),查詢地址爲0x407的帳號的餘額,命令以下:

curl --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407", "latest"],"id":1}' localhost:8123


其中:jsonrpc字段指定JSON-RPC版本號,method字段指定須要調用的api方法名,params字段爲傳送的參數,id爲消息標識字段;


調用合約方法:

假設目前有部署的智能合約,地址爲0x6ff93,咱們要調用的合約方法簽名爲multiply(uint256),傳入的參數值爲6,那麼調用命令的格式以下:



其中,from爲扣除GAS的帳戶地址,to爲智能合約部署的地址,data爲調用方法的簽名和傳入參數,編碼方式爲:

「0x」+sha3(「multiply(uint256)」).substring(0,8)+to_32bit_Hex_str(6)


to_32bit_Hex_str()方法的實現會依據不一樣的變量類型而有不一樣,具體規則能夠參考Ethereum Contract ABI 文檔(HERE)。


從上面的示例能夠看出,從外部對智能合約的調用須要進行復雜的編碼。萬幸,目前以太坊官方提供了使用javascript語言實現的web3.js模塊,對RPC和IPC兩種調用方式d都進行了封裝,對外提供了簡潔的接口,使用很是方便。


下面本文將使用web3.js模塊在nodejs環境下實現對智能合約的調用,並向外提供RESTful的api。詳情以下:

系統環境:

Ubuntu14.04.4+Node V5.1.1;


須要引入的Node模塊

express、web三、net,可使用npm命令安裝依賴;


主要代碼片斷

引入模塊依賴

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


設置RPC和IPC鏈接對象

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


調用以太坊客戶端方法,查詢指定帳戶的餘額

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


新建以太坊帳戶,該方法必須使用IPC api的調用方式

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


新建合約對象,其中contractData爲合約代碼編譯後的16進制字符串


調用智能合約方法

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


開啓http server

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=


最後使用node啓動服務,看到「Example app listening at http://:::9090」服務就啓動成功了。這樣用戶即可經過RESTful的http請求來與以太坊客戶端進行交互,並調用智能合約。


結束語

本篇文章是我對最近一段時間學習的以太坊平臺和區塊鏈技術的總結,主要介紹了以太坊平臺的一些基本概念、智能合約本地開發環境的搭建和外部系統調用智能合約api開發介紹3個方面的內容,即當是一次以太坊區塊鏈知識的概括梳理,也當是一次知識的分享交流。


因爲學習的時間有限,文中不免有理解不到位得地方,還請你們指正!同時,很是感謝公司其餘同事對我在學習以太坊平臺中的幫助,讓我受益不淺!最後,文中也引用和參考了不少官網的資料和網友的文章,在此獻上真摯的謝意!


參考資料:

  1. https://blog.ethereum.org/2015/06/26/state-tree-pruning/

  2. https://blog.ethereum.org/2014/02/18/ethereum-scalability-and-decentralization-updates/

  3. http://gavwood.com/Paper.pdf

  4. http://truffle.readthedocs.org/en/latest/

  5. https://github.com/ethereumjs/testrpc

  6. http://www.ethdocs.org/en/latest/

  7. https://solidity.readthedocs.io/en/latest/

相關文章
相關標籤/搜索