文章目錄
- 前言
- 1. 智能合約的去中心化管理
-
- 1.1 鍊碼新的生命周期
-
- 1.1.1 鍊碼的安裝和定義
-
- 1.1.1.1 打包鍊碼
- 1.1.1.2 安裝鍊碼
- 1.1.1.3 同意鍊碼的定義
- 1.1.1.4 送出鍊碼的定義
- 1.1.2 鍊碼的更新
- 1.1.3 完整的demo
- 1.1.4 比較
- 2. private data增強
-
- 2.1 什麼是private data 集合?
- 2.2 一個demo
- 2.3 private交易流程
- 2.4 私有資料的共享
-
- 2.4.1 私有資料共享模型
- 2.4.2 私有資料執行個體
- 2.5 删除私有資料
- 2.6 私有資料集合的定義
- 3. 外部鍊碼啟動器
-
- 3.1 外部構模組化型
-
-
- `detect`:
- `build`
- `release`
- `run`
-
- 3.2 配置外部的建構器和運作器
- 4. CouchDB中使用了狀态資料庫緩存來提高性能
- 5. 基于Alpine來打包docker鏡像
- 6. Release notes
-
- 新特性
- 重要變化
- 廢除
前言
鍊碼不需要“執行個體化”,可以同時運作java和go鍊碼,同一個鍊碼多次執行個體化。
想要了解上面的特性,請看下面的分解。
Fabric 2.0 在2020年1月29号終于release了,我們來看下有哪些新的變化。
主要展現在:對新應用和隐私的支援,增強了智能合約的管理,增加了對節點的操作。
需要注意的是,隻能由fabric-1.4.x更新到2.0。
ps:在網上有個翻譯,那一字一句的翻譯,真的讓我很難受。
下面我嘗試使用自己的了解來解讀。
(ps:我是在本地寫的,導緻導入的時候,有些圖檔未能上傳,有需要看的,請移步到我的blog:https://haojunsheng.github.io/2020/02/fabric-relase-2/)
1. 智能合約的去中心化管理
fabric 2.0引入了智能合約的去中心化管理,在此之前,鍊碼的安裝和執行個體化都是一個由組織在操作,現在則發生了變化。新的鍊碼的生命周期中,隻有多個組織達成了共識,才可以和賬本才可以進行互動。
- 多個組織必須同意鍊碼的參數。在2.0之前,一個組織可以為channel中的所有成員設定鍊碼的參數(例如執行個體化鍊碼時指定的背書政策),拒絕安裝鍊碼的組織将不能參與鍊碼的調用。在2.0中,同時提供中心化的模型和去中心化的模型。
- 鍊碼的更新更加安全。在之前的鍊碼生命周期中,一個組織即可更新鍊碼。在新的版本中,需要别的組織進行同意。
- 簡化了背書政策和private data的更新。我們不必重新打包/安裝鍊碼即可更新背書政策和private data集合的配置。同時我們設定了預設的背書政策,預設的背書政策在我們增加或者删除組織的時候會自動生效。
- 打包鍊碼:會打包為tar檔案,友善進行閱讀。
- 一次打包多次複用:之前鍊碼是通過名字+版本号來決定的,現在一次打包生成多個名字,可以多次安裝(在相同或者不同的通道上)
- 不需要所有人的同意即可打包chaincode:組織可以擴充鍊碼,不需要所有人的同意,隻要符合背書要求,這些交易即可被更新到賬本中。這樣做的好處是,不需要所有人的同意,即可小規模的修改鍊碼的bug。
1.1 鍊碼新的生命周期
1.1.1 鍊碼的安裝和定義
新的鍊碼周期要求組織對鍊碼的名字,版本,背書政策達成一緻,需要執行以下四步,但不需要每個組織都執行:
- 打包鍊碼:一個或者每一個組織完成。
- 自己的節點安裝鍊碼。每個組織要執行,因為需要交易或者查詢賬本。
- 同意鍊碼的定義:需要滿足channel LifecycleEndorsment(預設是大多數)政策的足夠數量的組織來執行。
- 送出chaincode的定義:第一個收集到足夠數量的節點來執行。
下面來詳細的看上面4步:
1.1.1.1 打包鍊碼
鍊碼在安裝前需要打包為tar檔案。我們可以使用peer指令,node sdk,或者第三方工具。
第三方的打包工具需要滿足以下要求:
- 鍊碼以tar.gz結尾;
- tar檔案需要包含2個檔案(不是目錄),元檔案Chaincode-Package-Metadata.json和chaincode檔案。
- Chaincode-Package-Metadata.json檔案長成下面這樣。
-
{"Path":"fabric-samples/chaincode/fabcar/go","Type":"golang","Label":"fabcarv1"}
一個demo如下。2個組織不需要使用相同的名字。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-tgtM5BdB-1582029897382)(…/images/posts/fabric/Lifecycle-package.png)]
1.1.1.2 安裝鍊碼
每個節點上都需要安裝。強烈建議每個組織隻打包一次鍊碼,然後把該鍊碼安裝在該組織的所有節點上。如果一個channel想要保證所有的組織運作相同的鍊碼,那麼打包指令應該由一個組織來進行。
安裝成功後會傳回*MYCC_1:hash.*這樣的格式,我們需要進行儲存,友善後面的使用,如果忘記了,可以進行查詢。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-d2cqLO8D-1582029897383)(…/images/posts/fabric/Lifecycle-install.png)]
1.1.1.3 同意鍊碼的定義
我的了解是,在上面,每個組織都給chaincode起了一個名字,這樣,在實際中是無法使用的,是以現在大家來投票來确定一個統一的名字,包含下面的參數:
- 名字
- 版本:chaincode打包的時候生成的。
- Sequence:用來追蹤鍊碼的更新過程。是自增的。
- 背書政策:哪些組織可以執行可以驗證交易。
- **Collection Configuration:**私有資料相關。
- Initialization:原來chaincode的預設的init函數不執行,現在可以了。
- ESCC/VSCC Plugins
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-QjcOOW7T-1582029897383)(…/images/posts/fabric/Lifecycle-approve.png)]
1.1.1.4 送出鍊碼的定義
一旦得到了絕大多數成員的同意,就可以送出鍊碼的定義了。
我們可以使用checkcommitreadiness指令來檢查是否已經有鍊碼的定義了,首先會發送給所有的peer節點,在發送給order節點。送出必須是組織的管理者來完成的。
Channel/Application/LifecycleEndorsement來管理認可的組織的數量,預設是大多數。LifecycleEndorsement和chaincode的背書政策是分離的,沒有任何關系的。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-u1wIoDGz-1582029897384)(…/images/posts/fabric/Lifecycle-commit.png)]
即使一個組織沒有安裝鍊碼,仍然可以響應鍊碼的定義。
當鍊碼的定義被确認後,将會在所有安裝鍊碼的節點上啟動鍊碼容器。如果我們在定義鍊碼的時候要求使用init函數,那麼init函數将會被調用。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-KSkVwjYw-1582029897384)(…/images/posts/fabric/Lifecycle-start.png)]
1.1.2 鍊碼的更新
更新和安裝類似,我們既可以更新鍊碼的内容,還可以更新鍊碼的背書政策。
-
打包鍊碼。隻有在更新鍊碼内容的時候需要。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-pN4ACywl-1582029897386)(…/images/posts/fabric/Lifecycle-upgrade-package-20200217233850395.png)]
-
安裝新鍊碼。同上。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-UN0fCSd6-1582029897387)(…/images/posts/fabric/Lifecycle-upgrade-install.png)]
-
鍊碼定義投票。sequence将會自增1。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-wntCVO9Q-1582029897388)(…/images/posts/fabric/Lifecycle-upgrade-approve-20200218163958279.png)]
-
送出定義。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-wZPOieSz-1582029897388)(…/images/posts/fabric/Lifecycle-upgrade-commit.png)]
将會啟動新的鍊碼容器。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-IU1hSe4v-1582029897389)(…/images/posts/fabric/Lifecycle-upgrade-start.png)]
1.1.3 完整的demo
下面是chaincode的比較完整的操作。來自fabric-samples。
## at first we package the chaincode
packageChaincode 1
## Install chaincode on peer0.org1 and peer0.org2
echo "Installing chaincode on peer0.org1..."
installChaincode 1
echo "Install chaincode on peer0.org2..."
installChaincode 2
## query whether the chaincode is installed
queryInstalled 1
## approve the definition for org1
approveForMyOrg 1
## check whether the chaincode definition is ready to be committed
## expect org1 to have approved and org2 not to
checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": false"
checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": false"
## now approve also for org2
approveForMyOrg 2
## check whether the chaincode definition is ready to be committed
## expect them both to have approved
checkCommitReadiness 1 "\"Org1MSP\": true" "\"Org2MSP\": true"
checkCommitReadiness 2 "\"Org1MSP\": true" "\"Org2MSP\": true"
## now that we know for sure both orgs have approved, commit the definition
commitChaincodeDefinition 1 2
## query on both orgs to see that the definition committed successfully
queryCommitted 1
queryCommitted 2
## Invoke the chaincode
chaincodeInvokeInit 1 2
sleep 10
## Invoke the chaincode
chaincodeInvoke 1 2
# Query chaincode on peer0.org1
echo "Querying chaincode on peer0.org1..."
chaincodeQuery 1
下面來看圖:
加入通道:如果一個channel已經有了定義好的chaincode,那麼新加入的組織在安裝鍊碼後可以直接使用原來的名字。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-CMSQvQ3G-1582029897390)(…/images/posts/fabric/Lifecycle-join-approve.png)]
如果背書政策是預設的大多數,那麼背書政策會自動更新,把新的組織計算在内。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-2qG6GXQC-1582029897391)(…/images/posts/fabric/Lifecycle-join-start.png)]
更新背書政策
我們不必重新打包或者安裝鍊碼即可更新背書政策。channel中的成員會重新生成一個chaincode定義。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-2Z7D7LYF-1582029897391)(…/images/posts/fabric/Lifecycle-endorsement-approve.png)]
新的背書政策在新的鍊碼定義通過後,即可生效,我們不必重新開機容器即可更新背書政策。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-CKnURxDs-1582029897392)(…/images/posts/fabric/Lifecycle-endorsement-commit.png)]
無法安裝鍊碼即可同意鍊碼的定義:
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-5vaWVnNX-1582029897392)(…/images/posts/fabric/Lifecycle-no-package.png)]
不同意鍊碼定義的組織将不能使用鍊碼:
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-ueV6I1vz-1582029897393)(…/images/posts/fabric/Lifecycle-no-package-20200217235444051.png)]
上圖中的組織三不可以使用鍊碼。
channel不認可鍊碼的定義:這裡比較繞,說的是channel中的組織沒有對鍊碼的定義達成共識。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-qQxHw9xK-1582029897393)(…/images/posts/fabric/Lifecycle-majority-disagree.png)]
組織安裝了不同類型的鍊碼:這裡的意思是說隻要鍊碼産生相同的讀寫集,那麼可以安裝不同語言寫的鍊碼,比如java和go。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-woH2XOU7-1582029897394)(…/images/posts/fabric/Lifecycle-languages.png)]
一次打包,多次使用:
我們可以打包一次,給鍊碼建立不同的定義,進而運作多個智能合約執行個體(但是背書政策要有差別)。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-BsrJfrpy-1582029897394)(…/images/posts/fabric/Lifecycle-multiple.png)]
1.1.4 比較
做了個表格,把舊的聲明周期和新的進行了比較。
1.x | 2.0 | |
---|---|---|
package | 有 | 有 |
install | 有 | 有 |
approve | 無 | 有 |
commit | 無 | 有 |
instantiate | 有 | 無 |
upgrade | 有 | 有 |
2. private data增強
Fabric 2.0增強了private data,我們不需要建立私有資料集合即可使用私有資料。做了以下增強:
- 私有資料的共享和驗證。當私有資料向非原來的集合中的成員共享時,該成員可以通過GetPrivateDataHash() 函數來驗證hash是不是和鍊上儲存的hash一緻。
- 集合級别的背書政策。我們可以使用背書政策來定義私有資料集合。
- 每個組織都有暗含的私有資料集合。
2.1 什麼是private data 集合?
在同一個channel中,A組織的資料不想給其他的組織看的資料。從v1.2開始,創造了private data collections,我們可以背書,送出和查詢私有資料,在不建立一個獨立channel的情況下。
private data collections由兩部分組成:
- 實際的私有資料。在不同的節點間通過gossip協定來發送。私有資料存儲在授權的peer節點上的sidedb資料庫中,可以通過Chaincode來通路。order節點無法看到private data。注意,必須配置錨節點資訊,設定CORE_PEER_GOSSIP_EXTERNALENDPOINT變量。
- 私有資料的hash,會寫入到區塊鍊網絡中,其他人可以進行審計。
當集合中的成員需要把該私有資料向第三方共享時,第三方可以通過比較該資料的hash和鍊上儲存的hash,看是否一緻。
還有一些特殊情況,每個組織都可以建立一個私有資料集合,之後可以共享給其他成員。
我們把private data和channel進行一個比較。
- channel:所有的交易和賬本都是私密的。
- 私有資料集合:通道中組織的子集共享資料時。直接通過p2p來傳播每條具體的交易,而不是區塊,order節點無法看到真實的交易。
2.2 一個demo
有下面5個角色:
Farmer出售商品,Distributor分銷商負責把商品運到海外,Shipper負責在兩個角色之間運貨,Wholesaler批發商從distributors批發商品,Retailer零售商從shippers和wholesaler購買商品。
場景是:
- Distributor想和Farmer,Shipper共享資料,但是不想讓Retailer和wholesaler看到資料;
- Distributor賣給Retailer和wholesaler的價格不同;
- wholesaler和Retailer,Shipper之間也需要共享資料;
為了滿足上面的場景,我們不需要建立這麼多的channel,可以使用PDC。
- PDC1: Distributor, Farmer and Shipper
- PDC2: Distributor and Wholesaler
- PDC3: Wholesaler, Retailer and Shipper
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-lRHH8fyY-1582029897394)(…/images/posts/fabric/PrivateDataConcept-1.png)]
上面場景下,peer節點的賬本如下,也稱為SideDB。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Vkfx0HxF-1582029897395)(…/images/posts/fabric/PrivateDataConcept-3.png)]
2.3 private交易流程
- 用戶端發送提案給授權的背書節點,提案中加入transient 字段;
- 私有資料存儲在transient data store(臨時的存儲在peer節點);
- 背書節點發送提案響應到用戶端,響應的内容是private data的hash值;
- 用戶端節點把hash值發送給order節點;
- 在送出階段,授權的節點将會檢查政策,自己是否有權限通路private data,如果有的話,将會檢查transient data store 字段,看看是否在背書階段拿到了private data。沒有的話,會從其他節點去拉取。在驗證和送出階段,private data将會被存儲到資料庫中,同時把transient data store 删除。
2.4 私有資料的共享
我們可能會有把私有資料向其他組織或者其他集合共享的需求,接受方需要驗證hash:
- 隻要滿足背書政策(fabric 2.0中,我們可以定義鍊碼級别,鍵和集合級别的背書政策),不需要是集合中的成員,即可通路私有資料的鍵
- 我們可以使用GetPrivateDataHash()來驗證hash
在實際中,我們可能會建立大量的私有資料集合,這個不利于我們的維護。更好的情況是每個組織都是一個集合,然後共享就可以了。更好的是我們不必為此進行定義,因為在2.0中預設設定了。
2.4.1 私有資料共享模型
下面這個是每個組織一個集合的模型:
- 使用相應的公鑰來追蹤公共狀态的變化:
- 鍊碼通路控制:我們可以在鍊碼實作通路控制,指定哪些用戶端可以檢視私有資料。
- 共享私有資料:通過hash來确認;
- 和其他集合共享私有資料:
- 可以把私有資料轉移到其他的集合。這個時候會删除原來的集合。
- 在交易達成之前,可以使用私有資料進行預請求;
- 保護交易者的隐私
2.4.2 私有資料執行個體
把私有資料模型和鍊碼結合可以發揮出很大的作用,具體如下所示:
- 可以通過處于公共鍊碼狀态的UUID密鑰來跟蹤資産。僅記錄資産的所有權,關于資産的其他資訊一無所知。
- 鍊碼将要求任何轉移請求都必須來自擁有權限的客戶,并且密鑰受基于狀态的認可限制,要求所有者組織和監管機構的同級必須認可任何轉移請求。
- 資産的所有者可以看到該資産的所有交易詳情,其他的組織隻可以看到hash。
- 監管者可以保留私有資料。
具體的交易流如下所示:
- 資産所有者和買家線上下達成交易價格;
- 賣家需要證明資産的所有權。既可以線下提供私有資料的細節,也可以提供線上的憑證;
- 賣家線上驗證hash;
- 買家調用鍊碼記錄出價的細節到自己的private data中。監管者可能也需要記錄。
- 賣家調用鍊碼轉移資産,需要資産和出價細節的隐私資料,需要賣家,買家,監管者參與,除此之外,還需要滿足背書政策;
- 鍊碼會對上述資訊進行驗證;
- 賣家把公開的資料和私有資料的hash送出給order節點,打包成區塊;
- 其他節點将會驗證是否滿足背書政策,私有資料的狀态是否被其他的交易更改;
- 所有節點會進行記賬;
- 至此交易完成,其他的節點可以查詢這筆資産的公開的資訊,但無法擷取私有資訊。
2.5 删除私有資料
對于非常敏感的資料,比如政府要求的。我們可以從peer節點上徹底的删除,隻留下hash來證明該資料确實存在過。資料删除後,無法從鍊碼進行查詢,其他的peer節點也不可查詢。
2.6 私有資料集合的定義
從fabric 2.0開始,在chaincode定義階段來進行定義:
- name:集合的名字;
- policy:private data的policy必須比鍊碼的背書政策更加廣泛,因為背書節點必須有private data才可以進行背書。比如一個channel裡面包含了10個組織,5個組織需要有private data的權限,背書政策可以指定為5個中的三個;
- requiredPeerCount:在背書節點把提案響應傳回到用戶端之前,最少把private data傳遞到其他節點的數量。不建議寫0,因為這樣的話,将會導緻private data的丢失。
- maxPeerCount:如果設定為0,在背書階段,private data将不會傳播,在commit階段,資料才會傳播;
- blockToLive:私有資料的存活時間,到期自動删除。設為0表示,永不删除;
- memberOnlyRead:表示隻有授權的人可以讀。
- memberOnlyWrite:
- endorsementPolicy:
3. 外部鍊碼啟動器
我們可以使用自己喜歡的方式來建構和啟動鍊碼,不必使用docker。
- 解除了對docker daemon的依賴。之前的fabric要求peer節點可以通路到docker daemon,而這在生産環境不一定是現實的。
- 容器的替代品:我們不一定在使用容器了。
- 鍊碼作為外部的服務。之前鍊碼是被peer啟動的,現在鍊碼可以作為單獨的外部服務。
在Hyperledger Fabric 2.0之前,用于建構和啟動鍊碼的過程是peer節點實作的一部分,無法輕松自定義。必須使用特定的語言。這種方法限制了鍊碼的語言,必須依賴容器,chaincode無法作為單獨運作的服務。
從2.0開始,我們在peer的core.yaml中,加入了一個externalBuilder的配置來自定義自己的服務。
# List of directories to treat as external builders and launchers for
# chaincode. The external builder detection processing will iterate over the
# builders in the order specified below.
externalBuilders: []
# - path: /path/to/directory
# name: descriptive-builder-name
# environmentWhitelist:
# - ENVVAR_NAME_TO_PROPAGATE_FROM_PEER
# - GOPROXY
3.1 外部構模組化型
fabric的建構器使用了Heroku Buildpacks。
外部建構和運作期由下面四個部分組成:
-
: 判斷是否由我們自定義的模型來運作。bin/detect
-
: 把打包後的鍊碼變為可執行版本。用來建構,編譯鍊碼。bin/build
-
(optional): 提供chaincode的中繼資料。bin/release
-
(optional): 運作鍊碼。bin/run
下面分别是四個腳本的内容:
detect
:
detect
#!/bin/bash
CHAINCODE_METADATA_DIR="$2"
# use jq to extract the chaincode type from metadata.json and exit with
# success if the chaincode type is golang
if [ "$(jq -r .type "$CHAINCODE_METADATA_DIR/metadata.json" | tr '[:upper:]' '[:lower:]')" = "golang" ]; then
exit 0
fi
exit 1
build
build
#!/bin/bash
CHAINCODE_SOURCE_DIR="$1"
CHAINCODE_METADATA_DIR="$2"
BUILD_OUTPUT_DIR="$3"
# extract package path from metadata.json
GO_PACKAGE_PATH="$(jq -r .path "$CHAINCODE_METADATA_DIR/metadata.json")"
if [ -f "$CHAINCODE_SOURCE_DIR/src/go.mod" ]; then
cd "$CHAINCODE_SOURCE_DIR/src"
go build -v -mod=readonly -o "$BUILD_OUTPUT_DIR/chaincode" "$GO_PACKAGE_PATH"
else
GO111MODULE=off go build -v -o "$BUILD_OUTPUT_DIR/chaincode" "$GO_PACKAGE_PATH"
fi
# save statedb index metadata to provide at release
if [ -d "$CHAINCODE_SOURCE_DIR/META-INF" ]; then
cp -a "$CHAINCODE_SOURCE_DIR/META-INF" "$BUILD_OUTPUT_DIR/"
fi
release
release
#!/bin/bash
BUILD_OUTPUT_DIR="$1"
RELEASE_OUTPUT_DIR="$2"
# copy indexes from META-INF/* to the output directory
if [ -d "$BUILD_OUTPUT_DIR/META-INF" ] ; then
cp -a "$BUILD_OUTPUT_DIR/META-INF/"* "$RELEASE_OUTPUT_DIR/"
fi
run
run
BUILD_OUTPUT_DIR="$1"
RUN_METADATA_DIR="$2"
# setup the environment expected by the go chaincode shim
export CORE_CHAINCODE_ID_NAME="$(jq -r .chaincode_id "$RUN_METADATA_DIR/chaincode.json")"
export CORE_PEER_TLS_ENABLED="true"
export CORE_TLS_CLIENT_CERT_FILE="$RUN_METADATA_DIR/client.crt"
export CORE_TLS_CLIENT_KEY_FILE="$RUN_METADATA_DIR/client.key"
export CORE_PEER_TLS_ROOTCERT_FILE="$RUN_METADATA_DIR/root.crt"
export CORE_PEER_LOCALMSPID="$(jq -r .mspid "$RUN_METADATA_DIR/chaincode.json")"
# populate the key and certificate material used by the go chaincode shim
jq -r .client_cert "$RUN_METADATA_DIR/chaincode.json" > "$CORE_TLS_CLIENT_CERT_FILE"
jq -r .client_key "$RUN_METADATA_DIR/chaincode.json" > "$CORE_TLS_CLIENT_KEY_FILE"
jq -r .root_cert "$RUN_METADATA_DIR/chaincode.json" > "$CORE_PEER_TLS_ROOTCERT_FILE"
if [ -z "$(jq -r .client_cert "$RUN_METADATA_DIR/chaincode.json")" ]; then
export CORE_PEER_TLS_ENABLED="false"
fi
# exec the chaincode to replace the script with the chaincode process
exec "$BUILD_OUTPUT_DIR/chaincode" -peer.address="$(jq -r .peer_address "$ARTIFACTS/chaincode.json")"
3.2 配置外部的建構器和運作器
上面說了,這個是在core.yaml中配置的,一個demo如下所示:
chaincode:
externalBuilders:
- name: my-golang-builder
path: /builders/golang
environmentWhitelist:
- GOPROXY
- GONOPROXY
- GOSUMDB
- GONOSUMDB
- name: noop-builder
path: /builders/binary
4. CouchDB中使用了狀态資料庫緩存來提高性能
- 使用外部CouchDB狀态資料庫時,背書和驗證階段的讀取延遲曆來是性能瓶頸。
- fabric 2.0中,每個peer都進行了緩存,在core.yaml中的cacheSize來進行配置。
5. 基于Alpine來打包docker鏡像
從 v2.0 開始,Hyperledger Fabric Docker 鏡像将使用 Alpine Linux 作為基礎鏡像,這是一個面向安全的輕量級 Linux 發行版。這意味着 Docker 鏡像現在要小得多,提供更快的下載下傳和啟動時間,以及占用主機系統上更少的磁盤空間。Alpine Linux 的設計從一開始就考慮到了安全性,Alpine 發行版的最小化特性大大降低了安全漏洞的風險。
6. Release notes
新特性
**FAB-11237:**去中心化的智能合約管理
新的應用程式模式:
- FAB-10889: Implicit org-specific collections
- FAB-15066: Endorsement policies for collections
- FAB-13581: memberOnlyWrite collection configuration option
- FAB-13527: GetPrivateDataHash chaincode API
- FAB-12043: Option to include private data in block events
FAB-103: State database cache for CouchDB
重要變化
- FAB-5177: The ccenv build image no longer includes the shim
- FAB-15366: Logger removed from chaincode shim
- FAB-16213: The go chaincode entities extension has been removed
- FAB-12075: Client Identity (CID) library has moved
- FAB-14720: Support for CAR chaincode package format removed
-
FAB-15285: Support for invoking system chaincodes from user chaincodes
has been removed.
- FAB-15390: Support for peer’s Admin service has been removed.
- FAB-16303: GetHistoryForKey returns results from newest to oldest
-
FAB-16722: The ‘provisional’ genesis method of generating the system channel
for orderers has been removed.
- FAB-16477 and FAB-17116: New configuration for orderer genesismethod and genesisfile
- FAB-15343: System Chaincode Plugins have been removed.
- FAB-11096: Docker images with Alpine Linux
- FAB-11096: Bash not available in Docker images with Alpine Linux
- 使用sh或者ash
- FAB-15499: Ledger data format upgrade
- FAB-16866: Chaincode built upon installation on peer
- FAB-15837: Orderer FileLedger location moved if specified with relative path
- FAB-14271: Policies must be specified in configtx.yaml
- FAB-17000: Warn when certificates are about to expire
- FAB-16987: Go version has been updated to 1.13.4.
廢除
- FAB-15754: The ‘Solo’ consensus type is deprecated.
- FAB-16408: The ‘Kafka’ consensus type is deprecated.
-
FAB-7559: Support for specifying orderer endpoints at the global level
in channel configuration is deprecated.
- FAB-17428: Support for configtxgen flag
is deprecated.--outputAnchorPeersUpdate