Hyperledger Fabric Chaincode for Operators——實操智能合約


什么是Chaincode(智能合約)?

chaincode是一個程序,它是使用Go語言編寫的,最終在Java等其他編程語言中實現了指定的接口。chaincode運行在一個被背書peer進程獨立出來的安全的Docker容器中。chaincode通過應用程序提交的事務初始化和管理賬本狀態。

chaincode通常處理被網絡成員認可的業務邏輯,因此它被認為是一種“智能合約”。由chaincode創建的狀態只作用於該chaincode,而不能通過另一個chaincode直接訪問。但是,在同一個網絡中,給定適當的權限,chaincode可以調用另一個chaincode來訪問它的狀態。

在下面的部分中,我們將通過區塊鏈通信產品應用方案供應商諾亞的視角來探索chaincode。我們的興趣將更加關注諾亞對於chaincode生命周期的操作;在區塊鏈網絡中,打包、安裝、實例化和升級chaincode的過程,是chaincode的操作生命周期的一個功能。

 

智能合約生命周期

Hyperledger Fabric的API支持與區塊鏈網絡中的各個節點進行交互——peers、orderers和MSPs——它還允許其中一個在支持的背書節點上打包、安裝、實例化和升級chaincode。盡管Hyperledger Fabric可以用來管理chaincode的生命周期,但它還是提供了特定語言的sdk抽象了Hyperledger Fabric API的細節,以促進應用程序的開發。另外,可以通過CLI直接訪問Hyperledger Fabric API,我們將在此文檔中使用它。

 官方提供了四個命令來管理一個chaincode的生命周期: package、install、instantiate和upgrade。在未來的版本中,官方也正在考慮添加stop和start命令操作事務來禁用和重新啟用chaincode,而不必實際卸載它。在成功安裝並實例化了一個chaincode之后,chaincode就處於活躍中(正在運行),並且可以通過調用事務處理事務。在安裝完畢后,也可以在任何時間都對chaincode進行升級。

 

Packaging(包)

chaincode包由3部分組成:

  • chaincode由chaincode部署規范(ChaincodeDeploymentSpec)或CDS定義。CDS是根據代碼和其他屬性(如名稱和版本)定義了chaincode包。
  • 一個可選的實例化策略,它可以在策略上用相同的策略來描述,用於支持和在背書策略中描述。參考Hyperledger Fabric Endorsement policies——背書策略
  • 由“擁有”chaincode的實體的一組簽名。

這些簽名有以下目的:

  • 為了建立chaincode的所有權;
  • 允許對包的內容進行驗證;
  • 允許檢測包是否篡改

一個channel上的chaincode實例化事務的創建者是通過chaincode的實例化策略來驗證的。

 

創建package(包)

打包chaincode有兩種方法。一種是當想要一個chaincode擁有多個所有者時,需要使用多個身份標識為該chaincode簽名。這個工作流程需要我們首先創建一個已簽名的chaincode(一個簽署的CDS),然后通過序列的方式將其傳遞給其他所有者來簽署。

更簡單的工作流程是正在發行安裝事務的節點的身份簽名時部署已簽署的CDS。

首先將處理更復雜的情況。但是,如果不需要擔心多個所有者,那么可以跳過下面的安裝chaincode部分。

 要創建一個已簽名的chaincode包,請使用以下命令:

peer chaincode package -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 0 -s -S -i "AND('OrgA.admin')" ccpack.out

-s參數是指可以創建一個由多個所有者簽署的包,而不是簡單地創建一個未處理/修飾過的CDS。當指定了-s時,如果其他所有者需要簽名,也必須指定-s參數。否則,這個進程會創建一個除了CDS實例化策略之外的已簽署CDS。

-S參數使用在core.yaml中由localMspid屬性值標識的MSP來指示該程序的簽名。

-S參數是可選的。但是,如果一個包是在沒有簽名的情況下創建的,那么它就不能由任何其他所有者使用signpackage命令來簽署。

 -i參數是可選的,即指定chaincode實例化策略。實例化策略與背書策略具有相同的格式,並指定哪些id可以實例化chaincode。在上面的示例中,只允許使用OrgA的admin實例化鏈代碼。如果沒有提供策略,則使用默認策略,這將只允許peer中MSP的admin身份來實例化chaincode。

 

包簽名(Package signing)

一個已經被簽名的chaincode包在被創建時候可以交由其它所有者檢查並簽名,這個工作流程支持chaincode包帶外簽署。

ChaincodeDeploymentSpec視需要也許會有共同的全部所有者簽名去創建一個SignedChaincodeDeploymentSpec(或SignedCDS),SignedCDS包含了3個元素:

  1. CDS包含了chaincode的源碼、名稱和版本信息。
  2. chaincode的實例化策略,即表示背書策略。
  3. chaincode的所有者列表,以背書的方式定義。

注意:當chaincode在某些channel上實例化時,此背書策略是由帶外決定的,以提供適當的MSP原則。如果沒有指定實例化策略,則默認策略是channel的任何MSP的admin。

每個所有者通過將其與所有者的身份(例如證書)相結合,並簽署結合后的結果來為ChaincodeDeploymentSpec背書。

一個chaincode所有者可以使用下面的命令來簽署一個以前創建的簽名包:

peer chaincode signpackage ccpack.out signedccpack.out

ccpack.out和signedccpack.out分別是輸入和輸出包。signedccpack.out包含了使用本地MSP簽名的包的附加簽名。

 

安裝chaincode

安裝事務將chaincode的源代碼打包成一種指定的格式,稱為ChaincodeDeploymentSpec(chaincode部署規范或CDS),並將其安裝到運行該chaincode的peer節點上。

注意:必須在channel中的每個背書節點上安裝chaincode,以運行chaincode。

 當安裝API被簡單地給出一個ChaincodeDeploymentSpec時,它將默認實例化策略,並包含一個空的所有者列表。

 注意:chaincode只應該安裝在對chaincode擁有的成員的背書peer節點上,以保護網絡中其他成員的chaincode邏輯的機密性。那些沒有chaincode的成員,不能成為chaincode交易的背書人;也就是說,它們不能執行chaincode。但是,它們仍然可以驗證並將事務提交到賬本上。

 要安裝一個chaincode,請將一個簽署的提案發送到system chaincode(系統智能合約)其中被描述為生命周期系統智能合約( lifecycle system chaincode —— LSCC)的部分。例如,要安裝使用CLI的簡單資產chaincode中描述的sacc示例chaincode,該命令將如下所示:

peer chaincode install -n asset_mgmt -v 1.0 -p sacc

CLI容器內執行創建的SignedChaincodeDeploymentSpec sacc,並將其發送給本地peer,本地peer會調用LSCC上的安裝方法。對-p選項的參數指定了chaincode的路徑,它必須位於用戶的GOPATH的源碼樹中,例如$GOPATH/src/sacc。有關命令選項的完整描述,后面將會講到。

 要注意一點,為了在peer上安裝,簽署的提案的簽名必須來自peer的本地MSP管理員的一個簽名。

 

chaincode實例化

實例化事務調用生命周期系統chaincode(LSCC)來創建和初始化一個channel上的chaincode。這是一個chaincode-channel綁定過程:chaincode可以綁定到任意數量的channel,並分別在每個channel上獨立操作。換句話說,不管chaincode安裝和實例化了多少個其他channel,狀態都被隔離到一個事務提交的channel上。

實例化事務的創建者必須滿足在SignedCDS中包含的chaincode的實例化策略,並且該創建者作為創建該channel配置信息的一部分,也必須是channel上的一個寫入者。這對於channel的安全性來說是非常重要的,它可以防止惡意實體部署chaincode或欺騙成員在一個未綁定的channel上執行chaincode。

例如,默認的實例化策略是任何channel上的MSP管理員,因此一個chaincode實例化事務的創建者必須是channel管理員的成員。當事務提案到達背書人(節點)的時候,它將驗證創建者的簽名與實例化策略。並且在將其提交給賬本之前,在事務驗證期間再次執行此操作。

實例化事務還為channel上的chaincode設置了背書策略。背書策略描述了交易結果的認證要求,被該channel的所有成員所接受。

例如,使用CLI實例化sacc chaincode,並使用john和0初始化狀態,命令將如下所示:

peer chaincode instantiate -n sacc -v 1.0 -c '{"Args":["john","0"]}' -P "OR ('Org1.member','Org2.member')"

注意:簽注策略(CLI使用波蘭表示法),它需要來自Org1或Org2的任意成員的支持,以支持所有的事務到sacc。也就是說,無論是Org1或Org2都必須簽署在sacc上執行調用的結果,以使事務是有效的。

【波蘭表示法(Polish notation,或波蘭記法),是一種邏輯、算術和代數表示方法,其特點是操作符置於操作數的前面,因此也稱做前綴表示法。如果操作符的元數(arity)是固定的,則語法上不需要括號仍然能被無歧義地解析。波蘭記法是波蘭數學家揚·武卡謝維奇1920年代引入的,用於簡化命題邏輯。】

 在chaincode成功實例化之后,chaincode在channel上進入活躍狀態,並准備處理任何背書事務類型支持的事務協議。這些事務是並發處理的,因為它們到達了背書peer。

 

chaincode升級

任何時候,chaincode都可以通過更改其版本來進行升級,這是SignedCDS的一部分。其他部分,例如所有者和實例化策略是可選的。但是,chaincode的名稱必須是相同的,否則,它將被視為完全不同的chaincode。

在升級之前,必須將chaincode的新版本安裝在需要的背書peer上。升級是一個類似於實例化事務的事務,它將chaincode的新版本綁定到channel。其他channels所綁定的舊版本chaincode將會繼續運行舊版本chaincode換句話說,升級事務只會一次影響一個channel,即提交事務的channel。

注意:由於chaincode的多個版本可能同時處於活躍狀態,所以升級過程不會自動刪除舊版本,因此用戶必須暫時管理這個版本。

與實例化事務有一個微妙的區別:升級事務是根據當前的chaincode實例化策略檢查的,而不是新策略(如果指定的話)。這是為了確保在當前的實例化策略中指定的現有成員可以升級chaincode。

注意:在升級過程中,調用chaincode Init函數來執行任何與數據相關的更新或重新初始化它,因此在升級chaincode時必須注意避免重新設置狀態。

 

停止和啟動chaincode

注意,停止和啟動生命周期事務還沒有實現。但是,可以通過從每個背書人中刪除chaincode容器和SignedCDS包來手動停止chaincode。這是通過在背書peer節點運行的每個主機或虛擬機上刪除chaincode的容器來完成的,然后從每個背書peer節點上刪除SignedCDS。

TODO-為了從peer節點刪除CDS,首先需要進入peer節點的容器。我們確實需要提供一個能夠執行此功能的實用程序腳本。

docker rm -f <container id>
rm /var/hyperledger/production/chaincodes/<ccname>:<ccversion>

Stop在工作流程中是有用的,可以在控制方式上進行升級,在進行升級之前,可以在所有peer上停止一個chaincode。

 

CLI(客戶端)

官方正在評估為Hyperledger Fabric peer二進制文件分發特定平台的二進制文件的需求。目前,可以簡單地從運行的docker容器中調用命令。

 要查看當前可用的CLI命令,請在運行的fabric-peer Docker容器中執行以下命令:

docker run -it hyperledger/fabric-peer bash
# peer chaincode --help

注意:可使用docker exec -it cli(容器名) bash命令進入cli

這顯示了與下面示例相似的輸出:

Usage:
  peer chaincode [command]

Available Commands:
  install     Package the specified chaincode into a deployment spec and save it on the peer's path.
  instantiate Deploy the specified chaincode to the network.
  invoke      Invoke the specified chaincode.
  list        Get the instantiated chaincodes on a channel or installed chaincodes on a peer.
  package     Package the specified chaincode into a deployment spec.
  query       Query using the specified chaincode.
  signpackage Sign the specified chaincode package
  upgrade     Upgrade chaincode.

Flags:
    --cafile string      Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
-h, --help               help for chaincode
-o, --orderer string     Ordering service endpoint
    --tls                Use TLS when communicating with the orderer endpoint
    --transient string   Transient map of arguments in JSON encoding

全局flags:--logging-level string

默認的日志記錄level和overrides,參見core.yaml的完整語法。

–test.coverprofile string Done (default “coverage.cov”)

-v, –version

使用“peer chaincode [command] –help”獲取更多關於命令的信息。

為了方便在腳本化的應用程序中使用,peer命令總是在發生命令失敗時生成非零返回代碼。

chaincode命令的例子:

peer chaincode install -n mycc -v 0 -p path/to/my/chaincode/v0
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a", "b", "c"]}' -C mychannel
peer chaincode install -n mycc -v 1 -p path/to/my/chaincode/v1
peer chaincode upgrade -n mycc -v 1 -c '{"Args":["d", "e", "f"]}' -C mychannel
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","e"]}'
peer chaincode invoke -o orderer.example.com:7050  --tls --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'

 

系統智能合約(System chaincode)

系統chaincode具有相同的編程模型,除了它在peer進程中運行,而不是像普通的chaincode那樣在一個單獨的容器中運行。因此,系統chaincode被構建到peer的可執行文件中,並且不遵循上面描述的相同的生命周期。特別是安裝、實例化和升級並不適用於系統chaincode。

系統chaincode的目的是為了在peer和chaincode之間減少gRPC的通信成本,並權衡管理的靈活性。例如,系統chaincode只能用peer二進制進行升級。它還必須注冊一個固定的參數集,並且沒有背書策略或背書策略功能。

系統chaincode用於Hyperledger Fabric以實現許多系統行為,使它們可以被系統集成商所取代或修改。

當前的系統chaincode列表:

  1. LSCC( Lifecycle system chaincode ):生命周期系統chaincode處理上面描述的生命周期請求。
  2. CSCC(Configuration system chaincode):配置系統chaincode在peer端處理channel配置。
  3. QSCC(Query system chaincode):查詢系統chaincode提供了分類查詢api,例如獲取塊和事務。
  4. ESCC(Endorsement system chaincode):背書系統chaincode通過簽署事務提案響應來處理支持。
  5. VSCC(Validation system chaincode):驗證系統chaincode處理事務驗證,包括檢查背書策略和多版本並發控制。

在修改或替換這些系統chaincode時必須注意,特別是LSCC、ESCC和VSCC,因為它們在主事務執行路徑中。值得注意的是,當VSCC在將其提交到賬本之前驗證一個塊,重要的是,channel中的所有peer節點都要計算相同的驗證,以避免賬本差異(非確定性)。因此,如果VSCC被修改或替換,就需要特別的處理和維護。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM