本實驗室由我們與合作夥伴 Block.one 共同開發。如果您在帳戶個人資料中選擇接收產品最新消息、公告和優惠資訊,您的個人資訊即有可能提供給本實驗室的贊助者 Block.one。
GSP991
總覽
在本實驗室中,您會將單節點 EOSIO 區塊鏈擴充為多節點架構,並安裝各種 EOSIO 軟體元件來設定多節點 EOSIO 區塊鏈。最後,您會在新的 EOSIO 區塊鏈上執行一些節點營運工作。
目標
在本實驗室中,您將瞭解如何執行下列工作:
- 載入現有的 Compute Engine 虛擬機器。
- 安裝及建構 EOSIO 系統合約。
- 部署具有四 (4) 個 EOSIO 節點的多節點區塊鏈。
- 在 EOSIO 多節點區塊鏈上建立使用者帳戶。
- 呼叫動作,在使用者帳戶之間轉移代幣。
事前準備
開始本實驗室前,建議先完成「Block.one:EOSIO 區塊鏈入門」實驗室。
此外,建議您也熟悉下列概念:
設定和需求
瞭解以下事項後,再點選「Start Lab」按鈕
請詳閱以下操作說明。實驗室活動會計時,且中途無法暫停。點選「Start Lab」後就會開始計時,顯示可使用 Google Cloud 資源的時間。
您將在真正的雲端環境完成實作實驗室活動,而不是模擬或示範環境。為此,我們會提供新的暫時憑證,供您在實驗室活動期間登入及存取 Google Cloud。
為了順利完成這個實驗室,請先確認:
- 可以使用標準的網際網路瀏覽器 (Chrome 瀏覽器為佳)。
注意事項:請使用無痕模式 (建議選項) 或私密瀏覽視窗執行此實驗室,這可以防止個人帳戶和學員帳戶之間的衝突,避免個人帳戶產生額外費用。
- 是時候完成實驗室活動了!別忘了,活動一旦開始將無法暫停。
注意事項:務必使用實驗室專用的學員帳戶。如果使用其他 Google Cloud 帳戶,可能會產生額外費用。
如何開始實驗室及登入 Google Cloud 控制台
-
按一下「Start Lab」按鈕。如果實驗室會產生費用,請在開啟的對話方塊中選取付款方式。右側的「Lab setup and access」面板會顯示下列項目:
- 「Open Google Cloud console」按鈕
- 此實驗室所需的臨時憑證 (使用者名稱和密碼)
- 完成此實驗室所需的其他資訊 (如有)
請注意,實驗室計時器位於頁面頂端附近,會顯示剩餘時間。
-
按一下「Open Google Cloud console」。如果使用 Chrome 瀏覽器,也可以按一下滑鼠右鍵,選取「在無痕視窗中開啟連結」。
接著,實驗室會啟動相關資源,並開啟另一個分頁,顯示「登入」頁面。
提示:您可以在不同的視窗並排開啟分頁。
注意:頁面顯示「選擇帳戶」對話方塊時,請點選「使用其他帳戶」。
-
如有必要,請將下方的 Username 貼到「登入」對話方塊。
{{{user_0.username | "Username"}}}
您也可以在「Lab setup and access」面板找到「Username」。
-
點選「下一步」。
-
複製下方的 Password,並貼到「歡迎使用」對話方塊。
{{{user_0.password | "Password"}}}
您也可以在「Lab setup and access」面板找到「Password」。
-
點選「下一步」。
重要事項:請務必使用實驗室提供的憑證,而非自己的 Google Cloud 帳戶憑證。
注意:如果使用自己的 Google Cloud 帳戶來進行這個實驗室,可能會產生額外費用。
-
繼續點按後續頁面:
- 接受條款及細則。
- 由於這是臨時帳戶,請勿新增救援選項或雙重驗證機制。
- 請勿申請免費試用。
Google Cloud 控制台稍後會在這個分頁開啟。
注意:如要使用 Google Cloud 產品和服務,請按一下「導覽選單」,或在「搜尋」欄位輸入服務或產品名稱。
背景
本節概述本實驗室涵蓋的概念。
EOSIO 區塊鏈
EOSIO 區塊鏈是高效且具確定性的分散式狀態機器,能實現去中心化運作。區塊鏈會透過一系列交互連結的區塊追蹤交易。每個區塊都透過密碼編譯技術,與同一條鏈上的先前區塊緊密連結。因此,只要更動特定區塊所記錄的交易資料,就勢必會導致後續區塊的加密驗證失敗。這項簡單的原理,正是確保區塊鏈交易不可竄改且安全無虞的關鍵。區塊的產生與驗證,是由名為「區塊生產者」的特殊節點執行。
EOSIO 共識
在任何分散式節點群組中,區塊驗證都是一項難題。去中心化系統必須具備共識模型,才能以具備容錯能力的方式驗證此類區塊。共識機制能使分散式節點與使用者對當前狀態達成一致。區塊鏈最常用的共識模型有兩種:「工作量證明」(PoW) 和「權益證明」(PoS)。採用「權益證明」模型時,擁有最多權益或資產占比最高的節點,擁有相應的決策權。其中一種有趣的變體是「委託權益證明」(DPoS),會由眾多參與者或利害關係人選出少數代表,再由這些代表負責決策。EOSIO 會使用委託權益證明 (DPoS) 選出活躍生產者,這些生產者隨後會獲得授權,可產生、驗證及簽署區塊,最終將區塊新增至區塊鏈。
EOSIO 帳戶、金鑰和權限
帳戶可識別 EOSIO 區塊鏈中的參與者。參與者可以是個人或群組,視帳戶內指派的權限而定。帳戶也代表智慧合約的主體,可將動作推送至區塊鏈中的其他帳戶,並從其他帳戶接收動作。EOSIO 中的金鑰是以 Base58 表示的二進位字串,用於簽署及驗證交易、區塊和其他訊息。金鑰會建立在與帳戶相關聯的數位錢包中。由於帳戶擁有權完全由帳戶名稱決定,因此更新與帳戶相關聯的金鑰,並不會影響安全性。這種新穎的權限架構由帳戶、權限和授權表組成,可決定帳戶能執行哪些操作,以及構成交易的動作如何獲得授權。為此,每個帳戶會獲派階層式權限結構,而每項權限會獲派一組公開金鑰和私密金鑰,用於簽署和驗證。
EOSIO 智慧合約
智慧合約是低階軟體程式庫,內含構成交易的動作實作項目,也會定義如何儲存動作所存取及處理的資料。EOSIO 的智慧合約採用 C++ 等高階語言編寫,並編譯為 WebAssembly (WASM) 二進位檔。隨後便可將智慧合約部署至區塊鏈,並在帳戶的沙箱中執行。
工作 1:建立虛擬機器
-
依序點選「導覽選單」圖示
>「Compute Engine」>「VM 執行個體」。
-
點選「建立執行個體」,建立新的執行個體。
-
前往「機器設定」部分。
選取下列值:
-
名稱:
instance-1
-
區域:
-
可用區:
-
機器家族:
一般用途 (預設)
-
系列:
E2
-
機型:
e2-standard-2 (2 個 vCPU,8 GB 記憶體)
-
點選「OS 和儲存空間」。
點選「變更」,開始設定開機磁碟,並選取以下值:
-
作業系統:
Ubuntu
-
版本:
Ubuntu 22.04 LTS
-
架構:
x86/64
按一下「選取」。
-
如要建立並啟動 VM,請點選「建立」。
注意:VM 可能需要約兩分鐘才會啟動並全面運作。
點選「Check my progress」,確認目標已達成。
建立虛擬機器
工作 2:安裝 EOSIO 平台
- 依序點選「導覽選單」圖示
>「Compute Engine」>「VM 執行個體」。
您會看到自己建立的 VM 執行個體。
-
如要在 VM 執行個體 instance-1 開啟命令提示字元,請在「VM 執行個體」清單中找到該執行個體,點選該列的「SSH」。系統隨即會開啟殼層終端機視窗。
-
首先,務必更新 VM 環境的軟體套件清單:
sudo apt update
- 安裝
libssl1.1 依附元件。EOSIO 2.1.0 需要此元件,但 Ubuntu 22.04 以上版本不會預設包含此元件:
wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb
sudo apt install ./libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb
- 取得 EOSIO 軟體二進位檔。這包括節點 P2P 軟體 nodeos、CLI 用戶端 cleos、錢包管理工具 keosd,以及其他工具:
curl -LO https://github.com/eosio/eos/releases/download/v2.1.0/eosio_2.1.0-1-ubuntu-20.04_amd64.deb
- 安裝 EOSIO 軟體二進位檔。如需安裝任何必要的軟體依附元件,請按下 Enter 鍵:
sudo apt install ./eosio_2.1.0-1-ubuntu-20.04_amd64.deb
- 確認已安裝 nodeos:
nodeos --version
系統會回覆 nodeos 的版本資訊:
v2.1.0
- 確認已安裝 cleos:
cleos version client
系統會回覆 cleos 的版本資訊:
v2.1.0
- 確認已安裝 keosd:
keosd -v
系統會回覆 keosd 的版本資訊:
v2.1.0
點選「Check my progress」,確認目標已達成。
安裝 EOSIO 平台
工作 3:建立預設錢包
錢包會儲存帳戶和生產者所需的加密編譯金鑰,前者用於簽署交易,後者則用於簽署區塊。此外,錢包還提供簽署作業所需的安全隔離區,確保私密金鑰絕不外流。如要在區塊鏈上變更狀態,您需要透過錢包儲存加密編譯金鑰,並執行數位簽署。
- 首先,為 EOSIO 錢包管理工具 keosd 所管理的任何錢包,設定較長的解鎖逾時時間:
keosd --unlock-timeout 999999999 &
如此一來,就不必每 15 分鐘 (預設逾時時間) 解鎖錢包。這也會啟動 keosd Daemon 服務。回應內容應類似下方範例:
info thread-0 wallet_plugin.cpp:38 plugin_initialize ] initializing wallet plugin
info thread-0 wallet_api_plugin.cpp:84 plugin_startup ] starting wallet_api_plugin
info thread-0 http_plugin.cpp:983 add_handler ] add api url: /v1/wallet/create
...
info thread-0 http_plugin.cpp:983 add_handler ] add api url: /v1/wallet/unlock
info thread-0 http_plugin.cpp:983 add_handler ] add api url: /v1/node/get_supported_apis
如需返回殼層提示視窗,請按下 Enter 鍵。
- 建立預設錢包,並將錢包密碼輸出至名為 my_wallet_password 的檔案:
cleos wallet create --file my_wallet_password
這會建立名為「default」的錢包。回應內容應如下:
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
saving password to my_wallet_password
錢包建立完成後,keosd 預設會開啟並解鎖錢包。
- 如要查看所有代管錢包,請執行下列指令:
cleos wallet list
回應內容應如下:
Wallets:
[
"default *"
]
錢包名稱旁的星號表示已經解鎖。
點選「Check my progress」,確認目標已達成。
建立預設錢包
工作 4:將 EOSIO 系統帳戶的私密金鑰新增至錢包
每個新的 EOSIO 區塊鏈都有一個名為 eosio 的預設系統帳戶,用於進行區塊鏈的初始設定。根據預設,此帳戶會與以下私密金鑰相關聯:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3。
將這個私密金鑰匯入錢包,代表 eosio 帳戶簽署交易。
- 使用 cleos wallet open 指令,開啟 default 錢包。請注意,錢包已開啟並解鎖,但如果再次鎖定,您須執行下列程序:
cleos wallet open
回應內容應如下:
Opened: default
- 使用 cleos wallet unlock 指令,並傳遞在 my_wallet_password 檔案中儲存的錢包密碼,解鎖 default 錢包:
cleos wallet unlock <my_wallet_password
回應內容應如下:
password: Unlocked: default
- 使用 cleos wallet import 指令,將 EOSIO 私密金鑰
5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 匯入 default 錢包:
cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
回應內容應如下:
imported private key for: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
這是與所匯入私密金鑰相對應的公開金鑰。請忽略關於使用預設錢包的任何警告。在正式環境部署時,您可以考慮為錢包命名,而不是使用「default」當做名稱。
點選「Check my progress」,確認目標已達成。
將 EOSIO 系統帳戶的私密金鑰新增至錢包
工作 5:安裝 EOSIO 合約開發工具包 (CDT)
EOSIO CDT 工具包內含 CDT C++ 編譯器,可用於建構系統合約,以及日後您自己的 C++ 智慧合約。系統合約非常重要,能啟用第二層軟體功能,進而新增及支援其他功能。
- 首先,安裝 build-essential 套件。這個套件包含在 Linux 環境建構 C/C++ 軟體所需的各種工具。
sudo apt install build-essential
- 取得 EOSIO CDT 二進位檔:
curl -LO https://github.com/eosio/eosio.cdt/releases/download/v1.8.1/eosio.cdt_1.8.1-1-ubuntu-18.04_amd64.deb
- 安裝 EOSIO CDT 二進位檔:
sudo apt install ./eosio.cdt_1.8.1-1-ubuntu-18.04_amd64.deb
- 確認已安裝 EOSIO CDT 編譯器:
eosio-cpp --version
系統應會回覆 EOSIO CDT 編譯器版本資訊:
eosio-cpp version 1.8.1
點選「Check my progress」,確認目標已達成。
安裝 EOSIO 合約開發工具包
工作 6:建構系統合約和 eosio.boot
您需要部署 EOSIO 系統合約,才能建立可運作的多節點 EOSIO 區塊鏈。系統合約的用途包括但不限於:提供 EOSIO 共識所需的第 2 層功能;支援質押代幣、投票與建立自有代幣等操作;並確保新功能可成功整合及運作。
- 安裝 CMake,這是 eosio.contracts 建構指令碼所使用的軟體依附元件:
sudo apt install cmake
- 下載最新版系統 eosio.contracts:
git clone https://github.com/EOSIO/eosio.contracts.git \
--branch release/1.9.x --single-branch
- 建構系統 eosio.contracts。在這個步驟中,您也需要傳遞 eosio 和 eosio.cdt 的安裝目錄。
cd eosio.contracts
./build.sh -e /usr/opt/eosio/2.1.0 -c /usr/opt/eosio.cdt/1.8.1
cd ~
若出現任何關於缺少 ricardian 合約的警告,請直接忽略。回應內容應類似下方範例 (不含警告):
Using EOSIO.CDT installation at: /usr/opt/eosio.cdt/1.8.1
=========== Building eosio.contracts ===========
...
-- Building eosio.contracts v1.9.2
...
-- Unit tests will not be built. To build tests, set BUILD_TESTS to true.
-- Configuring done
-- Generating done
-- Build files have been written to: ./eosio.contracts/build
[ 11%] Performing build step for 'contracts_project'
[ 18%] Built target eosio.bios
[ 18%] Built target eosio.msig
[ 36%] Built target powup.results
[ 36%] Built target rex.results
[ 54%] Built target eosio.token
[ 90%] Built target eosio.system
[100%] Built target eosio.wrap
[ 22%] No install step for 'contracts_project'
[ 33%] No test step for 'contracts_project'
[ 44%] Completed 'contracts_project'
[100%] Built target contracts_project`
請記下 EOSIO 系統合約的建構位置,稍後部署特定系統合約時會用到:~/eosio.contracts/build/contracts。
- 建構 eosio.boot 系統合約:
git clone https://github.com/EOSIO/eos.git \
--branch release/2.1.x --single-branch
cd eos/contracts/contracts/eosio.boot
cmake .
make
cd ~
請忽略警告。回應內容應類似下方範例:
-- Configuring done
-- Generating done
-- Build files have been written to: ~/eos/contracts/contracts/eosio.boot
- 記下 eosio.boot 合約的建構位置,稍後的部署作業會用到:
~/eos/contracts/contracts/eosio.boot。
點選「Check my progress」,確認目標已達成。
建構系統合約和 eosio.boot
工作 7:啟動引導節點並建立系統帳戶
在這項工作中,您將啟動引導創世節點,並建立系統帳戶,這與建立錢包不同,必須將交易傳送至區塊鏈。
因此,引導節點至少必須處於執行狀態。為此,您需要先建立資料目錄和創世檔案,供所有節點使用。若是正式環境,每個節點都會託管在自己的伺服器上,並使用自己的資源。在本實驗室中,您將於同一環境部署所有節點。
- 建立新目錄 nodes,用於儲存每個節點的區塊鏈資料庫、記錄檔和設定檔。
mkdir nodes
- 在 nodes 目錄,建立預設的 genesis.json 檔案:
cat >nodes/genesis.json
- 複製下列 JSON 內容並貼到終端機,依序按下 Enter 鍵和 Ctrl-D 鍵,儲存 genesis.json 檔案:
{
"initial_timestamp": "2018-06-01T12:00:00.000",
"initial_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"initial_configuration": {
"max_block_net_usage": 1048576,
"target_block_net_usage_pct": 1000,
"max_transaction_net_usage": 524288,
"base_per_transaction_net_usage": 12,
"net_usage_leeway": 500,
"context_free_discount_net_usage_num": 20,
"context_free_discount_net_usage_den": 100,
"max_block_cpu_usage": 200000,
"target_block_cpu_usage_pct": 1000,
"max_transaction_cpu_usage": 150000,
"min_transaction_cpu_usage": 100,
"max_transaction_lifetime": 3600,
"deferred_trx_expiration_window": 600,
"max_transaction_delay": 3888000,
"max_inline_action_size": 524288,
"max_inline_action_depth": 4,
"max_authority_depth": 6
},
"initial_chain_id": "0000000000000000000000000000000000000000000000000000000000000000"
}
「initial_key」是指 eosio 帳戶使用的初始開發公開金鑰。如有需要,您可以將「initial_key」替換為自己的開發金鑰;這也是在正式環境部署時的建議做法。這類金鑰必須存在於 eosio 帳戶所使用的錢包。您已在先前章節中匯入該金鑰。
- 確認 genesis.json 檔案已成功建立並填入內容:
cat nodes/genesis.json
您應會看到與先前步驟相同的內容。
- 建立引導節點目錄 nodes/00-boot,用來儲存與引導節點相關的所有區塊鏈資料:
mkdir nodes/00-boot
- 啟動引導節點,以背景工作形式啟動 nodeos 服務 Daemon,並將 stdout/stderr 重新導向至 00-boot/00.log 檔案:
nodeos \
--plugin eosio::http_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::producer_api_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::net_api_plugin \
--contracts-console \
--max-transaction-time=200 \
--chain-state-db-size-mb 1024 \
--enable-stale-production \
--producer-name eosio \
--genesis-json ~/nodes/genesis.json \
--blocks-dir ~/nodes/00-boot/blocks \
--config-dir ~/nodes/00-boot \
--data-dir ~/nodes/00-boot \
--http-server-address 127.0.0.1:8888 \
--p2p-listen-endpoint 127.0.0.1:9876 \
--signature-provider EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 \
>>~/nodes/00-boot/00.log 2>&1 &
這會啟動引導節點並載入部分外掛程式,生產者名稱設為 eosio,監聽對象為 HTTP 通訊埠 8888 和 P2P 通訊埠 9876,並使用預設開發金鑰 EOS6MRy...、5KQwrP... 來簽署區塊。如果 EOSIO 開發金鑰未覆寫為 --signature-provider,系統會使用預設金鑰。
- 確認引導節點正在執行及產生區塊:
tail -f nodes/00-boot/00.log
輸出內容會如下所示。
輸出內容:
...
info 2021-03-08T02:44:11.900 nodeos producer_plugin.cpp:2333 produce_block ] Produced block e0dc6324ce3c8f35... #588 @ 2021-03-08T02:44:12.000 signed by eosio [trxs: 0, lib: 587, confirmed: 0]
最後一行會顯示最新產生的區塊編號,以及目前的最終不可逆區塊 (lib);後者代表區塊鏈末端的最後一個區塊。
-
按下 Ctrl+C 鍵,結束 tail 程式。
-
引導節點開始執行後,您可取得儲存在鏈結資料庫的 eosio 帳戶相關資訊:
cleos get account eosio
回應內容應如下:
created: 2018-06-01T12:00:00.000
privileged: true
permissions:
owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
memory:
quota: unlimited used: 2.66 KiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
請注意,eosio 帳戶確實是特殊權限帳戶,而與 owner 和 active 權限相關聯的金鑰,即為先前匯入錢包的該組預設開發金鑰。這樣一來,設定多節點區塊鏈時,eosio 帳戶就能授權交易。
- 建立其他系統帳戶。這些帳戶也會儲存在區塊鏈資料庫。
cleos create account eosio eosio.bpay EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.msig EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.names EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.ram EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.ramfee EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.saving EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.stake EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.vpay EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio eosio.rex EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
您會將相同的開發金鑰組指派給所有系統帳戶,以及 owner 和 active 權限。在正式環境部署時,建議您指派不同的金鑰組給各個權限,以便加強安全防護。您也可以為每個系統帳戶設定不同金鑰。
上述指令的回應內容應類似下方範例:
executed transaction: 98f22027c6703e554042b1d4a93beb70b1dc30be0fe65267932155c9d70e6493 200 bytes 153 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"eosio.bpay","owner":{"threshold":1,"keys":[{"key":"EOS6MRyAjQq8ud7hVNYcfn...
warning: transaction executed locally, but may not be confirmed by the network yet ]
...
executed transaction: 2f0cb00110374976f3cd9195bccac81fe0ee330c515b4a656d6d41f6181f636d 200 bytes 189 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"eosio.rex","owner":{"threshold":1,"keys":[{"key":"EOS6MRyAjQq8ud7hVNYcfnV...
warning: transaction executed locally, but may not be confirmed by the network yet ]
請忽略警告。您會在後續工作中使用這些帳戶。
點選「Check my progress」,確認目標已達成。
建構系統合約和 eosio.boot
工作 8:部署 eosio.token 和 eosio.msig 合約,建立/發行 SYS 代幣
在這項工作中,您將建立並發行虛構的 SYS 代幣,為此也需要部署先前建構的 eosio.token 和 eosio.msig 系統合約。
- 部署 eosio.token 合約。有了這份合約,您便可建立、發行及轉移新代幣或現有代幣。
cleos set contract eosio.token ~/eosio.contracts/build/contracts/eosio.token/
回應內容應類似下方範例:
Reading WASM from ~/eosio.contracts/build/contracts/eosio.token/eosio.token.wasm...
Publishing contract...
executed transaction: 11aca7fb68e0821cf8f74be0188741964787f830d0918abdfccae4a54c25e291 19360 bytes 4445 us
# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d010000000180022860000060037f7f7f01...
# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e320008076163636f756e7400010762616c616e63...
- 部署 eosio.msig 合約。這份合約支援帳戶之間的多重簽署程序,並能簡化權限管理作業。
cleos set contract eosio.msig ~/eosio.contracts/build/contracts/eosio.msig/
回應內容會類似下方範例:
Reading WASM from ~/eosio.contracts/build/contracts/eosio.msig/eosio.msig.wasm...
Publishing contract...
executed transaction: c2260b7d05bb38d2df097799baedd890ce7560bedbd1b79e7d07e4f6a5b25238 23256 bytes 3684 us
# eosio <= eosio::setcode {"account":"eosio.msig","vmtype":0,"vmversion":0,"code":"0061736d0100000001b8022f60000060037f7f7f017...
# eosio <= eosio::setabi {"account":"eosio.msig","abi":"0e656f73696f3a3a6162692f312e32001006616374696f6e0004076163636f756e740...
- 建立 SYS 代幣,總發行量為 100 億枚:
cleos push action eosio.token create '["eosio", "10000000000.0000 SYS"]' -p eosio.token
上述指令會從 eosio.token 合約推送一筆含有 create 動作的交易,並透過 eosio.token 帳戶的 active 權限授權。回應內容應類似下方範例:
executed transaction: 6a4766a00c8fe26343d5eb6c1ad5e53b35064dc6f3a5f55908eff2edba30efca 120 bytes 603 us
# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"10000000000.0000 SYS"}
- 將 10 億枚 SYS 代幣從儲備庫發行至流通市場:
cleos push action eosio.token issue '["eosio", "1000000000.0000 SYS", "memo"]' -p eosio
上述指令會從 eosio.token 合約推送一筆含有 issue 動作的交易,並透過 eosio 帳戶的 active 權限授權。
回應內容會類似下方範例:
executed transaction: 4613fcff26bc6f96010273b475e839018f0afe2ef2af840d481070c9c54e36f1 128 bytes 405 us
# eosio.token <= eosio.token::issue {"to":"eosio","quantity":"1000000000.0000 SYS","memo":"memo"}
點選「Check my progress」,確認目標已達成。
建立及部署 eosio.token、eosio.msig 合約和 SYS 代幣
工作 9:啟用通訊協定功能,並部署 eosio.boot 和 eosio.system 合約
通訊協定功能可為 EOSIO 區塊鏈帶來額外的選用功能。在這項工作中,您將啟用一些強烈建議用於 EOSIO 區塊鏈的通訊協定功能。為此需要先部署 eosio.boot 合約,再啟用這些功能。最後,您將部署 eosio.system 合約,完成 EOSIO 區塊鏈的第二層架構。
這能啟用系統資源 (CPU、RAM、NET),並支援代幣質押/取消質押、資源購買、潛在生產者註冊與隨後的投票作業、生產者獎勵領取,以及權限和限制設定等。通訊協定功能必須透過 EOSIO 共識,取得絕對多數生產者的同意後才能啟用。在本案例中,您只需執行引導節點。
- 首先,安裝 jq 工具,使 JSON 字串的剖析結果更易於閱讀:
sudo apt install jq
- 現在,我們來查看系統支援哪些通訊協定功能:
curl -X POST http://127.0.0.1:8888/v1/producer/get_supported_protocol_features -d '{"exclude_disabled": false, "exclude_unactivatable": false}' | jq | more
上述指令會將 HTTP POST 要求,傳送至由 Producer API 外掛程式提供的 get_supported_protocol_features 端點。
回應內容會顯示現有 EOSIO 網路 (目前只包含引導節點) 支援的所有通訊協定功能。
查看輸出內容 (多次按下空格鍵),直到返回殼層提示視窗。
輸出內容:
[{"feature_digest": "0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd", "subjective_restrictions": {"enabled": true, "preactivation_required": false, "earliest_allowed_activation_time": "1970-01-01T00:00:00.000"}, "description_digest": "64fe7df32e9b86be2b296b3f81dfd527f84e82b98e363bc97e40bc7a83733310", "dependencies": [], "protocol_feature_type": "builtin", "specification": [{"name": "builtin_feature_codename", "value": "PREACTIVATE_FEATURE"}]},
...
{"feature_digest": "ded2e25adcd78cbb94fa7f63a8f80a9af2b1a905e551a6e124e7d7829da1ea02", "subjective_restrictions": {"enabled": true, "preactivation_required": true, "earliest_allowed_activation_time": "1970-01-01T00:00:00.000"}, "description_digest": "72ec6337e369cbb33ef7716d3267db9d5678fe54555c25ca4c9f5b9dfb7739f3", "dependencies": [], "protocol_feature_type": "builtin", "specification": [{"name": "builtin_feature_codename", "value": "SECURITY_GROUP"}]},
...
{"feature_digest": "f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d", "subjective_restrictions": {"enabled": true, "preactivation_required": true, "earliest_allowed_activation_time": "1970-01-01T00:00:00.000"}, "description_digest": "1eab748b95a2e6f4d7cb42065bdee5566af8efddf01a55a0a8d831b823f8828a", "dependencies": [], "protocol_feature_type": "builtin", "specification": [{"name": "builtin_feature_codename", "value": "GET_SENDER"}]}]
- 啟用 PREACTIVATE_FEATURE 功能。如此便能啟用其他功能,例如可以升級 eosio.system 合約,進而導入新功能。另請注意,如要啟用通訊協定功能,必須傳遞該功能的摘要或雜湊碼。
curl -X POST http://127.0.0.1:8888/v1/producer/schedule_protocol_feature_activations -d '{"protocol_features_to_activate": ["0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd"]}'
請注意,您可以查看先前步驟中 get_supported_protocol_features 端點傳回的資料,在 feature_digest 欄位找到功能摘要雜湊碼 0ec7e...。如果啟用成功,回應內容應如下所示。
輸出內容:
{"result": "ok"}
如果該功能已啟用,系統會改為傳回下列回應,您可以放心忽略。
輸出內容:
{"code": 500, "message": "Internal Service Error", "error": {"code": 3250000, "name": "protocol_feature_exception", "what": "Protocol feature exception", "details": [{"message": "protocol feature with digest '<hex-value>' has already been activated", "file": "controller.cpp", "line_number": 1650, "method": "check_protocol_features"}]}}
- 部署 eosio.boot 合約:
cleos set contract eosio ~/eos/contracts/contracts/eosio.boot/
回應內容應類似下方範例:
Reading WASM from ~/eos/contracts/contracts/eosio.boot/eosio.boot.wasm...
Publishing contract...
executed transaction: a029c644104da357a201f75058fc6772cf63f5fdfa9135be2c3b7c498d81d46d 2752 bytes 852 us
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d01000000013e0c60000060027f7f0060017e0060...
# eosio <= eosio::setabi {"account":"eosio","abi":"0e656f73696f3a3a6162692f312e32001008616374697661746500010e666561747572655f...
- 啟用其他通訊協定功能,例如 KV_DATABASE、ACTION_RETURN_VALUE 等。這項操作可在部署 eosio.boot 合約後執行。
# KV_DATABASE
cleos push action eosio activate '["825ee6288fb1373eab1b5187ec2f04f6eacb39cb3a97f356a07c91622dd61d16"]' -p eosio
# ACTION_RETURN_VALUE
cleos push action eosio activate '["c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071"]' -p eosio
# CONFIGURABLE_WASM_LIMITS
cleos push action eosio activate '["bf61537fd21c61a60e542a5d66c3f6a78da0589336868307f94a82bccea84e88"]' -p eosio
# BLOCKCHAIN_PARAMETERS
cleos push action eosio activate '["5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4"]' -p eosio
# GET_SENDER
cleos push action eosio activate '["f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d"]' -p eosio
# FORWARD_SETCODE
cleos push action eosio activate '["2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25"]' -p eosio
# ONLY_BILL_FIRST_AUTHORIZER
cleos push action eosio activate '["8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405"]' -p eosio
# RESTRICT_ACTION_TO_SELF
cleos push action eosio activate '["ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43"]' -p eosio
# DISALLOW_EMPTY_PRODUCER_SCHEDULE
cleos push action eosio activate '["68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428"]' -p eosio
# FIX_LINKAUTH_RESTRICTION
cleos push action eosio activate '["e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526"]' -p eosio
# REPLACE_DEFERRED
cleos push action eosio activate '["ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"]' -p eosio
# NO_DUPLICATE_DEFERRED_ID
cleos push action eosio activate '["4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f"]' -p eosio
# ONLY_LINK_TO_EXISTING_PERMISSION
cleos push action eosio activate '["1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241"]' -p eosio
# RAM_RESTRICTIONS
cleos push action eosio activate '["4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67"]' -p eosio
# WEBAUTHN_KEY
cleos push action eosio activate '["4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2"]' -p eosio
# WTMSIG_BLOCK_SIGNATURES
cleos push action eosio activate '["299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707"]' -p eosio
- 部署 eosio.system 合約。這會啟用第二層功能,並允許從單節點轉換為多節點區塊鏈。
cleos set contract eosio ~/eosio.contracts/build/contracts/eosio.system/
點選「Check my progress」,確認目標已達成。
部署 eosio.boot 和 eosio.system 合約
工作 10:建立區塊生產者帳戶
在這項工作中,您將建立生產者帳戶,這些帳戶最終會接管 EOSIO 區塊鏈並產生區塊。第一步是將 eosio.msig 指定為特殊權限帳戶,以便代表 eosio 帳戶完成授權。eosio 帳戶之後會放棄此權限,改由代表獲選生產者群組的 eosio.prods 帳戶,接手區塊生產及驗證工作。
- 將 eosio.msig 設為特殊權限帳戶:
cleos push action eosio setpriv '["eosio.msig", 1]' -p eosio
回應內容應類似下方範例:
executed transaction: 385f0eb3c169898cc7faae46bb4371dbbfc46c5d482249c9933c4f8627fb271c 104 bytes 208 us
# eosio <= eosio::setpriv {"account":"eosio.msig","is_priv":1}
- 將 SYS 代幣初始化為版本 0,並設定精確度為 4 位小數:
cleos push action eosio init '["0", "4,SYS"]' -p eosio
回應內容應類似下方範例:
executed transaction: c537fbd77983104d8dcb1c58b09b433f68a2dd12c876a27b7556d4a722d42939 104 bytes 3467 us
# eosio <= eosio::init {"version":0,"core":"4,SYS"}
# eosio.token <= eosio.token::open {"owner":"eosio.rex","symbol":"4,SYS","ram_payer":"eosio"}
- 匯入生產者簽署區塊時要使用的金鑰。在正式環境部署時,應先建立這類金鑰再匯入。
cleos wallet import --private-key 5KLGj1HGRWbk5xNmoKfrcrQHXvcVJBPdAckoiJgFftXSJjLPp7b
cleos wallet import --private-key 5K6qk1KaCYYWX86UhAfUsbMwhGPUqrqHrZEQDjs9ekP5j6LgHUu
cleos wallet import --private-key 5JCStvbRgUZ6hjyfUiUaxt5iU3HP6zC1kwx3W7SweaEGvs4EPfQ
cleos wallet import --private-key 5JJjaKnAb9KM2vkkJDgrYXoeUEdGgWtB5WK1a38wrmKnS3KtkS6
匯入這些現有金鑰可簡化本實驗室的資源管理作業,但在正式環境部署時,應建立新金鑰。
各指令的回應內容應如下:
imported private key for: EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz
imported private key for: EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC
imported private key for: EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6
imported private key for: EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d
如果是分散式節點,各金鑰組會獨立儲存在各伺服器的錢包。為求簡單,本實驗室中會將各金鑰組儲存在同一個錢包。
- 使用初始資源和公開金鑰,建立區塊生產者帳戶:
cleos system newaccount --transfer eosio producer.one EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz --stake-net "50000000.0000 SYS" --stake-cpu "50000000.0000 SYS" --buy-ram-kbytes 8192
cleos system newaccount --transfer eosio producer.two EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC --stake-net "50000000.0000 SYS" --stake-cpu "50000000.0000 SYS" --buy-ram-kbytes 8192
cleos system newaccount --transfer eosio produc.three EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6 --stake-net "50000000.0000 SYS" --stake-cpu "50000000.0000 SYS" --buy-ram-kbytes 8192
cleos system newaccount --transfer eosio produce.four EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d --stake-net "50000000.0000 SYS" --stake-cpu "50000000.0000 SYS" --buy-ram-kbytes 8192
上述指令會建立新帳戶 producer.one、producer.two、produc.three、produce.four,並將先前步驟匯入的各個金鑰與個別帳戶建立關聯。此外,這項指令也會分配並質押 5,000 萬枚 SYS 給 NET 和 CPU,同時分配 8,000 枚 SYS 給 RAM。
回應內容應類似下方範例 (適用於每個新帳戶):
executed transaction: 6164d2741433c68edf426d430cb0986b198a6f4c63e7f7a46bcf8343562eacc0 336 bytes 1029 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"producer.one","owner":{"threshold":1,"keys":[{"key":"EOS8imf2TDq6FKtLZ8mv...
# eosio <= eosio::buyrambytes {"payer":"eosio","receiver":"producer.one","bytes":8388608}
# eosio <= eosio::delegatebw {"from":"eosio","receiver":"producer.one","stake_net_quantity":"50000000.0000 SYS","stake_cpu_quantity...
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"122.0851 SYS","memo":"buy ram"}
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.6135 SYS","memo":"ram fee"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"122.0851 SYS","memo":"buy ram"}
# eosio.ram <= eosio.token::transfer {"from":"eosio","to":"eosio.ram","quantity":"122.0851 SYS","memo":"buy ram"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.6135 SYS","memo":"ram fee"}
# eosio.ramfee <= eosio.token::transfer {"from":"eosio","to":"eosio.ramfee","quantity":"0.6135 SYS","memo":"ram fee"}
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"100000000.0000 SYS","memo":"stake bandwidth"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"100000000.0000 SYS","memo":"stake bandwidth"}
# eosio.stake <= eosio.token::transfer {"from":"eosio","to":"eosio.stake","quantity":"100000000.0000 SYS","memo":"stake bandwidth"}
- 將新帳戶註冊為生產者。請注意,執行各項指令時,還需提供生產者的網址。此處使用的是虛擬網址,僅供參考。
cleos system regproducer producer.one EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz https://producer.one.com/EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz
cleos system regproducer producer.two EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC https://producer.two.com/EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC
cleos system regproducer produc.three EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6 https://produc.three.com/EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6
cleos system regproducer produce.four EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d https://produce.four.com/EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d
上述指令的回應內容應類似下方範例:
executed transaction: 28ced4a34abd64fb2fc11fbb51d3e4e18d2933a9ab2560fc1c6fb80b0cfc336d 216 bytes 753 us
# eosio <= eosio::regproducer {"producer":"producer.one","producer_key":"EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz","u...
executed transaction: 06b8be4187c5fbabc3197064ae4c6d55ba553fdbcc8a560f060078e59d5dfc5e 216 bytes 306 us
# eosio <= eosio::regproducer {"producer":"producer.two","producer_key":"EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC","u...
executed transaction: c23a5164bf0cc1e35dfa3e55fed56e935ceb7d764dbe2e7a3bf4aee446e7d88d 216 bytes 270 us
# eosio <= eosio::regproducer {"producer":"produc.three","producer_key":"EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6","u...
executed transaction: 081aa8aca08b6d4e8e6bf576b2882f578faa7148e7c550196ff256ab0a9dcca3 216 bytes 224 us
# eosio <= eosio::regproducer {"producer":"produce.four","producer_key":"EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d","u...
- 列出目前的生產者帳戶,總共應有四個。
cleos system listproducers
回應內容應如下:
Producer Producer key Url Scaled votes`
**`produc.three`** `EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6 https://produc.three.com/EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNj` **`0.0000`**
**`produce.four`** `EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d https://produce.four.com/EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8` **`0.0000`**
**`producer.one`** `EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz https://producer.one.com/EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8` **`0.0000`**
**`producer.two`** `EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC https://producer.two.com/EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuE` **`0.0000`**
請注意,由於尚未開始投票,目前所有生產者的票數皆為零。
點選「Check my progress」,確認目標已達成。
建立區塊生產者帳戶
工作 11:從單節點生產者轉換為多節點生產者
在這項工作中,您終於要將單節點區塊鏈轉換為多節點架構。目前只有 eosio 帳戶具有特殊權限,可以簽署區塊。我們的目標是建立由一組獲選生產者管理的 EOSIO 區塊鏈;當絕對多數 (2/3 + 1) 的生產者確認區塊後,即視為達成共識。屆時,該區塊內的所有交易都將最終定案。
- 建立其餘節點目錄 nodes/01-node、nodes/02-node、nodes/03-node、nodes/04-node,用來儲存與新產生的節點 1、2、3、4 相關的所有區塊鏈資料:
mkdir nodes/01-node nodes/02-node nodes/03-node nodes/04-node
- 啟動節點 1,以背景工作形式啟動 nodeos 服務 Daemon,並將 stdout/stderr 重新導向至 01-node/01.log 檔案:
nodeos \
--plugin eosio::http_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::producer_api_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::net_api_plugin \
--contracts-console \
--max-transaction-time=200 \
--chain-state-db-size-mb 1024 \
--enable-stale-production \
--producer-name producer.one \
--genesis-json ~/nodes/genesis.json \
--blocks-dir ~/nodes/01-node/blocks \
--config-dir ~/nodes/01-node \
--data-dir ~/nodes/01-node \
--http-server-address 127.0.0.1:8889 \
--p2p-listen-endpoint 127.0.0.1:9877 \
--signature-provider EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz=KEY:5KLGj1HGRWbk5xNmoKfrcrQHXvcVJBPdAckoiJgFftXSJjLPp7b \
--p2p-peer-address 127.0.0.1:9876 \
>>~/nodes/01-node/01.log 2>&1 &
這會啟動節點 1 並載入部分外掛程式,生產者名稱設為 producer.one,監聽對象為 HTTP 通訊埠 8889 和 P2P 通訊埠 9877,同時以節點本身的金鑰 EOS8imf...、5KLGj1... 覆寫預設開發金鑰,並連線至 P2P 節點 9876 (引導節點)。
- 如要檢查節點 1 的記錄,瞭解與引導節點 (P2P 節點 9876) 交換的訊息,可以執行下列指令:
cat nodes/01-node/01.log | grep :9876 -C 3
輸出內容應類似下方範例。
輸出內容:
info 2021-10-22T21:56:43.161 nodeos producer_plugin.cpp:421 on_incoming_block ] Received block e79c2cc7df2bd7bc... #3040 @ 2021-10-22T21:56:41.500 signed by eosio [trxs: 0, lib: 3039, conf: 0, latency: 1661 ms]
...
info 2021-10-22T21:56:43.162 net-1 net_plugin.cpp:1604 set_state ] old state lib catchup becoming in sync
info 2021-10-22T21:56:43.162 net-1 net_plugin.cpp:1132 operator() ] Sending handshake generation 2 to 127.0.0.1:9876- 446609d, lib 3040, head 3041, id 5d69f1fa874933cf
info 2021-10-22T21:56:43.163 net-0 net_plugin.cpp:1947 sync_recv_notice ] notice_message, pending 3043, blk_num 3043, id b8f3389c52ff416c...
info 2021-10-22T21:56:43.163 net-0 net_plugin.cpp:1908 verify_catchup ] catch_up while in in sync, fork head num = 3043 target LIB = 3041 next_expected = 3042, id b8f3389c52ff416c..., peer 127.0.0.1:9876 - 446609d
info 2021-10-22T21:56:43.163 net-0 net_plugin.cpp:1604 set_state ] old state in sync becoming head catchup
info 2021-10-22T21:56:43.164 nodeos producer_plugin.cpp:421 on_incoming_block ] Received block 917275dee8c12e57... #3042 @ 2021-10-22T21:56:42.500 signed by eosio [trxs: 0, lib: 3041, conf: 0, latency: 664 ms]
...
請注意,節點 1 目前尚未產生區塊,但會接收/同步處理其他節點 (例如引導節點) 的區塊。
- 啟動節點 2,以背景工作形式啟動 nodeos 服務 Daemon,並將 stdout/stderr 重新導向至 02-node/02.log 檔案:
nodeos \
--plugin eosio::http_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::producer_api_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::net_api_plugin \
--contracts-console \
--max-transaction-time=200 \
--chain-state-db-size-mb 1024 \
--enable-stale-production \
--producer-name producer.two \
--genesis-json ~/nodes/genesis.json \
--blocks-dir ~/nodes/02-node/blocks \
--config-dir ~/nodes/02-node \
--data-dir ~/nodes/02-node \
--http-server-address 127.0.0.1:8890 \
--p2p-listen-endpoint 127.0.0.1:9878 \
--signature-provider EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC=KEY:5K6qk1KaCYYWX86UhAfUsbMwhGPUqrqHrZEQDjs9ekP5j6LgHUu \
--p2p-peer-address 127.0.0.1:9876 \
--p2p-peer-address 127.0.0.1:9877 \
>>~/nodes/02-node/02.log 2>&1 &
這會啟動節點 2 並載入部分外掛程式,生產者名稱設為 producer.two,監聽對象為 HTTP 通訊埠 8890 和 P2P 通訊埠 9878,同時以節點本身的金鑰 EOS8imf...、5KLGj1... 覆寫預設開發金鑰,並連線至 P2P 節點 9876 (引導節點) 和 9877 (節點 1)。
- 如要檢查節點 2 的記錄,瞭解與節點 1 (P2P 節點 9877) 交換的訊息,可以執行下列指令:
cat nodes/02-node/02.log | grep :9877 -C 3
輸出內容應類似下方範例。
輸出內容:
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1771 start_sync ] Catching up with chain, our last req is 6852, theirs is 6859 peer 127.0.0.1:9877 - 1a245d2
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1717 operator() ] requesting range 6853 to 6859, from 127.0.0.1:9877- 1a245d2
info 2021-10-22T22:28:31.497 nodeos producer_plugin.cpp:421 on_incoming_block ] Received block 3073fa4230d8d232... #6853 @ 2021-10-22T22:28:28.000 signed by eosio [trxs: 0, lib: 6852, conf: 0, latency: 3497 ms]
...
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1604 set_state ] old state lib catchup becoming in sync
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1132 operator() ] Sending handshake generation 3 to 127.0.0.1:9877- 1a245d2, lib 6858, head 6859, id 9a791a880b9b875e
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1947 sync_recv_notice ] notice_message, pending 6860, blk_num 6860, id 4dd2c7c8ae5301ed...
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1908 verify_catchup ] catch_up while in in sync, fork head num = 6860 target LIB = 6859 next_expected = 6860, id 4dd2c7c8ae5301ed..., peer 127.0.0.1:9877 - 1a245d2
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1604 set_state ] old state in sync becoming head catchup
...
請注意,節點 2 目前尚未產生區塊,但會接收/同步處理其他節點 (例如引導節點和節點 1) 的區塊。
- 啟動節點 3,以背景工作形式啟動 nodeos 服務 Daemon,並將 stdout/stderr 重新導向至 03-node/03.log 檔案:
nodeos \
--plugin eosio::http_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::producer_api_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::net_api_plugin \
--contracts-console \
--max-transaction-time=200 \
--chain-state-db-size-mb 1024 \
--enable-stale-production \
--producer-name produc.three \
--genesis-json ~/nodes/genesis.json \
--blocks-dir ~/nodes/03-node/blocks \
--config-dir ~/nodes/03-node \
--data-dir ~/nodes/03-node \
--http-server-address 127.0.0.1:8891 \
--p2p-listen-endpoint 127.0.0.1:9879 \
--signature-provider EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6=KEY:5JCStvbRgUZ6hjyfUiUaxt5iU3HP6zC1kwx3W7SweaEGvs4EPfQ \
--p2p-peer-address 127.0.0.1:9876 \
--p2p-peer-address 127.0.0.1:9877 \
--p2p-peer-address 127.0.0.1:9878 \
>>~/nodes/03-node/03.log 2>&1 &
這會啟動節點 3 並載入部分外掛程式,生產者名稱設為 produc.three,監聽對象為 HTTP 通訊埠 8891 和 P2P 通訊埠 9879,同時以節點本身的金鑰 EOS5n44...、5JCStv... 覆寫預設開發金鑰,並連線至 P2P 節點 9876 (引導節點)、9877 (節點 1) 和 9878 (節點 2)。
- 如要檢查節點 3 的記錄,瞭解與節點 2 (P2P 節點 9878) 交換的訊息,可以執行下列指令:
cat nodes/03-node/03.log | grep :9878 -C 3
輸出內容應類似下方範例。
輸出內容:
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1771 start_sync ] Catching up with chain, our last req is 6852, theirs is 6859 peer 127.0.0.1:`**`9878`** `- 1a245d2`
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1717 operator() ] requesting range 6853 to 6859, from 127.0.0.1:`**`9878`** `- 1a245d2`
info 2021-10-22T22:28:31.497 nodeos producer_plugin.cpp:421 on_incoming_block ] Received block 3073fa4230d8d232... #6853 @ 2021-10-22T22:28:28.000 signed by eosio [trxs: 0, lib: 6852, conf: 0, latency: 3497 ms]
...
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1604 set_state ] old state lib catchup becoming in sync
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1132 operator() ] Sending handshake generation 3 to 127.0.0.1:`**`9878`** `- 1a245d2, lib 6858, head 6859, id 9a791a880b9b875e
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1947 sync_recv_notice ] notice_message, pending 6860, blk_num 6860, id 4dd2c7c8ae5301ed...
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1908 verify_catchup ] catch_up while in in sync, fork head num = 6860 target LIB = 6859 next_expected = 6860, id 4dd2c7c8ae5301ed..., peer 127.0.0.1:`**`9878`** `- 1a245d2
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1604 set_state ] old state in sync becoming head catchup
...
請注意,節點 3 目前尚未產生區塊,但會接收/同步處理其他節點 (例如引導節點、節點 1 和 2) 的區塊。
- 啟動節點 4,以背景工作形式啟動 nodeos 服務 Daemon,並將 stdout/stderr 重新導向至 04-node/04.log 檔案:
nodeos \
--plugin eosio::http_plugin --plugin eosio::chain_api_plugin --plugin eosio::chain_plugin --plugin eosio::producer_api_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::net_api_plugin \
--contracts-console \
--max-transaction-time=200 \
--chain-state-db-size-mb 1024 \
--enable-stale-production \
--producer-name produce.four \
--genesis-json ~/nodes/genesis.json \
--blocks-dir ~/nodes/04-node/blocks \
--config-dir ~/nodes/04-node \
--data-dir ~/nodes/04-node \
--http-server-address 127.0.0.1:8892 \
--p2p-listen-endpoint 127.0.0.1:9880 \
--signature-provider EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d=KEY:5JJjaKnAb9KM2vkkJDgrYXoeUEdGgWtB5WK1a38wrmKnS3KtkS6 \
--p2p-peer-address 127.0.0.1:9876 \
--p2p-peer-address 127.0.0.1:9877 \
--p2p-peer-address 127.0.0.1:9878 \
--p2p-peer-address 127.0.0.1:9879 \
>>~/nodes/04-node/04.log 2>&1 &
這會啟動節點 4 並載入部分外掛程式,生產者名稱設為 produce.four,監聽對象為 HTTP 通訊埠 8892 和 P2P 通訊埠 9880,同時以節點本身的金鑰 EOS5y3T...、5JJjaK... 覆寫預設開發金鑰,並連線至 P2P 節點 9876 (引導節點)、9877 (節點 1)、9878 (節點 2) 和 9879 (節點 3)。
- 如要檢查節點 4 的記錄,瞭解與節點 3 (P2P 節點 9879) 交換的訊息,可以執行下列指令:
cat nodes/04-node/04.log | grep :9879 -C 3
回應內容應類似下方範例:
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1771 start_sync ] Catching up with chain, our last req is 6852, theirs is 6859 peer 127.0.0.1:9879 - 1a245d2
info 2021-10-22T22:28:31.496 net-1 net_plugin.cpp:1717 operator() ] requesting range 6853 to 6859, from 127.0.0.1:9879 - 1a245d2
info 2021-10-22T22:28:31.497 nodeos producer_plugin.cpp:421 on_incoming_block ] Received block 3073fa4230d8d232... #6853 @ 2021-10-22T22:28:28.000 signed by eosio [trxs: 0, lib: 6852, conf: 0, latency: 3497 ms]
...
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1604 set_state ] old state lib catchup becoming in sync
info 2021-10-22T22:28:31.501 net-0 net_plugin.cpp:1132 operator() ] Sending handshake generation 3 to 127.0.0.1:9879 - 1a245d2, lib 6858, head 6859, id 9a791a880b9b875e
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1947 sync_recv_notice ] notice_message, pending 6860, blk_num 6860, id 4dd2c7c8ae5301ed...
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1908 verify_catchup ] catch_up while in in sync, fork head num = 6860 target LIB = 6859 next_expected = 6860, id 4dd2c7c8ae5301ed..., peer 127.0.0.1:9879 - 1a245d2
info 2021-10-22T22:28:31.501 net-1 net_plugin.cpp:1604 set_state ] old state in sync becoming head catchup
...
請注意,節點 4 目前尚未產生區塊,但會接收/同步處理其他節點 (例如引導節點、節點 1、2 和 3) 的區塊。
現在,所有新節點 1、2、3、4 都已啟動並連線。這些節點會接收並同步處理引導節點所產生的區塊,但還不會產生區塊。為此,需要選出新的生產者。在正式環境部署時,使用者通常會透過投票指令,從候選生產者中選出最多 30 位生產者。得票數前 21 名的生產者會當選為區塊生產者。
在本實驗室中,您將使用現有的生產者帳戶,選出僅有的四位生產者。當 SYS 代幣質押量達到供應量的 15% 後,系統會提議由排名領先的生產者負責生產。在包含生產者清單的區塊完成確認並最終定案後,新的生產者就會在下一輪排程開始產生區塊。
- 使用 cleos system voteproducer prods 指令,投票給特定生產者。帳戶 producer.one 投票給自己及生產者 2、3 和 4;producer.two 投給自己、生產者 3 和 4。至於 produc.three 和 produce.four,則是先由 produc.three 投給自己和 produce.four,再由 produce.four 投給自己。
cleos system voteproducer prods producer.one producer.one producer.two produc.three produce.four
cleos system voteproducer prods producer.two producer.two produc.three produce.four
cleos system voteproducer prods produc.three produc.three produce.four
cleos system voteproducer prods produce.four produce.four
回應內容應類似下方範例:
executed transaction: 833178bdc9d5b8c86778fa2b2c0f20e976f4c253cb6ebcaa6ade8eb8bf3d0a4f 144 bytes 861 us
# eosio <= eosio::voteproducer {"voter":"producer.one","proxy":"","producers":["produc.three","produce.four","producer.one","produc...
executed transaction: 9c4961678017bfc2a7fd1398a2e4b33e472a6cadc0340400ebe9207e188d7692 136 bytes 379 us
# eosio <= eosio::voteproducer {"voter":"producer.two","proxy":"","producers":["produc.three","produce.four","producer.two"]}
executed transaction: d3d23bae8730f18e82da53defaff7184c49b83181bb9b6fa32096684e61ed74d 128 bytes 371 us`
# eosio <= eosio::voteproducer {"voter":"produc.three","proxy":"","producers":["produc.three","produce.four"]}
executed transaction: 95f63d46554dd436388e36b017b8e350514ef5b407b1c33c5779dc29c862cdb6 120 bytes 304 us`
# eosio <= eosio::voteproducer {"voter":"produce.four","proxy":"","producers":["produce.four"]}
- 查看各生產者的得票數百分比:
cleos system listproducers
上述指令的回應內容應如下:
Producer Producer key Url Scaled votes
produce.four EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8qHjmRjFxTyhh2vxvF5d https://produce.four.com/EOS5y3Tm1czTCia3o3JidVKmC78J9gRQU8 0.4000
produc.three EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNjRxAfPhUvM8tWS5svid6 https://produc.three.com/EOS5n442Qz4yVc4LbdPCDnxNSseAiUCrNj 0.3000
producer.two EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuEz2RMWhXb8LXxEgcR7MC https://producer.two.com/EOS7Ef4kuyTbXbtSPP5Bgethvo6pbitpuE 0.2000
producer.one EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8zKdLNzsbU9EiMSt9Lwz https://producer.one.com/EOS8imf2TDq6FKtLZ8mvXPWcd6EF2rQwo8 0.1000
請注意,生產者 1 獲得 10% 票數,生產者 2 獲得 20%,生產者 3 為 30%,生產者 4 則是 40%。由於所有生產者質押的 SYS 代幣總數超過代幣供應量的 15%,系統會提議由前 21 名生產者 (預設) 負責區塊生產。
當包含區塊生產者清單的區塊完成最終確認後,生產作業就會開始。由於只有四位生產者,因此全部生產者都會執行生產作業,且只要任意三個生產者達成共識,即可達到絕對多數。
- 確認新生產者確實在產生區塊:
tail -f nodes/01-node/01.log | grep Produced
上述指令應會顯示最後的區塊是由生產者 1 產生。如未看到任何輸出內容,請稍等幾秒鐘。四個生產者每 6 秒會各產生 12 個區塊,因此最後產生的區塊和下一輪的第一個區塊之間,應間隔 18 秒。
回應內容應類似下方範例:
info 2021-10-28T15:31:47.904 nodeos producer_plugin.cpp:2333 produce_block ] Produced block adeb43a9249e0ef8...` **`#7035`** `@ 2021-10-28T15:31:48.000 signed by` **`producer.one`** `[trxs: 0, lib: 6998, confirmed: 36]
info 2021-10-28T15:31:48.400 nodeos producer_plugin.cpp:2333 produce_block ] Produced block 991c7f7addb6006e...` **`#7036`** `@ 2021-10-28T15:31:48.500 signed by` **`producer.one`** `[trxs: 0, lib: 6998, confirmed: 0]
...
info 2021-10-28T15:31:52.901 nodeos producer_plugin.cpp:2333 produce_block ] Produced block c947dfab144600f7...` **`#7045`** `@ 2021-10-28T15:31:53.000 signed by` **`producer.one`** `[trxs: 0, lib: 6998, confirmed: 0]
info 2021-10-28T15:31:53.300 nodeos producer_plugin.cpp:2333 produce_block ] Produced block c871f71b3ebe9151...` **`#7046`** `@ 2021-10-28T15:31:53.500 signed by` **`producer.one`** `[trxs: 0, lib: 6998, confirmed: 0]`
再等待 18 秒,應該會看到下一輪產生的 12 個區塊,依此類推。您也可以將上述指令中的 01 替換為 02、03、04,確認其他三個節點確實會產生區塊。
-
按下 Ctrl+C 鍵,結束 tail 指令。
-
確認引導節點不再產生區塊:
tail -f nodes/00-boot/00.log | grep Produced
請注意,上述指令不應產生任何輸出內容,這表示引導節點已將區塊產生作業交給新選出的生產者。
現在區塊鏈已有四個生產者且能全面運作,您應撤銷預設 eosio 和相關 eosio.* 帳戶的相應權限,使這些帳戶無法再簽署交易及修改區塊鏈狀態。為此,您需要將 eosio 和 eosio.* 帳戶使用的金鑰重設為 null,以便註銷這些金鑰。
- 取得 eosio 帳戶資訊。請注意與 owner 和 active 權限相關聯的金鑰:
cleos get account eosio
回應內容應類似下方範例:
created: 2018-06-01T12:00:00.000
privileged: true
permissions:
owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
memory:
quota: unlimited used: 2.989 MiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
SYS balances:
liquid: 599999509.0258 SYS
staked: 0.0000 SYS
unstaking: 0.0000 SYS
total: 599999509.0258 SYS
- 註銷 eosio 帳戶使用的金鑰,並將權限連結至 eosio.prods 帳戶:
cleos push action eosio updateauth '{"account": "eosio", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@owner
cleos push action eosio updateauth '{"account": "eosio", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio.prods", "permission": "active"}}]}}' -p eosio@active
cleos get account eosio
回應內容應類似下方範例:
created: 2018-06-01T12:00:00.000
privileged: true
permissions:
owner 1: 1 eosio.prods@active
active 1: 1 eosio.prods@active
`memory:
quota: unlimited used: 2.989 MiB
net bandwidth:
used: unlimited
available: unlimited
limit: unlimited
cpu bandwidth:
used: unlimited
available: unlimited
limit: unlimited
SYS balances:
liquid: 599999509.0258 SYS
staked: 0.0000 SYS
unstaking: 0.0000 SYS
total: 599999509.0258 SYS
請注意,eosio 帳戶不再具備與 owner 和 active 權限相關聯的預設開發金鑰。現在這些權限是上層 eosio.prods@active 權限的子權限。此即為代表所有活躍區塊生產者的帳戶群組。
因此,現在 eosio 帳戶基本上是由 eosio.prods 帳戶控管。
- 註銷 eosio.* 帳戶使用的金鑰,並將權限連結至 eosio 帳戶:
cleos push action eosio updateauth '{"account": "eosio.bpay", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.bpay@owner
cleos push action eosio updateauth '{"account": "eosio.bpay", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.bpay@active
cleos push action eosio updateauth '{"account": "eosio.msig", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.msig@owner
cleos push action eosio updateauth '{"account": "eosio.msig", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.msig@active
cleos push action eosio updateauth '{"account": "eosio.names", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.names@owner
cleos push action eosio updateauth '{"account": "eosio.names", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.names@active
cleos push action eosio updateauth '{"account": "eosio.ram", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.ram@owner
cleos push action eosio updateauth '{"account": "eosio.ram", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.ram@active
cleos push action eosio updateauth '{"account": "eosio.ramfee", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.ramfee@owner
cleos push action eosio updateauth '{"account": "eosio.ramfee", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.ramfee@active
cleos push action eosio updateauth '{"account": "eosio.saving", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.saving@owner
cleos push action eosio updateauth '{"account": "eosio.saving", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.saving@active
cleos push action eosio updateauth '{"account": "eosio.stake", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.stake@owner
cleos push action eosio updateauth '{"account": "eosio.stake", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.stake@active
cleos push action eosio updateauth '{"account": "eosio.token", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.token@owner
cleos push action eosio updateauth '{"account": "eosio.token", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.token@active
cleos push action eosio updateauth '{"account": "eosio.vpay", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.vpay@owner
cleos push action eosio updateauth '{"account": "eosio.vpay", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.vpay@active
cleos push action eosio updateauth '{"account": "eosio.rex", "permission": "owner", "parent": "", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.rex@owner
cleos push action eosio updateauth '{"account": "eosio.rex", "permission": "active", "parent": "owner", "auth": {"threshold": 1, "keys": [], "waits": [], "accounts": [{"weight": 1, "permission": {"actor": "eosio", "permission": "active"}}]}}' -p eosio.rex@active
現在 eosio.* 帳戶不再具備與 owner 和 active 權限相關聯的預設開發金鑰。這些權限目前是上層 eosio@active 權限的子權限,也就是 eosio.prods@active 帳戶的子權限。
因此,現在所有系統帳戶 (包括 eosio) 基本上都由 eosio.prods 帳戶控管,該帳戶代表所有活躍區塊生產者的帳戶群組。終於,您已建構出可全面運作的多節點 EOSIO 區塊鏈!
點選「Check my progress」,確認目標已達成。
從單節點生產者轉換為多節點架構
恭喜!
在本實驗室中,您將先前部署的單節點 EOSIO 區塊鏈,擴充為多區塊鏈網路;並安裝了各種 EOSIO 軟體元件來設定多節點 EOSIO 區塊鏈。最後,您在新的 EOSIO 區塊鏈上執行了一些節點營運工作。
後續步驟/瞭解詳情
Google Cloud 教育訓練與認證
協助您瞭解如何充分運用 Google Cloud 的技術。我們的課程會介紹專業技能和最佳做法,讓您可以快速掌握要領並持續進修。我們提供從基本到進階等級的訓練課程,並有隨選、線上和虛擬課程等選項,方便您抽空參加。認證可協助您驗證及證明自己在 Google Cloud 技術方面的技能和專業知識。
使用手冊上次更新日期:2024 年 12 月 12 日
實驗室上次測試日期:2024 年 10 月 22 日
Copyright 2026 Google LLC 保留所有權利。Google 和 Google 標誌是 Google LLC 的商標,其他公司和產品名稱則有可能是其關聯公司的商標。