github.com/kaituanwang/hyperledger@v2.0.1+incompatible/docs/source/developapps/transactionhandler.md (about) 1 # Transaction handlers 2 3 **Audience**: Architects, Application and smart contract developers 4 5 Transaction handlers allow smart contract developers to define common processing 6 at key points during the interaction between an application and a smart 7 contract. Transaction handlers are optional but, if defined, they will receive 8 control before or after every transaction in a smart contract is invoked. There 9 is also a specific handler which receives control when a request is made to 10 invoke a transaction not defined in a smart contract. 11 12 Here's an example of transaction handlers for the [commercial paper smart 13 contract sample](./smartcontract.html): 14 15 ![develop.transactionhandler](./develop.diagram.2.png) 16 17 *Before, After and Unknown transaction handlers. In this example, 18 `beforeTransaction()` is called before the **issue**, **buy** and **redeem** 19 transactions. `afterTransaction()` is called after the **issue**, **buy** and 20 **redeem** transactions. `unknownTransaction()` is only called if a request is 21 made to invoke a transaction not defined in the smart contract. (The diagram is 22 simplified by not repeating `beforeTransaction` and `afterTransaction` boxes for 23 each transaction.)* 24 25 ## Types of handler 26 27 There are three types of transaction handlers which cover different aspects 28 of the interaction between an application and a smart contract: 29 30 * **Before handler**: is called before every smart contract transaction is 31 invoked. The handler will usually modify the transaction context to be used 32 by the transaction. The handler has access to the full range of Fabric APIs; 33 for example, it can issue `getState()` and `putState()`. 34 35 36 * **After handler**: is called after every smart contract transaction is 37 invoked. The handler will usually perform post-processing common to all 38 transactions, and also has full access to the Fabric APIs. 39 40 41 * **Unknown handler**: is called if an attempt is made to invoke a transaction 42 that is not defined in a smart contract. Typically, the handler will record 43 the failure for subsequent processing by an administrator. The handler has 44 full access to the Fabric APIs. 45 46 Defining a transaction handler is optional; a smart contract will perform 47 correctly without handlers being defined. A smart contract can define at most 48 one handler of each type. 49 50 ## Defining a handler 51 52 Transaction handlers are added to the smart contract as methods with well 53 defined names. Here's an example which adds a handler of each type: 54 55 ```JavaScript 56 CommercialPaperContract extends Contract { 57 58 ... 59 60 async beforeTransaction(ctx) { 61 // Write the transaction ID as an informational to the console 62 console.info(ctx.stub.getTxID()); 63 }; 64 65 async afterTransaction(ctx, result) { 66 // This handler interacts with the ledger 67 ctx.stub.cpList.putState(...); 68 }; 69 70 async unknownTransaction(ctx) { 71 // This handler throws an exception 72 throw new Error('Unknown transaction function'); 73 }; 74 75 } 76 ``` 77 78 The form of a transaction handler definition is the similar for all handler 79 types, but notice how the `afterTransaction(ctx, result)` also receives any 80 result returned by the transaction. The [API 81 documentation](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-contract-api.Contract.html) 82 shows you the exact form of these handlers. 83 84 ## Handler processing 85 86 Once a handler has been added to the smart contract, it will be invoked during 87 transaction processing. During processing, the handler receives `ctx`, the 88 [transaction context](./transationcontext.md), performs some processing, and 89 returns control as it completes. Processing continues as follows: 90 91 * **Before handler**: If the handler completes successfully, the transaction is 92 called with the updated context. If the handler throws an exception, then the 93 transaction is not called and the smart contract fails with the exception 94 error message. 95 96 97 * **After handler**: If the handler completes successfully, then the smart 98 contract completes as determined by the invoked transaction. If the handler 99 throws an exception, then the transaction fails with the exception error 100 message. 101 102 103 * **Unknown handler**: The handler should complete by throwing an exception with 104 the required error message. If an **Unknown handler** is not specified, or an 105 exception is not thrown by it, there is sensible default processing; the smart 106 contract will fail with an **unknown transaction** error message. 107 108 If the handler requires access to the function and parameters, then it is easy to do this: 109 110 ```JavaScript 111 async beforeTransaction(ctx) { 112 // Retrieve details of the transaction 113 let txnDetails = ctx.stub.getFunctionAndParameters(); 114 115 console.info(`Calling function: ${txnDetails.fcn} `); 116 console.info(util.format(`Function arguments : %j ${stub.getArgs()} ``); 117 } 118 ``` 119 120 See how this handler uses the utility API `getFunctionAndParameters` via the 121 [transaction context](./transactioncontext.html#stub). 122 123 ## Multiple handlers 124 125 It is only possible to define at most one handler of each type for a smart 126 contract. If a smart contract needs to invoke multiple functions during before, 127 after or unknown handling, it should coordinate this from within the appropriate 128 function.