應(yīng)用程序開發(fā) - 應(yīng)用程序設(shè)計(jì)元素 - 交易處理程序
交易處理程序允許智能合約開發(fā)人員在應(yīng)用程序與智能合約之間的交互過程中的關(guān)鍵點(diǎn)定義通用處理。交易處理程序是可選的,但如果定義奢人,它們將在調(diào)用智能合約中的每個(gè)交易之前或之后獲得控制。還有一個(gè)特定的處理程序淹禾,在發(fā)出請(qǐng)求以調(diào)用未在智能合約中定義的交易時(shí)接收控制畔乙。
這是 商業(yè)票據(jù)智能合約示例 的交易處理程序示例:
[圖片上傳失敗...(image-8487f2-1576754636320)]
之前,之后和未知交易處理程序忙厌。在此示例中凫岖,在發(fā)行,購買和贖回交易之前調(diào)用 BeforeFunction()
逢净。在發(fā)行哥放,購買和贖回交易之后調(diào)用 AfterFunction()
。僅當(dāng)發(fā)出請(qǐng)求以調(diào)用智能合約中未定義的交易時(shí)才調(diào)用 UnknownFunction()
爹土。 (通過不為每個(gè)交易重復(fù) BeforeFunction 和 AfterFunction 框來簡化該圖甥雕。)
1. 處理程序類型
三種類型的交易處理程序涵蓋了應(yīng)用程序和智能合約之間交互的不同方面:
- Before handler:在每次智能合約交易被調(diào)用之前被調(diào)用。處理程序通常將修改交易上下文以供交易使用胀茵。處理程序可以訪問所有的 Fabric API社露。例如,它可以發(fā)出 getState() 和 putState()琼娘。
- After handler:在每次智能合約交易被調(diào)用后被調(diào)用峭弟。處理程序通常將執(zhí)行所有交易通用的后處理,并且還具有對(duì) Fabric API 的完全訪問權(quán)限轨奄。
- Unknown handler:如果嘗試調(diào)用智能合約中未定義的交易孟害,則會(huì)被調(diào)用。通常挪拟,處理程序?qū)⒂涗浌收习の瘢怨┕芾韱T進(jìn)行后續(xù)處理。處理程序具有對(duì) Fabric API 的完全訪問權(quán)限。
2. 定義處理程序
交易處理程序?qū)⒆鳛榫哂忻鞔_定義名稱的方法添加到智能合約中谎柄。這是一個(gè)添加每種類型的處理程序的示例:
CommercialPaperContract extends Contract {
...
async beforeTransaction(ctx) {
// Write the transaction ID as an informational to the console
console.info(ctx.stub.getTxID());
};
async afterTransaction(ctx, result) {
// This handler interacts with the ledger
ctx.stub.cpList.putState(...);
};
async unknownTransaction(ctx) {
// This handler throws an exception
throw new Error('Unknown transaction function');
};
}
交易處理程序定義的形式對(duì)于所有處理程序類型都是相似的丁侄,但是請(qǐng)注意afterTransaction(ctx,result)
如何也接收交易返回的任何結(jié)果朝巫。
3. 處理程序處理
將處理程序添加到智能合約后鸿摇,便可以在交易處理期間將其調(diào)用。在處理期間劈猿,處理程序接收 ctx (交易上下文)拙吉,執(zhí)行一些處理,并在完成時(shí)返回控制揪荣。處理繼續(xù)如下:
- 在處理程序之前 (Before handler):如果處理程序成功完成筷黔,則使用更新的上下文調(diào)用交易。如果處理程序引發(fā)異常仗颈,則不會(huì)調(diào)用該交易佛舱,并且智能合約將失敗,并顯示異常錯(cuò)誤消息挨决。
- 處理程序之后 (After handler):如果處理程序成功完成请祖,則智能合約將根據(jù)調(diào)用的交易完成。如果處理程序引發(fā)異常脖祈,則交易將失敗并顯示異常錯(cuò)誤消息肆捕。
- 未知的處理程序 (Unknown handler):處理程序應(yīng)通過引發(fā)帶有所需錯(cuò)誤消息的異常來完成。如果未指定 Unknown 處理程序撒犀,或者未引發(fā)異常福压,則存在明智的默認(rèn)處理;智能合約將失敗或舞,并顯示未知的交易錯(cuò)誤消息荆姆。
如果處理程序需要訪問函數(shù)和參數(shù),則很容易做到這一點(diǎn):
async beforeTransaction(ctx) {
// Retrieve details of the transaction
let txnDetails = ctx.stub.getFunctionAndParameters();
console.info(`Calling function: ${txnDetails.fcn} `);
console.info(util.format(`Function arguments : %j ${stub.getArgs()} ``);
}
4. 多個(gè)處理程序
對(duì)于智能合約映凳,最多只能為每種類型定義一個(gè)處理程序胆筒。如果智能合約需要在處理之前,之后或未知期間調(diào)用多個(gè)函數(shù)诈豌,則應(yīng)在適當(dāng)?shù)暮瘮?shù)內(nèi)進(jìn)行協(xié)調(diào)仆救。
Reference
- Docs ? Developing Applications ? Application design elements ? Transaction handlers, https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/transactionhandler.html
- Docs ? Developing Applications ? Smart Contract Processing, https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/smartcontract.html
項(xiàng)目源代碼
項(xiàng)目源代碼會(huì)逐步上傳到 Github,地址為 https://github.com/windstamp矫渔。
Contributor
- Windstamp, https://github.com/windstamp