Hyperledger Besu Onchain Permission 操作方法解析

Besu 聯盟治理的基本元件

李彥寬 Kevin Lee
BSOS Taiwan
17 min readJun 18, 2020

--

前言

之前兩篇 Hyperledger Besu 系列文,我們詳細說明了 Besu 的 privacy 的實作方法:

除了 privacy 之外,permission 也是企業以太坊 (Enterprise Ethereum) 的重要議題之一。在 Ethereum 公有鏈上,任何人皆可透過帳號 (account) 對節點 (node) 操作並發出交易;而許可制架構的企業以太坊,則需通過認證才可加入聯盟鏈節點,且只有被許可的帳號能操作區塊鏈,這便是 permission。EEA 針對 permission 的框架定義如下:

For Enterprise Ethereum, permissioning refers to the ability of a node to join an Enterprise Ethereum blockchain, and the ability of individual accounts or nodes to perform specific functions.

從這一段敘述,我們可以了解到,EEA 認為 permission 應該包含「節點准入」及「帳號准入」兩種層級。目前支援 permission 的企業以太坊包含 QuorumBesuAutonity

不同的應用情境會需要不同強度的聯盟治理方式,Besu 提供了 permission 智能合約模組,讓聯盟更有彈性設計節點與帳號的治理。接下來,我們將深度解析其操作方法。

節點許可與帳號許可

Besu 遵守 EEA 規範,實作節點與帳號的 permission,可參考官網。Besu 採用正面表列的白名單,分別實作節點與帳號的權限控管:

  • Besu permission 建構初始時存在一個 admin account,只有 admin 有權限把節點與帳號加入或移出白名單。
  • 對於節點,必須在白名單中才能加入聯盟鏈。
  • 對於帳號,必須在白名單中才能操作區塊鏈。
  • Admin 可將其他 account 或是合約 (contract) 加入或移出 admin list

節點許可

Besu 提供如 ibft2 等拜占庭容錯的共識機制,但若作惡節點超過全網 1/3 時,便無法達成共識。為了降低節點作惡造成的風險,只有被許可的節點,才能加入聯盟。在 Besu permission 架構中,只有 admin 帳號有權限將節點加入或移出白名單。

帳號許可

就算聯盟中所有節點都不作惡,鏈上還是有可能存在壞人。例如透過聯盟鏈不需手續費 (gas) 的特性,透過殭屍帳號故意發出巨量交易,造成網路塞車。透過帳號許可,只有白名單中的帳號可操作區塊鏈,可防止帳號的惡意行為,並藉由身份審查綁定帳號的鏈下身份,實做鏈上實名交易。帳號許可包含以下功能:

  • 強制要求帳號身份審查,通過審查方可加入白名單
  • 暫停特定帳號
  • 設定帳號黑名單
  • 限制帳號可以執行的操作

與節點許可相同,只有 admin 帳號可將其他帳號加入或移出白名單,及進行帳號權限設定。

Local 與 Onchain 兩種作法

Besu 提供 local (off-chain) 與 onchain 兩種層級的 permission 實現方式,皆可對節點與帳號做許可控管。

Local permission 的作法只作用在單一節點,於鏈下作業。Besu 中的每個節點都有一個權限配置設定檔,此設定檔定義了該節點的節點與帳號白名單。Besu API 中提及的 perm 相關 API 可針對 local permission 操作;

permissions_config.toml 設定檔,可參考官網,格式如下:

accounts-whitelist=["0x18af5bfa9222e79fb2793a2008ed0b3c8e900999"]
nodes-whitelist=["enode://0fd7b7570bd37eb0bb21dabe543a811b8d4bb886af44db79e1990a1e5bc55c4ab9d42293dbcb550935ba5cde7d596176781301ce87d995159cc8537acc0a40f5@34.74.191.37:60606","enode://8b417b77f371836458da853d7e33241ee0f1e379e28045ac7adaeca2697b64bfa7b4cadcd5c8da6f5b39c1b503f4253a0c7f35643cef08b1aaf301b50995971c@34.73.199.100:60606"]

Onchain permission 的做法作用在整個聯盟鏈,透過智能合約進行節點與帳號的許可控管,聯盟鏈的所有節點使用相同規則,於鏈上作業。節點透過智能合約讀取規則, 並且鏈上的交易在 transaction pool validation 階段確認是否符合 permission 規則,符合規則的交易才可成功執行。

下圖說明 local 與 onchain 兩種許可機制,在發送交易的過程中權限驗證的流程。Local permission 讀取節點設定檔,符合許可規則才上鏈;Onchain permission 則在上鏈階段讀取智能合約,符合許可規則才能成功上鏈。

Local permission 由單一節點透過設定檔,限制連線對象與帳號的使用權限,不會影響到聯盟鏈中的其他節點,使用上非常單純。Onchain permission 則是一個鏈上的規則,此規則由智能合約定義,聯盟鏈中的所有節點皆需遵守。

因為只有 onchain permission 的作法能做到整體聯盟的許可治理,因此本文接下來將著重 Besu onchain permission 的探討。

Besu permission 環境

首先,我們必須建立一個 Besu permission 的環境,建立完成後可透過 Metamask (區塊鏈錢包 app,可連接區塊鏈做簡單操作) 連接 Besu,確認區塊鏈是否正常運行。前兩篇系列文已介紹過 Besu privacy 的環境建置,而 permission 的環境一樣可以參考 besu-sample-networks 專案

$ git clone https://github.com/PegaSysEng/besu-sample-networks
$ cd besu-sample-networks
$ ./run-permissioning.sh

besu-sample-networks 專案另外提供 Dapp 輔助操作 permission 相關的智能合約,可透過 script 安裝:

$ ./run-permissioning-dapp.sh

經過一段時間執行後,終端畫面會顯示發佈多張智能合約,完成後便可操作 permission Dapp。Metamask 自訂 RPC,填入 Besu 連線資訊後,匯入範例中的帳號:0x627306090abaB3A6e1400e9345bC60c78a8BEf57

在瀏覽器中輸入 http://ip:3001

如此一來,一套許可制的 Besu 環境便設定完成!詳細流程可參考 Pegasys 放在 Youtube 上的教學影片

Besu Permission Dapp

上一段我們成功建立一套 Besu permission 環境,並運行一個簡單的 Dapp,本段將說明如何操作這個範例 Dapp。

從 Dapp 畫面我們看到有三個標籤

  • Whitelisted Accounts
  • Whitelisted Nodes
  • Admins

Admins 是一個 account list,身為 admin 的帳號才可操作 permission 相關的智能合約。第一個 admin 在部署 permission 智能合約時需指定,本範例使用前面匯入 Metamask 的帳號:0x627306090abaB3A6e1400e9345bC60c78a8BEf57 作為 admin。

Admin 帳號可在 Whitelisted Node 與 Whitelisted Account 中加入聯盟的白名單中,或從白名單移除。不在白名單的 node 無法 addPeer 加入該聯盟;不在白名單的 account 無法對節點做上鏈操作,透過 Metamask 交易無法成功執行:

Besu Onchain Permission 智能合約深度解析

雖然 Besu 提供 Dapp 幫助使用者了解 onchain permission 的輪廓,但這樣的基本範例是無法達到企業級應用需求的。為了更高的可用性、安全性,以及擴展性,我們需將 Besu onchain permission smart contracts 模組化,以利嵌入企業級的應用架構。我們將帶讀者揭開 permission 智能合約的神秘面紗。

Besu permission 智能合約可分成三大類:

  • Admin
  • Account
  • Node

如同 Dapp 展示,只有 Admin 中的帳號可操作 AccountNode 的智能合約,而聯盟鏈中節點與帳號的規則分別定義在 NodeAccount 中。目前 Pegasys 官方推出 16 支 permission 智能合約中,有 5 支關鍵合約提供使用者調用:

  • AccountIngress.sol
  • NodeIngress.sol
  • AccountRules.sol
  • NodeRules.sol
  • Admin.sol

當中 AccountIngress.sol 與 NodeIngress.sol 兩支智能合約屬於 “入口合約”,被放在區塊鏈的創世區塊,Besu 系統透過這兩個入口驗證使用者操作是否符合聯盟規則。從 besu-sample-networks 專案中,我們找到 permission 的創世區塊 config/besu/ibft2GenesisPermissioning.json,有兩個 permission 合約:

  • 0x8888:AccountIngress.sol,account permission 入口合約。
  • 0x9999:NodeIngress.sol,node permission 入口合約。

其餘三支合約在 Besu permission 系統建置時會分別部署,並將合約資訊綁定入口合約,透過 setContractAddress function 將 admin 與 rules 寫入。AccountIngress 綁定一張 Admin 與一張 AccountRules;NodeIngress 綁定一張 Admin 與一張 NodeRules。五支智能合約在系統中配置如下:

實際操作上,我們會從入口合約找到對應的 admin 與 rules 合約資訊,並使用 admin 帳號操作 rules 合約。接著,我們將詳細說明所有可操作的合約功能 (functions)。

透過 Remix 操作 Permission 合約

以下我們使用 Remix IDE 搭配 Metamask 來觀察並操作合約功能。

1. 需要先將 Remix 的 Deploy & run transactions 設為 Active

2. 設定區塊鏈連線,選擇 Injected Web3,Remix 會與 Metamask 綁定,便可操作 Besu 上的智能合約。

3. 將 permission 合約匯入 Remix

4. 我們利用 Remix 來觀察合約操作。編譯 AccountIngress.sol 後填入合約地址 0x8888:

  • 兩個 write function,作用是將 admin 與 rules 寫入合約或從合約移除
  • ADMIN_CONTRACT 會回傳 “admin” 字串的 bytes32 hex string
  • RULES_CONTRACT 會回傳 “rules” 字串的 bytes32 hex string
  • getContractAddress 會回傳掛載的 admin 或是 rules contract address,以下範例找出 rules 的合約地址

透過入口合約找到 rules 後,我們根據找到的 rules contract address 來做觀察。先選擇 AccountRules.sol,編譯後填入合約地址 0xEcFcaB0A285d3380E488A39B4BB21e777f8A4EaC:

  • 從合約的 modifier 看出,只有 AccountIngress 綁定的 admin 才可以操作 write function:
modifier onlyAdmin() {
address adminContractAddress = ingressContract.getContractAddress(ingressContract.ADMIN_CONTRACT());
require(adminContractAddress != address(0), "Ingress contract must have Admin contract registered");
require(Admin(adminContractAddress).isAuthorized(msg.sender), "Sender not authorized");
_;
}
  • AccountRules 有以下 write function 提供操作
- addAccount:加入帳號到白名單
- addAccounts:加入多個帳號到白名單
- enterReadOnly:讓白名單成員只有讀取權限
- exitReadOnly:歸還白名單成員寫入權限
- removeAccount:將帳號移出白名單
  • AccountRules 有以下 read function
- accountInWhitelist:回傳帳號是否在白名單中
- getAccounts:回傳所有白名單中的帳號
- getByIndex 與 whitelist 相同,回傳 whitelist[index] 的 account 值
- getContractVersion:回傳 AccountIngress 綁定 AccountRules 的版本
- getSize:回傳白名單中帳號數量
- isReadOnly:回傳是否為僅讀取模式

5. 透過相同方式,我們也可以找出 NodeIngress、NodeRules 與 Admin 的操作列表

0x9999 NodeIngress
NodeRules
Admin

以上說明了 Besu permission 相關的智能合約,其實合約功能並不複雜,主要針對 admin、account 與 node 的 CRD 操作。只不過,如何利用這些合約模組,設計出符合實際場景需求的聯盟治理方案,才是真正的難題。

結語

Besu 符合 EEA 的規範,具備節點與帳號的許可規則,並提供 local 與 onchain 兩種層級的作法。本文著重於 onchain permission 的智能合約剖析。除了展示官方提供的環境建置與 Dapp 外,也透過 Remix 詳細說明了 permission 智能合約的 CRD 操作。

Besu 提供了一套良好的 onchain permission smart contracts 與可展示的 Dapp,但這些只是最基礎的功能元件,距離搭建企業級的聯盟治理還有很長的一段路需要走。例如 privacy 與 permission 在設計上如何融合搭配,以滿足商業數據控管的需求? admin 如何透過投票等共識行為來產生(原生是採中央極權)?Account 被加入白名單時,如何綁定帳號對應的鏈下身份?這些都是企業導入聯盟鏈真實必須面對的議題。關於這些議題,請容 BSOS 留待「企業區塊鏈導入」系列文章再行探討。

Hyperledger Besu 系列文三部曲在此暫告一段落,如果你原本就熟悉 Ethereum,相信看完這三部曲之後,你就能夠實際架設 Besu,並很快展開 Dapp 的實作;此外,除了了解 Besu 的實作方法,我們更期待開發者朋友們看完這三篇系列文,也和我們一樣,發現現有聯盟鏈技術仍然有不足之處,有待我們一起努力、共同解決。筆者任職的 BSOS 是專注在聯盟鏈及企業應用的區塊鏈公司,我們與國際區塊鏈組織接軌,不斷創造更進步的技術解決方案最佳導入實務,希望能實現更公平、高效且非中心壟斷的價值互聯網!

參考資料

https://medium.com/bsos-taiwan/how-to-create-besu-private-raw-transaction-13a651637fc7
https://medium.com/bsos-taiwan/how-to-use-besu-private-smart-contract-51e33c5b6d62
https://entethalliance.github.io/client-spec/spec.html#dfn-permission
https://besu.hyperledger.org/en/stable/Concepts/Permissioning/Permissioning-Overview/
https://besu.hyperledger.org/en/stable/Tutorials/Permissioning/Create-Permissioned-Network/
https://besu.hyperledger.org/en/stable/Reference/API-Methods/
https://github.com/PegaSysEng/besu-sample-networks
https://www.youtube.com/watch?v=MhOJKOoEZQQ
https://github.com/PegaSysEng/permissioning-smart-contracts/tree/master/contracts

--

--

李彥寬 Kevin Lee
BSOS Taiwan

BSOS Senior Backend Engineer. Capable of working with blockchain, big data, distributed computing, decentralized storage, and managing databases.