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.