【劉文彬】區塊鏈3.0:擁抱EOS

原文連接:醒者呆的博客園,www.cnblogs.com/Evsward/p/e…html

EOS是當下最火的區塊鏈技術,被社會普遍看好爲下一代區塊鏈3.0。不一樣於以太坊的學習,EOS的主語言是C++,本文做爲EOS研究的首篇文章,重點介紹EOS的創新點,它的周邊生態,各類概念原理的解釋,以及它被看好的緣由。而針對EOS的源碼學習,原理實現以及並行的C++語言的快速學習與掌握,我會在接下來制定一系列學習計劃一一付諸實現。java

關鍵字:EOS,DAPP,石墨烯技術,構建本地節點,公鏈映射,選舉,EOS鏈配置,術語解釋node

EOS.IO

EOS.IO 是由block.one開發的一個基於區塊鏈結構設計的可以支持水平和垂直擴展的去中心化應用的平臺。它就像是一個完整的操做系統,能夠在上面構建各類應用。EOS.IO提供了帳戶、認證、數據庫,異步通訊以及跨平臺跨集羣的定時應用。它有望支持每秒百萬級交易,徹底零費率,並能夠快速且容易地部署去中心化應用。
複製代碼

以上是我對官方定義的理解,經過這個定義,咱們能夠抽離出最主要內容,就是EOS的核心競爭力是:python

  • tps:百萬級
  • gas = 0
  • Dapp更加容易高效地被部署

正如在以前的文章中的分析,下一代區塊鏈不是ico,確定是大規模的各行各業的Dapp的雄起,就像當年互聯網革了傳統行業的命同樣,因此,可以作好大型商業應用的基建工做的公鏈就是將來區塊鏈的寵兒。目前,呼喊着百萬級tps,手續費爲0,快速部署Dapp的EOS無疑切中了全部的要點。git

下面針對一些名詞進行一個解釋,以防止混淆:github

  • EOS,目前指的是基於ERC20在以太坊上發行的代幣,用於block.one公司開發軟件與社區運營。
  • EOS.IO,是由block.one開發的可構建公鏈的軟件源代碼。
  • EOS platform,採用了EOS.IO軟件構建的公鏈平臺。
  • Dapp,這裏指的是將來在EOS公鏈平臺上基於EOS.IO軟件開發部署的去中心化應用。

EOS

EOS目前是以太坊ERC20的一個Token,不少看好EOS將來的朋友已經大量買入了此Token(包括我身邊不少同事),已成爲以太坊Token體系中最強勢的一支。在即將到來的5月底,不出意外地話,EOS.IO公鏈將如期上線,屆時,EOS持有者將會經過某種映射方式將資產轉移到該公鏈上。web

EOS私募分配機制

例如,一個週期我計劃發放20枚EOS。在這期間,Bob貢獻了4個ETH,而Alice貢獻了1個ETH,此週期結束。那麼總ETH募集量爲5ETH,對應發放一個EOS的等價價值爲0.25ETH,所以,Bob會獲得16枚EOS,而Alice會得到4枚EOS。算法

因此,當你花費ETH或者BTC參與了EOS私募,必定是等到它一個週期結束纔會進行錨定覈算,你纔會收到EOS token。mongodb

有個有意思的是,在EOS官方問答上,它不容許美國公民、實體將EOS當作一種投機性產品購買,固然了,由於區塊鏈的匿名性,EOS這麼說並無什麼意義,估計只是作個態度,對了官方也不建議EOS買賣,但你也控制不了OTC和交易所(總之,EOS是戲精)。
複製代碼

另外,block.one爲了保證它們不會購買EOS,不會爲投資人支付股息,也不會發起任何形式的回購來操縱幣盤,它們打算進行一個獨立的第三方審計,將會發佈一個獨立審計報告提供進一步的保證。chrome

EOS上EOS platform的映射機制

上面講到了,EOS是存在於以太坊的代幣,那麼當EOS公鏈平臺推出之後,如何轉移這些代幣到EOS公幣呢?上面我也提到過是經過某種映射方法。那麼下面就來具體說說是如何映射的。

2018年6月1日,22:59:59,也就是EOS代幣最終的發放週期結束前的23小時倒計時,EOS將被鎖定交易,不可被交易。

思考,經過上面的總結做爲將來研究EOS的經驗,官方講的內容有多少是作戲,有多少隻是提議,畢竟咱們是在區塊鏈行業,它沒法作到對我的節點行爲的控制。因此就以上這句話來說,它如何控制以太坊EOS代幣的交易鎖定?我想它是控制不了的,由於交易所和OTC都不會聽它的,它最多隻是能經過智能合約控制代幣發放週期而已。所以,要時刻保持獨立思考能力,不要人云亦云,被人洗腦。
複製代碼

咱們繼續來分析,在上面這個時間點,EOS token的發放將會完成,任何人經過EOS.IO源碼啓動一個EOS platform的,將可以生成一個JSON文件會映射EOS的公鑰爲以太坊的EOS token帳戶的餘額。

block.one是EOS.IO公鏈源碼的開發者,它不會配置或啓動任何EOS平臺,block.one將不會控制什麼時候,如何或者EOS.IO軟件是否被使用或實現,或者如何,什麼時候以及是否啓動一個EOS platform。所以,您不該該指望,也不能保證您如今或未來會收到任何其餘加密token或數字資產(不想對EOS代幣負責)。

WebAssembly

WebAssembly(縮寫Wasm)是一種基於堆棧的虛擬機的二進制指令格式。Wasm設計做爲一個便攜式的針對高級語言的編譯器,例如C/C++/Rust,使各類客戶端或服務端應用程序都可以在web中部署。
複製代碼

目前Wasm支持Firefox,chrome,IE以及Safari瀏覽器。WebAssembly技術是在瀏覽器中不一樣於JS的另外一種存在,但因爲C++的高效,Wasm的效率可能會比JS更高,它就是在瀏覽器中運行C++程序的意思,目前WebAssembly比較好的編譯器是LLVM。

石墨烯技術

石墨烯技術是新一代的區塊鏈技術,基於DPOS共識算法。目前市場上流行的區塊鏈陣營有三種,一種是第一代以比特幣爲主的生態體系,他們是基於POW共識,純粹的去中心化,基於p2p的加密數字貨幣技術;第二種就是以以太坊構成的生態體系,主要以基於智能合約的ERC20的代幣體系,他們是基於POW共識,目前以太坊正準備切換到POW+POS的多共識體系;第三種就是進化到目前最強勁的石墨烯技術生態體系,它是基於DPOS(股份受權證實共識),支持高併發,高性能等大規模工業級商業場景的基礎設施,誕生了BTS(BitShare)開源商業系統,Steem去中心化社交網絡平臺以及EOS。將來會針對石墨烯技術以及DPOS共識作一個專門的博文調查。,目前咱們看到的石墨烯技術的幾個顯著特色是:

  • 轉帳速度特別快
  • 吞吐量tps極高
  • 安全性很高,沒有原生bug出現
  • 功能強大,應用性極高

防護機制

第一代比特幣體系是很是安全的,但瓶頸不少。相比之下,第二代的以太坊有不少獨特的創新點,例如智能合約,然而它歷史遭受攻擊的次數和影響範圍都很是嚴重。最後說基於石墨烯技術的EOS,它是經過我的持有幣的數量進行資源分配(包括存儲空間、網絡帶寬以及算力),沒有足夠幣是沒法發起攻擊的,而若是大量購幣攻擊,則至關於已經成爲房東卻要砸自家房子,是得不償失的行爲。因此EOS在防護攻擊方面是具有自然免疫力的。

分叉的處理

因爲出塊權被緊緊掌握在21個超級節點的手裏,若是其中某個節點做惡的話是很容易被追蹤到的,這個節點做惡的表現多是在它出塊的輪次人爲形成了一個分叉,此時,須要21個節點中的15個節點進行確認,經過確認的這一區塊被認爲是主鏈上不可逆的一個塊,任何不存在該塊的都會被看作無效。這樣就避免了分叉的可能。

DApp

EOS經過石墨烯基礎技術,再加上自身的優化,能夠達到百萬級tps,同時不一樣於以太坊停留在Paas(平臺即服務)的屬性,EOS開拓思路增長了SaaS(軟件即服務)的能力,加入了Dapp通用的帳號體系、權限身份認證、異步通訊、自描述數據庫、自描述接口以及上面提到的WebAssembly瀏覽器客戶端部署工具包,總之,擁有這一切優點的EOS將真正成爲了將來工業級應用的平臺。

不過咱們也要感謝以太坊提供的智能合約和Dapp的思想,在EOS獲得了普遍而有效地發揚,咱們能夠開發本身的Dapp部署在EOS上,經過持幣數量來得到對應比例的資源(包括存儲空間,網絡帶寬以及算力),這是革了AWS SAAS和PaaS的命(恐怕將來AWS只有提供雲計算基礎設施的市場了)。

超級節點的選舉機制

不一樣於以太坊POA,由於以太坊的POA是基於很是小場景的私鏈或者聯盟鏈的,這與大規模對外公開的公鏈EOS的場景是不一樣的。不過在我還未研究過EOS源碼的當下來看,DPOS的超級節點的選舉以及出塊的機制與POA一模一樣。

  • 用戶節點經過rpc接口進行投票,這裏面不一樣的地方是:EOS是經過持幣數量來決定手裏有幾票(這也是權益證實的精髓所在),而以太坊POA只是一個節點一票的形式。
  • 節點被選舉成功,以太坊POA是沒有肯定數量限制的,隨時按照全網投票與票數清零之後的每一輪投票結果去增刪超級節點。而EOS則不一樣,超級節點目前只有21個,在整個投票週期結束之後,排名前21位即勝任。
  • 超級節點的要求不一樣,以太坊POA的認證節點與普通節點並不是有任何差異。而EOS的超級節點則不一樣,這21個超級節點必須符合很是高的性能要求以及運維能力,社區規模等。
  • 機會均等概念在EOS超級節點中仍然是存在的,不過當一個超級節點出塊方面出現問題,在必定規則下會被丟棄,而後從新選出新的節點替代它做爲超級節點的身份。

EOS術語解釋

  • Account,帳戶
  • Authority,權力
  • Block,縮寫Blk,每一個區塊可包含0個或多個交易,以及一個對前置區塊的加密鏈接。不可逆。
  • DAC,分權自治集體,或者是分權自治公司。
  • DAO,分權自治組織
  • Deferred Transaction,縮寫defTx,延期交易。該交易是有智能合約所建立,會在將來的某個時間被執行。這個交易也可以建立另外一個在其以後的交易。所以,延期交易能夠建立無限循環的順序交易。用戶受權一個延期交易必須指定到執行的時刻擁有足夠的帶寬,存儲來執行預期交易。
  • DLTs,分佈式帳本技術。一種分佈式帳本(也被稱做共享式帳本),它是一個基於複製、共享以及同步數字化資產的跨站點、跨國家、跨機構的共識。
  • DPoS,受權權益證實。此外,也能夠表明民主即權益證實。DPoS是共識算法的一種,即區塊生產者可以針對交易或區塊的真實性,可驗證,不可逆等特性達成共識的一種方法。
  • Key pair,縮寫keys,一個密鑰對,包括公鑰和其對應的私鑰。
  • larimer,一種EOS的計量單位,等於0.0001 EOS。(性質如同以太坊中的Wei)
  • Master Password,用於解鎖,或解密一個錢包文件的密碼。
  • Action,一個對區塊鏈的改變更做。能夠是一個或這多個動做組成一個交易。
  • Non-Producing Node,非生產節點,也能夠被理解爲普通節點。這是一個完整的區塊鏈節點,但它智能觀察和驗證區塊,以及只能維護本身本地區塊鏈的拷貝。一個普通節點能夠在一個「備用池」中,經過投票流程稱爲生產節點(具有出塊權的超級節點)一個超級節點,也會被投票出局,成爲一個普通節點。可是值得注意的是,大多數普通節點並不在「備用池」中。
  • Oracle,在區塊鏈和智能合約的上下文中,它是一個代理,被智能合約使用用來找到和驗證明際發生的並提交這個信息到區塊鏈上。
  • peer-to-peer,p2p,對等計算或網絡是一個分佈式應用程序架構,在對等環境下,它被分去爲任務或者是工做量。對等節點是擁有等價權限,在應用程序中的參與機會均等。他們組成了點對點的網絡節點。
  • Permission,加權的,安全機制,經過評估它的簽名權力來肯定一個信息是否被正確受權。
  • Private Key,用來簽名交易的私鑰。
  • Public Key,縮寫pub key,公鑰,會在交易間被傳輸。
  • Scope,做用域,智能合約的做用域,智能合約智能寫入他們同一個做用域的本身的其餘合約,而只可以讀取其餘做用域的合約。
  • Smart Contract, 智能合約,一個計算機協議,旨在促進、驗證或執行談判。
  • Standby Pool,100個全節點的集合,渴望被選中爲21個超級節點之一,他們實際上已經擁有了超級節點的能力,不管什麼時候鏈須要替換一個超級節點時,就會從備用池中選擇。
  • Transaction,縮寫Tx,Txn。它有事務的含義,通常咱們稱做交易。它是一個完整的原子的區塊鏈的變化,一個或多個消息的組合,在EOS中一般是由一個智能合約來執行。
  • Wallet,錢包,會生成一個加密錢包文件或是經過客戶端來管理,例如cleos。它管理了私鑰以及用一個安全的方式去促進交易的簽名。錢包能夠被鎖定或解鎖。
  • Block Producer, 縮寫bp。21個超級節點之一,是目前正在出塊輪次的那個超級節點。

構建本地環境

EOS三個組件:

  • nodeos:服務端區塊鏈節點組件
  • cleos:命令行接口,與區塊鏈交互,管理錢包,管理帳戶,在區塊鏈上調用方法。(很重要,至關於以太坊web3)
  • keosd:管理EOSIO錢包的組件。

接下來,咱們將構建這些EOSIO組件,並將它們部署在一個主機,經過單個節點對網絡(testnet)進行測試與配置。

構建源碼

獲取源碼

recursive參數會將全部子組件自動克隆下來,最終咱們會在本地獲得所有完整的源碼。

git clone https://github.com/EOSIO/eos --recursive

自動構建源碼。

cd eos && ./eosio_build.sh

構建時間較長,最終構建成功的頁面以下:

[100%] Built target cleos
Scanning dependencies of target nodeos
[100%] Building CXX object programs/nodeos/CMakeFiles/nodeos.dir/main.cpp.o
[100%] Linking CXX executable chain_test
[100%] Linking CXX executable nodeos
[100%] Built target chain_test
[100%] Built target nodeos


     _______  _______  _______ _________ _______
    (  ____ \(  ___  )(  ____ \\__   __/(  ___  )
    | (    \/| (   ) || (    \/   ) (   | (   ) |
    | (__    | |   | || (_____    | |   | |   | |
    |  __)   | |   | |(_____  )   | |   | |   | |
    | (      | |   | |      ) |   | |   | |   | |
    | (____/\| (___) |/\____) |___) (___| (___) |
    (_______/(_______)\_______)\_______/(_______)

    EOS.IO has been successfully built. 0:32:57

    To verify your installation run the following commands:

    /home/liuwenbin/opt/mongodb/bin/mongod -f /home/liuwenbin/opt/mongodb/mongod.conf &
    cd /home/liuwenbin/eos/build; make test

    For more information:
    EOS.IO website: https://eos.io
    EOS.IO Telegram channel @ ***EOSProject
    EOS.IO resources: https://eos.io/resources/
    EOS.IO wiki: https://github.com/EOSIO/eos/wiki
複製代碼

手動構建源碼

安裝開發工具包

sudo apt-get update
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make \
                     libbz2-dev libssl-dev libgmp3-dev \
                     autotools-dev build-essential \
                     libbz2-dev libicu-dev python-dev \
                     autoconf libtool git mongodb
複製代碼
wget 下載llvm-key出錯,能夠按照提示加入參數--no-check-certificate搞定。
複製代碼

依賴

基於我本機是Ubuntu16.04,除了使用上面的自動編譯之外,也能夠手動安裝,不怕折磨的話。

目前EOS當前版本的依賴包括:

  • Clang 4.0.0
  • CMake 3.5.1
  • Boost 1.66
  • OpenSSL
  • LLVM 4.0
  • secp256k1-zkp (Cryptonomex branch)

依賴安裝請參照官方文檔

跑單元測試

cd build && make test

這一步是爲了驗證源碼功能完整度,耗時也較久。

安裝命令

sudo make install

命令會被安裝在/usr/local。執行完這個命令之後,咱們能夠在系統任何位置進行命令啓用。

啓動一個單獨節點

構建完成後,會在build/programs/目錄中出現nodeos文件夾,這是咱們要啓動節點的工具。經過如下命令啓動你本身的獨立節點區塊鏈

cd programs/nodeos && ./nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::account_history_api_plugin 
複製代碼

這條命令中,可執行文件./nodeos後面有不少參數,好看的是後面的plugin是啓動時對插件的配置,剩下的參數配置咱們會在接下來介紹到。啓動之後,日誌打印出來相關信息:

liuwenbin@liuwenbin-H81M-DS2:~/work/CLionProjects/github.com/eos/build/programs/nodeos$ ./nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::c
hain_api_plugin --plugin eosio::account_history_api_plugin 
3054170ms thread-0   wallet_plugin.cpp:41          plugin_initialize    ] initializing wallet plugin
3054170ms thread-0   http_plugin.cpp:141           plugin_initialize    ] host: 127.0.0.1 port: 8888 
3054170ms thread-0   http_plugin.cpp:144           plugin_initialize    ] configured http to listen on 127.0.0.1:8888
3054170ms thread-0   chain_plugin.cpp:99           plugin_initialize    ] initializing chain plugin
3054170ms thread-0   net_plugin.cpp:2628           plugin_initialize    ] Initialize net plugin
3054170ms thread-0   net_plugin.cpp:2644           plugin_initialize    ] Setting net_plugin logging level to info
3054170ms thread-0   net_plugin.cpp:2669           plugin_initialize    ] host: 0.0.0.0 port: 9876 
3054170ms thread-0   net_plugin.cpp:2745           plugin_initialize    ] my node_id is 86aa711400110362b7a94d9468fc45bdbfa8887a3bdaf9502dbea59694179b09
3054170ms thread-0   main.cpp:90                   main                 ] nodeos version 96ee0325
3054170ms thread-0   main.cpp:91                   main                 ] eosio root is /home/liuwenbin/.local/share
3054170ms thread-0   http_plugin.cpp:213           plugin_startup       ] start listening for http requests
3054170ms thread-0   wallet_api_plugin.cpp:70      plugin_startup       ] starting wallet_api_plugin
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/create
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/get_public_keys
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/import_key
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/list_keys
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/list_wallets
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/lock
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/lock_all
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/open
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/set_timeout
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/sign_transaction
3054170ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/wallet/unlock
3054170ms thread-0   chain_plugin.cpp:178          plugin_startup       ] 
 generating default genesis file /home/liuwenbin/.local/share/eosio/nodeos/config/genesis.json
3054209ms thread-0   chain_plugin.cpp:208          plugin_startup       ] starting chain in read/write mode
3054209ms thread-0   chain_plugin.cpp:213          plugin_startup       ] Blockchain started; head block is #0, genesis timestamp is 2018-03-01T12:00:00.000
3054209ms thread-0   chain_api_plugin.cpp:62       plugin_startup       ] starting chain_api_plugin
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/abi_bin_to_json
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/abi_json_to_bin
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_account
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_block
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_code
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_currency_balance
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_currency_stats
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_info
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_required_keys
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/get_table_rows
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/push_block
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/push_transaction
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/chain/push_transactions
3054209ms thread-0   account_history_api_plugin.cpp:45 plugin_startup       ] starting account_history_api_plugin
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/account_history/get_controlled_accounts
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/account_history/get_key_accounts
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/account_history/get_transaction
3054209ms thread-0   http_plugin.cpp:242           add_handler          ] add api url: /v1/account_history/get_transactions
3054209ms thread-0   net_plugin.cpp:2757           plugin_startup       ] starting listener, max clients is 25
3054209ms thread-0   producer_plugin.cpp:161       plugin_startup       ] producer plugin:  plugin_startup() begin
3054209ms thread-0   producer_plugin.cpp:166       plugin_startup       ] Launching block production for 1 producers.

*******************************
*                             *
*   ------ NEW CHAIN ------   *
*   -  Welcome to EOSIO!  -   *
*   -----------------------   *
*                             *
*******************************

Your genesis seems to have an old timestamp
Please consider using the --genesis-timestamp option to give your genesis a recent timestamp

3054209ms thread-0   producer_plugin.cpp:176       plugin_startup       ] producer plugin:  plugin_startup() end
eosio generated block bd1a5181... #1 @ 2018-04-13T02:50:54.500 with 0 trxs, lib: 0
eosio generated block a8c18ba3... #2 @ 2018-04-13T02:50:55.000 with 0 trxs, lib: 1
eosio generated block 1e4c703f... #3 @ 2018-04-13T02:50:55.500 with 0 trxs, lib: 2
eosio generated block d4c29cd4... #4 @ 2018-04-13T02:50:56.000 with 0 trxs, lib: 3
複製代碼

下面來逐一分析一下這個日誌內容,能夠看出EOS啓動私鏈節點是經過插件實現的,在啓動私鏈前,要對插件進行初始化配置,啓動各依賴組件處理器。下面來列舉一下主要插件內容:

  • wallet_plugin,錢包管理相關,啓動階段只出現過一次,說明它的功能主要依賴啓動後的操做,而在啓動期間須要作的配置不多。
  • wallet_api_plugin,依賴於wallet_plugin,出現一次,應該是提供外部調用與錢包交互的接口服務。
  • http_plugin,啓動階段大量出現的插件,說明在準備期,針對HTTP的配置和添加接口服務很是多。配置包括url,端口,監聽。接口服務包括錢包相關,鏈相關,帳戶相關的一系列api地址。
  • chain_plugin,鏈插件配置,出現了幾回,除了初始化啓動之外,還有針對鏈數據讀取模式的配置爲read/write模式,生成創世塊配置文件genesis.json,以及展現了創世區塊的各類屬性信息。
  • chain_api_plugin,一樣的,依賴於chain_plugin,提供外部調用鏈相關操做的接口服務。
  • net_plugin,網絡插件,出現了幾回,是對網絡節點的基本配置,包括網絡日誌的級別爲info,本地網絡監聽端口,生成節點id。最後啓動監聽器,並設置了以該網絡節點爲服務器的客戶端最多可以連入25個。
  • main,主插件,對eosio這整個軟件的一個主要插件,配置了eosio的版本以及展現了eosio工做的本地root地址。
  • account_history_api_plugin,顧名思義,帳戶歷史接口插件,估計是與帳戶歷史相關的供外部調用的接口服務。
  • producer_plugin,區塊生產者插件,插件啓動。

以上出現的全部插件亦可理解爲組件。

接着看日誌,提示我創世塊時間戳過期,能夠經過一個參數來修改,下面我嘗試修改一下,在以上啓動命令加入了參數,從新啓動:

--genesis-timestamp 2018-04-13T12:00:00.000

從新啓動之後,打印出來的日誌中,前面的都是相同的,咱們從producer_plugin貼出來是:

862009ms thread-0   producer_plugin.cpp:161       plugin_startup       ] producer plugin:  plugin_startup() begin
862009ms thread-0   producer_plugin.cpp:166       plugin_startup       ] Launching block production for 1 producers.
862009ms thread-0   producer_plugin.cpp:176       plugin_startup       ] producer plugin:  plugin_startup() end
862501ms thread-0   fork_database.cpp:77          _push_block          ] Number of missed blocks: 2783
eosio generated block 8e2a6ce1... #34 @ 2018-04-13T03:14:22.500 with 0 trxs, lib: 33
eosio generated block eb5e67b9... #35 @ 2018-04-13T03:14:23.000 with 0 trxs, lib: 34
eosio generated block 5aa06ff6... #36 @ 2018-04-13T03:14:23.500 with 0 trxs, lib: 35
複製代碼

能夠看到,那個關於創世塊時間戳的提示已經消失,producer_plugin插件啓動開始與完畢。接下來就是

fork_database程序,推送區塊,報出了消失區塊好2783。TODO:這一行還待將來分析解決。
複製代碼

接下來就是正常出塊了,因爲咱們本地啓動的節點必定是具有出塊權的(目前只有一個節點未涉及共識),這些塊是不包含任何交易信息的,出塊速度很快。

中止

斷開私鏈直接按下複製鍵(Ctrl+C)便可,日誌中也有體現:

eosio generated block de403b91... #37 @ 2018-04-13T03:14:24.000 with 0 trxs, lib: 36
eosio generated block f40f0e68... #38 @ 2018-04-13T03:14:24.500 with 0 trxs, lib: 37
eosio generated block c1b717d0... #39 @ 2018-04-13T03:14:25.000 with 0 trxs, lib: 38
865075ms thread-0   net_plugin.cpp:2771           plugin_shutdown      ] shutdown..
865075ms thread-0   net_plugin.cpp:2774           plugin_shutdown      ] close acceptor
865075ms thread-0   net_plugin.cpp:2777           plugin_shutdown      ] close 0 connections
865075ms thread-0   net_plugin.cpp:2785           plugin_shutdown      ] exit shutdown
複製代碼

能夠看到私鏈中止時,都是經過net_plugin插件來操做,操做的方法是與plugin_startup對應的plugin_shutdown,步驟爲:

  • 開始關閉的標識
  • 關閉接收器acceptor
  • 關閉鏈接
  • 完成私鏈中止工做,退出shutdown程序

以上內容在將來的源碼分析中均會涉及。

配置

EOS環境啓動之後,能夠在本地目錄:~/.local/share/eosio/nodeos/ 找到鏈相關文件:

liuwenbin@liuwenbin-H81M-DS2:~/.local/share/eosio/nodeos$ tree
.
├── config
│   ├── config.ini
│   └── genesis.json
└── data
    ├── blocks
    │   ├── blocks.index
    │   └── blocks.log
    └── shared_mem
        ├── shared_memory.bin
        └── shared_memory.meta

4 directories, 6 files
複製代碼

根目錄下包含config和data兩個目錄,data目錄中存儲了區塊運行時數據,日誌以及共享內存相關數據,咱們重點來看config文件夾中的內容:

genesis.json

{
  "initial_timestamp": "2018-03-01T12:00:00.000",
  "initial_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
  "initial_configuration": {
    "base_per_transaction_net_usage": 100,
    "base_per_transaction_cpu_usage": 500,
    "base_per_action_cpu_usage": 1000,
    "base_setcode_cpu_usage": 2097152,
    "per_signature_cpu_usage": 100000,
    "per_lock_net_usage": 32,
    "context_free_discount_cpu_usage_num": 20,
    "context_free_discount_cpu_usage_den": 100,
    "max_transaction_cpu_usage": 10485760,
    "max_transaction_net_usage": 104857,
    "max_block_cpu_usage": 104857600,
    "target_block_cpu_usage_pct": 1000,
    "max_block_net_usage": 1048576,
    "target_block_net_usage_pct": 1000,
    "max_transaction_lifetime": 3600,
    "max_transaction_exec_time": 0,
    "max_authority_depth": 6,
    "max_inline_depth": 4,
    "max_inline_action_size": 4096,
    "max_generated_transaction_count": 16
  },
  "initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
}
複製代碼

能夠看到初始化時間戳,初始化key,以及初始鏈id,鏈配置。其中鏈配置又包含了基礎每筆交易的網絡使用size、cpu使用size,每一個方法、每一個setcode、每一個簽名的cpu使用size,每一個鎖的網絡使用size,空閒期間的cpu使用度折扣上下文,交易的cpu、網絡使用度的最大值,區塊的最大網絡使用size,目標區塊的網絡使用size,交易最大存活生命週期長度、執行時間,權限深度的最大值,最大內聯深度,最大內聯操做size,交易的最大生成數量。

上面對genesis.json創世塊描述文件進行了平鋪直敘,咱們能夠看到,鏈時間,鏈key,鏈id都比較常見,而細緻入微到標識了每一個方法、每一個簽名等等的資源分配,這是很使人驚奇的。說明了

EOS對資源的控制是很是看中的。
複製代碼

config.ini

這是一個全局配置文件,就像java的property文件同樣。這裏面的配置會被細分到是由哪個插件來使用的,例如針對http_plugin配置的地址端口號等等,咱們也能夠經過手動修改這些配置來控制鏈的一些表現。config.ini這個全局配置文件就是開放給外部人員,做爲各類功能的靜態變量配置,功能開關等工具使用。下面針對配置項逐一分析: 屬於account_history_plugin插件的配置

  • filter_on_accounts:功能是實現僅追蹤配置值的帳戶產生的交易,默認註釋掉該配置項,意思是不設過濾器,追蹤全部交易。
  • get-transactions-time-limit:執行單個get_transactions調用的執行時間,單位是豪妙,默認值爲3(意思是3毫秒讀不到就丟棄)

屬於chain_plugin插件的配置

  • genesis-json,指定創世塊配置文件位置,默認值是「genesis.json」
  • genesis-timestamp,複寫初始化創世塊時間戳,咱們上面不是在啓動命令中經過加入--genesis-timestamp參數來配置該值了麼,在這裏配置之後重啓會是相同的效果。默認值是註釋掉,啓動時時間戳通常會過期。
  • block-log-dir:是區塊日誌的存儲位置,絕對路徑或者應用程序的相對路徑。
  • checkpoint:是一對區塊高度+區塊id,用來做爲檢查點。默認註釋掉,不設置檢查點。(檢查點的使用會在以後介紹,TODO)
  • max-reversible-block-time:容許可逆區塊在被確認爲無效以前存在的時間,默認爲-1,不容許出現可逆區塊。
  • max-pending-transaction-time:容許pending交易在無效以前的執行時間,默認爲-1,不容許出現pending的交易。
  • max-defered-transaction-time:容許延遲執行交易到區塊的推送時間,默認值20,
  • wasm-runtime:複寫默認的WebAssembly的runtime。默認是註釋掉(TODO:啥意思)

屬於faucet_testnet_plugin配置

  • faucet-create-interval-ms:建立帳戶的間隔,默認1秒鐘。
  • faucet-name:建立帳戶的建立器的名字。默認就是faucet。
  • faucet-private-key:公鑰,WIF(TODO:解釋WIF)私鑰,用於faucet建立帳戶簽名。默認值是在源碼下載時指定的,咱們能夠經過工具本身更改。

屬於http_plugin配置

  • http-server-address:本地IP端口,用於監聽進入的http鏈接。默認值爲127.0.0.1:8888
  • access-control-allow-origin:容許訪問控制,每一個請求會返回一個肯定的access-control-allow-origin。默認註釋掉,不設置特殊訪問限制。
  • access-control-allow-headers:同上,只是否是http請求的origin控制了,而是經過http頭來控制。默認也註釋掉,不設置特殊訪問限制。
  • access-control-allow-credentials:若是有特殊的訪問限制證書則返回true。默認值爲flase,不設限。

屬於mongo_db_plugin配置

  • mongodb-queue-size:nodeos和mongodb組件線程之間的隊列大小。默認值爲256。
  • mongodb-uri:MongoDB的uri鏈接字符串,若是不配置則該mongodb組件是未被激活的,而使用默認的‘EOS’數據庫。默認值不配置。

屬於net_plugin配置

  • p2p-listen-endpoint:實際的主機加端口,用來監聽進來的p2p鏈接。默認值爲0.0.0.0:9876
  • p2p-server-address:一個外部訪問的主機加端口,用於標識當前節點。默認使用上面的p2p-listen-endpoint配置。
  • p2p-peer-address:公共的對等節點的端點位置,提供外部鏈接。使用多重p2p-peer-address選項做爲構成網絡的須要。默認值是註釋掉,不設置p2p相關配置。(TODO,p2p網絡設置測試)
  • agent-name:在對等節點之間,用於標識一個節點而設置的名字。
  • allowed-connection:鏈接許可,可選值包括
    • any:容許全部鏈接,不設限制。
    • producers:僅容許區塊生產者鏈接,節點key是不須要的。
    • specified:配置節點key做爲特殊鏈接,能夠與producers節點key重複(要配置多個的時候能夠不適用producers,而用這個,不然沒意義)
    • none:誰都不容許連入。
  • peer-key:可選項,容許鏈接的節點公鑰。能夠被屢次使用。默認值是註釋掉,不使用該配置項。
  • peer-private-key:公鑰,WIF私鑰元組,可被指定屢次。默認註釋掉,不使用。
  • log-level-net-plugin:日誌級別包括all,debug,info,warn,error,off,這個不說了
  • max-clients:接收鏈接的客戶端的最大數量,設爲0的話表示沒有限制。默認25個。
  • connection-cleanup-period:在清理死鏈接以前,等待的秒數。默認值是30s。
  • network-version-match:準確匹配對等網絡版本。
  • sync-fetch-span:同步獲取量,同步時,從任何我的節點取回做爲一個chunk(大塊)的區塊數量,默認是100個。

屬於producer_plugin配置

  • enable-stale-production:陳舊生產能力。即便鏈是陳舊的,也可以出塊。默認值是false,不容許陳舊鏈(TODO:什麼是陳舊鏈)
  • required-participation:必須參與出塊。必須參與按序出塊的區塊生產者的百分比。默認值是33。至少33%的區塊生產者是要參與到按序出塊的。
  • producer-name:producer的ID,受節點控制。可能屢次指定。默認值是註釋掉,不使用。
  • private-key:私鑰,公鑰,WIF私鑰元組,能夠指定屢次。默認值已有,能夠修改。

屬於wallet_plugin配置

  • wallet-dir:錢包文件的路徑,絕對路徑或者應用程序的相對路徑。默認值是當前路徑「.」

  • unlock-timeout:解鎖錢包的超時時間,單位是秒。錢包在沒有活動一段時間之後會自動上鎖,這些活動可來自於任何錢包命令,例如list-wallet等。默認是註釋掉,沒有超時時間,不自動上鎖。

  • eosio-key:在錢包建立時,eosio祕鑰將被自動導入,默認是註釋掉,先不設置,由於我嗎是新建立錢包,未經過現有錢包導入。

  • plugin:激活插件,能夠被特殊指定屢次。默認是註釋掉,沒有特例,是插件都好使。

    配置中出現的全部time的單位通常都是毫秒。
    複製代碼

啓動命令參數

配置文件加啓動命令

上面咱們經過命令

./nodeos -e -p eosio --genesis-timestamp 2018-04-13T12:00:00.000 --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::account_history_api_plugin 
複製代碼

啓動了本地EOS環境。下面咱們針對這個啓動腳本的使用參數進行學習:

  • -e:enable-stale-production,參加上面config.ini的相關說明。設置之後至關於true。
  • -p:producer-name,給定了一個名字「eosio」用於出塊者名字。
  • --plugin:就是config.ini最後一個配置字段。

因此我在config.ini針對以上命令進行靜態配置。

enable-stale-production = true
producer-name = eosio
複製代碼

plugin的配置方式:

# Load the block producer plugin, so you can produce blocks
plugin = eosio::producer_plugin
# Wallet plugin
plugin = eosio::wallet_api_plugin
# As well as API and HTTP plugins
plugin = eosio::chain_api_plugin
plugin = eosio::http_plugin
# This will be used by the validation step below, to view account history
plugin = eosio::account_history_api_plugin
複製代碼

配置結束之後,因爲上面咱們也執行了命令安裝(sudo make install),下面咱們能夠直接在任何位置使用命令

nodeos

便可啓動與以前命令相同的EOS本地環境。

指定配置文件地址

咱們能夠在機器中維護多套config.ini 以及 genesis.json文件,而後啓動EOS環境時經過參數

--config-dir:指定地址用來加載配置文件,絕對路徑或應用程序相對路徑。

指定運行時數據地址

咱們也能夠經過啓動參數指定運行時數據的存儲位置。

--data-dir:指定地址用來存放運行時數據,日誌以及共享內存相關數據,絕對路徑或應用程序相對路徑。

其實config-dir和data-dir就是映射的上面的~/.local/share/eosio/nodeos/的內容,我在上面使用樹形結構列舉了出來,他們經過啓動參數都可指定新的位置。

總結

本文是EOS的入門手冊,介紹了EOS基本概念和術語解釋,包括髮展歷史,私募、代幣、公鏈映射方案,選舉機制、Dapp以及防護機制,最後對本地環境進行了構建,包括自動和手動的,以及啓動參數,結合分析了鏈的各類插件的配置參數,語義。接下來我分三個大步來加深自身的EOS的專業度:

  • 下一步我將經過兩篇文章重點快速學習C++語言基礎
  • 而後經過一到兩篇文章繼續EOS的分析研究,會根據官方文檔從智能合約、開發工具、交互工具、帳戶錢包權限模塊去進一步介紹EOS,同時會加入對RPC的使用研究
  • 再下一步我會根據EOS白皮書的結構,結合源碼去具體分析EOS各個插件的實現、區塊通訊、DPOS共識算法,帳戶管理,併發,Token,治理,腳本與虛擬機

參考資料

EOS官方文檔


相關文章和視頻推薦

圓方圓學院聚集大批區塊鏈名師,打造精品的區塊鏈技術課程。 在各大平臺都長期有優質免費公開課,歡迎報名收看。

公開課地址:ke.qq.com/course/3451…

相關文章
相關標籤/搜索