天天看點

Hyperledger Fabric和Composer實作區塊鍊應用程式

目前無法繞過技術領域的是區塊鍊話題。但除了加密貨币之外,還有更多有趣的應用程式可以帶來許多激動人心的軟體生态系統。這也适用于Hyperledger項目,該項目提供了一個非常子產品化的區塊鍊架構。讓我們看看使用Hyperledger Fabric和Composer實作區塊鍊應用程式是多麼容易。

關于項目Hyperledger

Hyperledger是一個umbrella項目的名稱,在該項目下開源區塊鍊方法和工具是協同開發的。它由Linux基金會于2015年推出,并享有IBM,英特爾和富士通等軟體巨頭以及大型社群的熱烈參與。Hyperledger的GitHub存儲庫目前比以往更加活躍。任何人都可以參與開發。

在Hyperledger中,不僅開發了單個區塊鍊架構(或平台)。相反,重點是并行采用多種方法,創造協同效應,可重複使用的元件和靈活性。從Hyperledger概念的角度來看,區塊鍊網絡與比特币或以太網等加密貨币的代表無法比較。相反,Hyperledger網絡的節點分布在參與組織中,這使得私有,許可或聯盟區塊鍊網絡特别有趣。首先,我們可以忘記公共區塊鍊的工作證明,股權證明和其他共識機制。所涉及的組織從應用程式業務價值和所涉及的信任中作為聯合體驗證彼此的交易和利益。這也很大程度上解決了可擴充性問題(我們從比特币網絡中了解到)并且可以實作高交易吞吐量。

Hyperledger Fabric和Composer實作區塊鍊應用程式

項目Hyperledger的不同區塊鍊方法是Fabric,Burrow,Iroha,Indy和Sawtooth。私有,許可和聯合區塊鍊可以與所有這些區塊鍊一起開發,但每種實作都遵循不同的方法。

我們将在本文中詳細介紹Fabric,因為它擁有最活躍的社群,并且是最靈活的變體。由于其強大的子產品化,fabric是普遍可用的。 “你可以将Hyperledger Fabric視為類似于Apache Web Server”,Linux基金會Hyperledger執行董事Brian Behlendorf說。其他方法更多用于在有限的環境中實施特殊情況。

Hyperledger Fabric ——靈活的區塊鍊應用平台

使用Fabric作為平台,可以開發完全獨立的分布式分類帳解決方案。Fabric包含可以盡可能自由實作的概念。區塊鍊網絡的基礎是對所需組織結構的模組化。每個參與者都有固定的身份,可以通過頒發的證書來識别自己。除了身份驗證之外,還包括授權。使用這種基于角色的系統,可以獲得許可區塊鍊中隐私和機密性的靈活方面。對于證書和參與者的管理,可以使用結構證書頒發機構(1.0版之前的成員服務提供者)。

資産的定義(要在區塊鍊上管理的項目)完全取決于區塊鍊應用程式。這些資産,例如來自汽車行業的引擎塊由JSON和/或二進制格式的鍵值對模型定義。

鍊代碼的概念旨在基于資産及其所有者實作業務邏輯。這可用于實作Go,Java或Node.js等語言中的規則,這些規則定義讀取權限或資産修改。執行鍊代碼功能可以讀取和傳回資産和/或建立和修改資産并将它們存儲在本地分類帳資料庫中。在節點上的本地持久性更改之後,将更改送出給網絡(“認可”)并在其他組織接受後插入到區塊鍊中。在以太坊或其他公共區塊鍊平台的背景下,可以将鍊碼與智能合約進行比較。

Hyperledger Fabric和Composer實作區塊鍊應用程式

通道用于實作隐私領域。在最簡單的場景中,整個鍊代碼部署在所有參與者加入的單個通道上。但是,為了建立封裝區域并僅允許標明的參與者在其中進行通信,可以配置具有受限參與者組的通道。每個通道可以部署不同的鍊代碼,進而可以實作功能隔離。此外,可以使用AES部分或完全加密通道中的通信。

結果,在每個通道中維護一個分布式分類帳,這可以被想象為連結交易的現金簿。每個參與者為他們所屬的每個通道保留一份分類帳副本。這為網絡中的每個現有信道建立了區塊鍊資料結構。與區塊鍊一樣,交易存儲在塊中,這些塊在單個連接配接清單中成為加密鍊。

但是,為了向用戶端應用程式提供分類帳資料的單獨視圖,甚至可以執行針對網絡的複雜讀取請求。由于使用了像CouchDB這樣的面向文檔的資料庫,這是可能的。這為連接配接到Fabric網絡的用戶端提供了靈活的資料通路。

使用Composer添加更簡單的概念

Hyperledger-Composer是Hyperledger生态系統中的工具之一。你可以将其視為Fabric的架構。如果你想開發,建構和管理Fabric網絡,那麼即使不是強制性的,也是實用的。它引入了基于Fabric的進一步概念,以提供精美的抽象概念。

除資産外,還可以在Composer模組化語言中定義網絡參與者,交易和事件的方案。每種交易類型的流都通過JavaScript代碼在簡單的API上實作。通路控制檔案可用于限制參與者對某些資源的通路權限。可以在Composer Query Language中定義對分類帳中資料的常用查詢,這是一種類似SQL的語言。

然後,必須将所有必需檔案打包到.bna檔案中的BND(業務網絡定義)。然後,可以将此存檔安裝在現有Fabric網絡上。BND的源代碼當然可以在我們首選的編輯器中進行本地開發和測試,是以可以通過Git進行版本控制。對于原型設計和示範目的,有Composer Playground。這提供了一個現代,清晰且直覺可用的Web界面,可通路Composer CLI的本地配置。使用Playground,你可以輕松建立,安裝,測試,編輯,導入和導出BND。

Hyperledger Fabric和Composer實作區塊鍊應用程式

在Composer Playground中,你可以以使用者友好的方式安裝,修改和測試新的業務網絡,而無需先前的樣本區塊鍊應用知識(例如車輛生命周期,汽車拍賣或農場動物跟蹤)。在設定工具之後,可以在本地完成相同的操作,這樣我們就可以在短時間玩遊戲後離開托管遊樂場。這個遊樂場非常适合使用原型驗證想法并了解底層的Composer和Fabric模型。

使用案例:引擎塊的供應鍊跟蹤

為了使用Hyperledger-Fabric和Composer實作私有區塊鍊網絡,以汽車行業的發動機組跟蹤為例。在這種情況下,有制造商和經銷商作為網絡參與者。發動機及其安裝的車輛顯示為資産。制造商和經銷商的公司被引入并被識别為網絡中的組織。

Fabric鍊代碼應提供以下功能:

  • 1.生産具有唯一序列号的發動機缸體。
  • 2.生産後将發動機缸體傳送給經銷商。
  • 3.跟蹤車輛的序列号。
  • 4.将發動機缸體安裝到注冊車輛中。

下一步是安裝所需的工具和設定項目。

開發環境設定和項目建立

首先,需要安裝文檔中列出的Fabric的所有要求。然後我們安裝Composer和Composer及其相關工具本身的要求。

然後,最好讓自己熟悉新環境。如果我們完全按照上一個連結的說明操作,則fabric-tools現在位于我們的主目錄中。通過描述的腳本,我們可以在Docker-Compose中啟動一個簡單的Fabric網絡,獲得對等管理者通路權限并停止并再次删除它。首先,我們下載下傳1.1版的Docker鏡像并啟動網絡:

export FABRIC_VERSION=hlfv11 && ./downloadFabric.sh && ./startFabric.sh
           

在網絡運作時,composer-playground web-UI可以通過

composer-playground

啟動。它使用composer-cli的所有托管配置并通路正在運作的Fabric網絡。從現在開始,我們将Fabric視為可配置的平台/基礎架構,其狀态通過合适的工具進行更改。我們不直接使用Fabric概念開發鍊代碼,權限或任何模型,因為Composer提供了更多優勢。

實施功能

現在我們在我們選擇的目錄中建立我們的BND項目。對于Yeoman(使用模闆設定項目的代碼生成器,如Maven Archtypes),有一個模闆(hyperledger-composer:businessnetwork。但是,我已經準備了一個存儲庫,我們現在也可以使用JavaScript ES6和一些很好的工具。我們應該從開始分支“初始”開始。

master

分支具有最終版本和工作版本。我們首先克隆存儲庫的初始分支。

git clone -b initial [email protected]:jverhoelen/fabric-composer-engine-supplychain.git
           

現在我們在我們選擇的編輯器中打開檔案夾。Visual Studio Code非常适合Composer,因為它具有可安裝的文法高亮擴充。稍作修改後你會發現它是一個NPM項目,是以我們從

npm install

開始安裝所有依賴項。使用

npm test

我們可以運作單元測試,使用

npm run lint

我們可以測試代碼樣式,并且使用

npm run createArchive

我們可以建立

the.bna

檔案,我們以打包格式完成業務網絡定義。讓我們馬上試試看是否一切正常。

然後我們熟悉項目結構。

lib

檔案夾包含實作交易處理器功能的JS檔案。當然,我們想測試這個業務邏輯并将我們的單元測試存儲在

test/

檔案夾中。模型定義(參與者,資産,交易等)在

models/

中。

我們想首先為所需的區塊鍊網絡模組化。為此,我們删除模型檔案的内容,并在第一行為其指定一個新的命名空間:

namespace org.acme.enginesupplychain
           

我們為參與者制造商和經銷商模組化,并使用Composer模組化語言的繼承。我們還希望每個參與者除了姓名外還有一個可選位址。我們将這些屬性放入一個概念中:

participant Member identified by memberId {
    o String memberId
    o String name
    o Address address optional
}
 
participant Manufacturer extends Member {
}
 
participant Merchant extends Member {
}
 
concept Address {
    o String country
    o String city
    o String street
    o String streetNo
}
           

然後我們介紹我們網絡的資産:引擎塊和稍後安裝引擎的汽車。在這裡,我們了解資産和參與者可以互相參考。引用始終指向任何類型的現有資源。我們以小“o”開頭的屬性總是存在于資源本身中。

asset Engine identified by engineId {
    o String engineId
    o EngineProperties data
 
    --> Manufacturer manufacturer
    --> Car currentCar optional
    --> Merchant merchant optional
}
 
asset Car identified by carId {
    o String carId
    o String legalDocumentId
}
 
concept EngineProperties {
    o String brand
    o String model
    o Double horsePower
    o Double cubicCapacity
    o Integer cylindersAmount
}
           

在對系統模組化之後,我們定義了可以在現有資産和參與者之上執行的所有可用操作。這些是交易資源。之後,我們為以下每個交易模型測試并實作基礎交易邏輯。

transaction EngineMerchantTransfer {
    --> Engine engine
    --> Merchant merchant
}
 
transaction EngineCarInstallation {
    --> Engine engine
    --> Car car
}
 
transaction EngineCreation {
    --> Manufacturer manufacturer
    o EngineProperties data
}
 
transaction CarCreation {
    o String legalIdDocument
}
           

現在我們已經定義了可能發生的事情,我們可以在送出交易時開始實作它如何影響分類帳狀态。首先,我們緻力于建立引擎資産。引擎應該以UUID格式獲得随機生成的ID,并且應該從一開始就始終屬于制造商。是以我們清空

logic.js

檔案并從頭開始。我們定義常量

modelsNamespace

和函數

uuid

,因為我們将更頻繁地需要它們。接下來是

createEngineAsset

函數。函數上方的文檔塊非常重要,以便Composer可以識别打包代碼時實作的交易類型。

/* global getAssetRegistry getFactory */
 
const modelsNamespace = 'org.acme.enginesupplychain'
function uuid() {
    const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1)
    return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`
}
 
/**
* Creation of a Engine asset triggered by physical production.
* @param {org.acme.enginesupplychain.EngineCreation} tx - the transaction to create an engine
* @transaction
*/
async function createEngineAsset(tx) { // eslint-disable-line no-unused-vars
    const engineRegistry = await getAssetRegistry(modelsNamespace + '.Engine')
    const engine = getFactory().newResource(modelsNamespace, 'Engine', uuid())
    const engineData = getFactory().newConcept(modelsNamespace, 'EngineProperties')
 
    engine.data = Object.assign(engineData, tx.data)
    engine.manufacturer = tx.manufacturer
 
    await engineRegistry.add(engine)
}
           

通過這種方式,我們還實作了其他交易類型

EngineMerchantTransfer

EngineCarInstallation

CarCreation

/**
* An engine is transfered to a merchant.
* @param {org.acme.enginesupplychain.EngineMerchantTransfer} tx - the engine transfer transaction
* @transaction
*/
async function transferEngineToMerchant(tx) { // eslint-disable-line no-unused-vars
    const engineRegistry = await getAssetRegistry(modelsNamespace + '.Engine')
    tx.engine.merchant = tx.merchant
 
    await engineRegistry.update(tx.engine)
}
 
/**
* An engine is installed in a car.
* @param {org.acme.enginesupplychain.EngineCarInstallation} tx - the engine into car installation transaction
* @transaction
*/
async function installEngineToCar(tx) { // eslint-disable-line no-unused-vars
    const engineRegistry = await getAssetRegistry(modelsNamespace + '.Engine')
    if (tx.car) {
        tx.engine.currentCar = tx.car
        await engineRegistry.update(tx.engine)
    } else {
        return Promise.reject('No target car was set on the transaction!')
    }
}
 
/**
* A car is created.
* @param {org.acme.enginesupplychain.CarCreation} tx - transaction to create a new car
* @transaction
*/
async function createCar(tx) { // eslint-disable-line no-unused-vars
    const carRegistry = await getAssetRegistry(modelsNamespace + '.Car')
    const factory = getFactory()
    const carId = uuid()
    const car = factory.newResource(modelsNamespace, 'Car', carId)
    car.legalDocumentId = tx.legalIdDocument
 
    await carRegistry.add(car)
}
           

功能本身的單元測試相對簡單,如果我們有經驗,我們不需要了解更多。隻有對此所需的對象的boostrapping仍然有點超載樣闆代碼。測試首先啟動記憶體中的Fabric網絡,在其上安裝業務網絡,然後以預設管理者身份對其進行身份驗證。因為這個Composer提供了庫

composer-admin

composer-client

composer-common

composer-connector-embedded

。在測試設定之後,我們現在可以針對嵌入式網絡編寫測試用例。由于其長度,設定代碼未包含在清單中,但可以在

test/EngineSupplychainSpec.js

中的主分支上檢視和測試。

用于測試交易類型的單元測試用例通常具有類似的模式。他們使用其屬性和關系重新建立交易,針對網絡執行交易,然後檢查所涉及的資産和參與者的資料狀态。我們來看看

createEngineAsset

的現有測試用例。

describe(‘EngineSupplychainSpec’, () => {
 
   // setup is done in the before and beforeEach hook
   // results are the bnc (BusinessNetworkConnection), target namespace
   // as well as test assets, participants and required registries
   describe('createEngineAsset', () => {
       it('should create an Engine by submitting a valid EngineCreation transaction', async () => {
           const factory = bnc.getBusinessNetwork().getFactory()
 
           const engineCreationTrans = factory.newTransaction(namespace, 'EngineCreation')
           engineCreationTrans.data = factory.newConcept(namespace, 'EngineProperties')
           engineCreationTrans.data.brand = 'Audi'
           engineCreationTrans.data.model = 'Fancy engine model'
           engineCreationTrans.data.horsePower = 400
           engineCreationTrans.data.cubicCapacity = 4000
           engineCreationTrans.data.cylindersAmount = 10
 
           const manufacturerRegistry = await bnc.getParticipantRegistry(namespace + '.Manufacturer')
           await manufacturerRegistry.addAll([])
           engineCreationTrans.manufacturer = factory.newRelationship(namespace, 'Manufacturer', testManufacturer.$identifier)
 
           await bnc.submitTransaction(engineCreationTrans)
 
           const allEngines = await engineRegistry.getAll()
           allEngines.length.should.equal(2)
       })
   })
})
           

在Hyperledger Composer中實作業務網絡定義的方法應該通過這些見解變得清晰。此外,BND可以為我們定義更多的東西。在

permissions.acl

中,你可以使用通路控制語言為給定簡單條件的參與者定義通路限制。對于許多應用程式,事件和查詢功能也非常有用和有趣。

最後,我們來看看主分支上的解決方案。所有這些要求都已在其中實施和測試。我們現在用

npm run createArchive

生成完成的

.bna

檔案,然後在

dist/

檔案夾中。我們現在可以将它導入到我們在控制台中啟動的Composer Playground中,以便在我們的本地Fabric網絡上進行嘗試。通過Web UI的方式應該是不言自明的,但它也是正式記錄的。

總結和展望

我們已經了解了Hyperledger項目的重要部分。具體來說,我們現在知道Fabric作為具有基本概念的區塊鍊平台。Composer添加了許多重要概念,使開發人員可以非常友善地實施和管理區塊鍊網絡。通過實施的關于發動機缸體生産和跟蹤的區塊鍊應用案例,我們了解了一個簡單但功能強大的私人/聯盟區塊鍊用例。

最終的區塊鍊網絡最初隻在本地執行。我們還沒有擴充同行組織和訂購服務的配置。但我們可以輕松添加更多組織并通過多個主機分發對等節點。對于由真正的組織聯盟跨越的區塊鍊網絡,我們仍然有一些問題需要解決:

我們如何管理組織和對等節點?組織如何自動将新的對等節點添加到網絡中?我們如何獲得一個可以抵禦失敗的公平和同質的網絡?客戶如何與網絡通信?

這個仍然年輕的平台已經提供了很多功能和舒适性。但是,仍有許多任務需要完成。從開發人員的角度來看,單元測試代碼看起來仍然非常臃腫。很快就會出現庫,通過它可以更容易地實作通常的測試模式。我們迫切希望看到Hyperledger等項目将如何繼續推動業務中分布式賬本技術的适應性。

故障排除

確定所有工具都與Fabric 1.1相容。這意味着必須下載下傳此版本的所有docker鏡像。應安裝最新版本的Composer和Composer Playground。目前是v0.19.1。本文中Fabric和Composer文檔的所有連結都是故意修複到Fabric 1.1和最新的Composer版本。

======================================================================

分享一些Hyperledger fabric、以太坊、比特币、EOS、Tendermint等區塊鍊相關的互動式線上程式設計實戰教程:

  • Hyperledger Fabric 區塊鍊開發詳解,本課程面向初學者,内容即包含Hyperledger Fabric的身份證書與MSP服務、權限政策、信道配置與啟動、鍊碼通信接口等核心概念,也包含Fabric網絡設計、nodejs鍊碼與應用開發的操作實踐,是Nodejs工程師學習Fabric區塊鍊開發的最佳選擇。
  • Hyperledger Fabric java 區塊鍊開發詳解,課程面向初學者,内容即包含Hyperledger Fabric的身份證書與MSP服務、權限政策、信道配置與啟動、鍊碼通信接口等核心概念,也包含Fabric網絡設計、java鍊碼與應用開發的操作實踐,是java工程師學習Fabric區塊鍊開發的最佳選擇。
  • java以太坊開發教程,主要是針對java和android程式員進行區塊鍊以太坊開發的web3j詳解。
  • python以太坊,主要是針對python工程師使用web3.py進行區塊鍊以太坊開發的詳解。
  • php以太坊,主要是介紹使用php進行智能合約開發互動,進行賬号建立、交易、轉賬、代币開發以及過濾器和交易等内容。
  • 以太坊入門教程,主要介紹智能合約與dapp應用開發,适合入門。
  • 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鍊、ipfs實作去中心化電商DApp實戰,适合進階。
  • ERC721以太坊通證明戰,課程以一個數字藝術品創作與分享DApp的實戰開發為主線,深入講解以太坊非同質化通證的概念、标準與開發方案。内容包含ERC-721标準的自主實作,講解OpenZeppelin合約代碼庫二次開發,實戰項目采用Truffle,IPFS,實作了通證以及去中心化的通證交易所。
  • C#以太坊,主要講解如何使用C#開發基于.Net的以太坊應用,包括賬戶管理、狀态與交易、智能合約開發與互動、過濾器和交易等。
  • java比特币開發教程,本課程面向初學者,内容即涵蓋比特币的核心概念,例如區塊鍊存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中內建比特币支援功能,例如建立位址、管理錢包、構造裸交易等,是Java工程師不可多得的比特币開發學習課程。
  • php比特币開發教程,本課程面向初學者,内容即涵蓋比特币的核心概念,例如區塊鍊存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中內建比特币支援功能,例如建立位址、管理錢包、構造裸交易等,是Php工程師不可多得的比特币開發學習課程。
  • c#比特币開發教程,本課程面向初學者,内容即涵蓋比特币的核心概念,例如區塊鍊存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在C#代碼中內建比特币支援功能,例如建立位址、管理錢包、構造裸交易等,是C#工程師不可多得的比特币開發學習課程。
  • EOS入門教程,本課程幫助你快速入門EOS區塊鍊去中心化應用的開發,内容涵蓋EOS工具鍊、賬戶與錢包、發行代币、智能合約開發與部署、使用代碼與智能合約互動等核心知識點,最後綜合運用各知識點完成一個便簽DApp的開發。
  • 深入淺出玩轉EOS錢包開發,本課程以手機EOS錢包的完整開發過程為主線,深入學習EOS區塊鍊應用開發,課程内容即涵蓋賬戶、計算資源、智能合約、動作與交易等EOS區塊鍊的核心概念,同時也講解如何使用eosjs和eosjs-ecc開發包通路EOS區塊鍊,以及如何在React前端應用中內建對EOS區塊鍊的支援。課程内容深入淺出,非常适合前端工程師深入學習EOS區塊鍊應用開發。
  • tendermint區塊鍊開發詳解,本課程适合希望使用tendermint進行區塊鍊開發的工程師,課程内容即包括tendermint應用開發模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀态庫等,也包括代币發行等豐富的實操代碼,是go語言工程師快速入門區塊鍊開發的最佳選擇。

彙智網原創翻譯,轉載請标明出處。這裡是原文使用Hyperledger Fabric和Composer實作區塊鍊應用程式

繼續閱讀