受眾:架構師,應用程序和智能合約開發人員
應用程序可以通過將交易提交到分類賬或查詢分類賬內容來與區塊鏈網絡進行交互。本主題涵蓋了應用程序如何執行此操作的機制。在我們的方案中,組織使用調用商業票據智能合約中定義的發行,購買和贖回交易的應用程序訪問PaperNet 。盡管MagnetoCorp發行商業票據的申請是基本的,但它涵蓋了所有主要的理解要點。
在本主題中,我們將介紹:
為了幫助您理解,我們將參考Hyperledger Fabric隨附的商業紙樣應用程序。您可以下載它并在本地運行它。它是用JavaScript和Java編寫的,但是邏輯是完全獨立于語言的,因此您可以輕松地看到發生了什么!(該示例也將適用于Go。)
基本流程
應用程序使用Fabric SDK與區塊鏈網絡進行交互。這是應用程序如何調用商業票據智能合約的簡化圖:
PaperNet應用程序調用商業票據智能合約以提交發行交易請求。
申請必須遵循六個基本步驟才能提交交易:
- 從錢包中選擇一個身份
- 連接到網關
- 訪問所需的網絡
- 構建智能合約的交易請求
- 將交易提交到網絡
- 處理回應
您將看到典型的應用程序如何使用Fabric SDK執行這六個步驟。您將在issue.js
文件中找到應用程序代碼。 在瀏覽器中查看它,如果已下載,則在您喜歡的編輯器中將其打開。花一些時間查看應用程序的整體結構;即使有注釋和空格,也只有100行代碼!
錢包
在的頂部issue.js
,您將看到兩個Fabric類進入了作用域:
const { FileSystemWallet, Gateway } = require('fabric-network');
您可以fabric-network
在node SDK文檔中閱讀有關這些類的 信息,但是現在,讓我們看看如何使用它們將MagnetoCorp的應用程序連接到PaperNet。該應用程序使用Fabric Wallet類,如下所示:
const wallet = new FileSystemWallet('../identity/user/isabella/wallet');
查看如何在本地文件系統中wallet
找到錢包。從錢包中檢索到的身份顯然適用于正在使用該issue
應用程序的名為Isabella的用戶。錢包包含一組身份(X.509數字證書),可用于訪問PaperNet或任何其他Fabric網絡。如果您運行本教程,并查看此目錄,則將看到Isabella的身份憑證。
想象一下一個錢包,里面裝有政府身份證,駕駛執照或ATM卡的數字等效物。其中的X.509數字證書將使持有者與組織相關聯,從而使他們具有網絡通道中的權利。例如,Isabella
可能是MagnetoCorp的管理員,這可能給她比Balaji
來自DigiBank 的其他用戶更多的特權。此外,智能合約可以使用交易上下文在智能合約處理期間檢索此身份。
還要注意,錢包不持有任何形式的現金或代幣-它們持有身份。
網關
第二個關鍵類是結構網關。最重要的是, 網關標識一個或多個提供對網絡訪問權限的對等點-在我們的示例中為PaperNet。查看如何issue.js
連接到其網關:
await gateway.connect(connectionProfile, connectionOptions);
gateway.connect()
有兩個重要參數:
- connectionProfile:連接配置文件的文件系統位置,該 連接配置文件將一組對等方標識為PaperNet的網關
-
connectionOptions:一組用于控制
issue.js
與PaperNet交互方式的選項
了解客戶端應用程序如何使用網關將自身與網絡拓撲隔離,這可能會發生變化。網關負責使用連接配置文件和連接選項將交易建議發送到網絡中正確的對等節點 。
花一些時間檢查連接 配置文件 ./gateway/connectionProfile.yaml
。它使用 YAML,使其易于閱讀。
它已加載并轉換為JSON對象:
let connectionProfile = yaml.safeLoad(file.readFileSync('./gateway/connectionProfile.yaml', 'utf8'));
目前,我們僅對個人資料的channels:
和peers:
部分感興趣:(我們對細節進行了一些修改,以更好地解釋發生了什么。)
channels:
papernet:
peers:
peer1.magnetocorp.com:
endorsingPeer: true
eventSource: true
peer2.digibank.com:
endorsingPeer: true
eventSource: true
peers:
peer1.magnetocorp.com:
url: grpcs://localhost:7051
grpcOptions:
ssl-target-name-override: peer1.magnetocorp.com
request-timeout: 120
tlsCACerts:
path: certificates/magnetocorp/magnetocorp.com-cert.pem
peer2.digibank.com:
url: grpcs://localhost:8051
grpcOptions:
ssl-target-name-override: peer1.digibank.com
tlsCACerts:
path: certificates/digibank/digibank.com-cert.pem
了解如何channel:
識別PaperNet:
網絡通道及其兩個對等端。MagnetoCorp peer1.magenetocorp.com
和DigiBank具有 peer2.digibank.com
,兩者都具有對同伴的支持作用。通過peers:
密鑰鏈接到這些對等設備,該密鑰包含有關如何連接到它們的詳細信息,包括它們各自的網絡地址。
連接配置文件包含很多信息-不僅包括對等信息-而且還包含網絡通道,網絡訂購者,組織和CA,因此如果您不了解所有信息,請不要擔心!
現在讓我們將注意力轉向該connectionOptions
對象:
let connectionOptions = {
identity: userName,
wallet: wallet
}
了解如何指定標識userName
和錢包wallet
用于連接網關。這些是在代碼的前面分配的值。
應用程序還可以使用其他連接選項來指示SDK代表其智能操作。例如:
let connectionOptions = {
identity: userName,
wallet: wallet,
eventHandlerOptions: {
commitTimeout: 100,
strategy: EventStrategies.MSPID_SCOPE_ANYFORTX
},
}
在這里,commitTimeout
告訴SDK等待100秒以了解事務是否已提交。并指定SDK可以在單個MagnetoCorp對等方確認交易后通知應用程序,而相反,這要求MagnetoCorp和DigiBank的所有對等方確認交易。strategy: EventStrategies.MSPID_SCOPE_ANYFORTX``strategy: EventStrategies.NETWORK_SCOPE_ALLFORTX
如果您愿意,請閱讀更多有關連接選項如何允許應用程序指定面向目標的行為的信息,而不必擔心如何實現。
網絡渠道
在網關上定義的同齡人connectionProfile.yaml
提供 issue.js
與接入PaperNet。因為這些對等方可以加入多個網絡通道,所以網關實際上為應用程序提供了對多個網絡通道的訪問權限!
查看應用程序如何選擇特定頻道:
const network = await gateway.getNetwork('PaperNet');
從那時起,network
將提供對PaperNet的訪問。此外,如果應用程序要同時訪問另一個網絡BondNet
,則很容易:
const network2 = await gateway.getNetwork('BondNet');
現在我們的應用程序可以訪問到第二網絡,BondNet
同時有PaperNet
!
我們可以在這里看到Hyperledger面料的強大的功能-應用程序可以參加一個在網絡的網絡,通過連接到多個網關同行,每一個連接到多個網絡渠道。根據中提供的錢包身份,應用程序將在不同渠道中擁有不同的權利gateway.connect()
。
構造要求
該應用程序現在準備發布商業票據。為此,它將CommercialPaperContract
再次使用,訪問此智能合約相當簡單:
const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');
注意應用程序如何提供名稱papercontract
–和明確的合同名稱:org.papernet.commercialpaper
!我們將看到合同名稱如何從papercontract.js
包含許多合同的鏈碼文件中挑選出一個合同。在PaperNet中,papercontract.js
已使用名稱安裝并實例化了名稱papercontract
,如果您有興趣,請閱讀如何安裝和實例化包含多個智能合約的鏈碼。
如果我們的應用程序同時需要訪問PaperNet或BondNet中的另一個合同,這將很容易:
const euroContract = await network.getContract('EuroCommercialPaperContract');
const bondContract = await network2.getContract('BondContract');
在這些示例中,請注意我們如何不使用合格合同名稱-每個文件只有一個智能合同,并且getContract()
將使用找到的第一個合同。
回顧一下MagnetoCorp發行第一張商業票據所使用的交易:
Txn = issue
Issuer = MagnetoCorp
Paper = 00001
Issue time = 31 May 2020 09:00:00 EST
Maturity date = 30 November 2020
Face value = 5M USD
現在讓我們將此交易提交給PaperNet!
提交交易
提交交易是對SDK的單一方法調用:
const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');
查看submitTransaction()
參數如何與事務請求的參數匹配。這些值將傳遞給issue()
智能合約中的方法,并用于創建新的商業票據。回顧其簽名:
async issue(ctx, issuer, paperNumber, issueDateTime, maturityDateTime, faceValue) {...}
在應用程序發布后不久,智能合約可能會收到控制權submitTransaction()
,但事實并非如此。在幕后,SDK使用connectionOptions
和connectionProfile
詳細信息將交易建議發送到網絡中正確的對等方,在這里它可以獲取所需的認可。但是,應用程序無需擔心所有這些問題submitTransaction
,它只需要發布就可以了,SDK會處理一切!
請注意,submitTransaction
API包含用于偵聽事務提交的過程。需要偵聽提交,因為沒有提交,您將不知道您的交易是否已成功排序,驗證并提交到分類賬。
現在讓我們將注意力轉移到應用程序如何處理響應上!
流程響應
回想一下發行交易papercontract.js
如何返回商業票據響應:
return paper.toBuffer();
您會注意到一個小怪癖–新的新數據paper
需要在返回到應用程序之前轉換為緩沖區。請注意,如何issue.js
使用類方法CommercialPaper.fromBuffer()
為響應緩沖紙補充水分,作為商業論文:
let paper = CommercialPaper.fromBuffer(issueResponse);
這允許paper
在描述性完成消息中以自然的方式使用:
console.log(`${paper.issuer} commercial paper : ${paper.paperNumber} successfully issued for value ${paper.faceValue}`);
了解paper
在應用程序合約和智能合約中如何使用相同的類–如果您像這樣構造代碼,它將真正幫助提高可讀性和重用性。
與交易建議一樣,智能合約完成后,應用程序似乎很快就會收到控制權,但事實并非如此。在幕后,SDK管理整個共識過程,并根據strategy
connectionOption 通知應用程序完成。如果您對SDK的幕后操作感興趣,請閱讀詳細的 交易流程。
而已!在本主題中,您已經了解了如何通過檢查MagnetoCorp的應用程序如何在PaperNet中發布新的商業論文來從示例應用程序中調用智能合約。現在,檢查關鍵分類賬和智能合約數據結構是根據其背后的體系結構主題設計的。