github.com/true-sqn/fabric@v2.1.1+incompatible/docs/source/developapps/transactioncontext.md (about)

     1  # Transaction context
     2  
     3  **Audience**: Architects, application and smart contract developers
     4  
     5  A transaction context performs two functions. Firstly, it allows a developer to
     6  define and maintain user variables across transaction invocations within a smart
     7  contract. Secondly, it provides access to a wide range of Fabric APIs that allow
     8  smart contract developers to perform operations relating to detailed transaction
     9  processing. These range from querying or updating the ledger, both the immutable
    10  blockchain and the modifiable world state, to retrieving the
    11  transaction-submitting application's digital identity.
    12  
    13  A transaction context is created when a smart contract is deployed to a channel and
    14  made available to every subsequent transaction invocation. A transaction context
    15  helps smart contract developers write programs that are powerful, efficient and
    16  easy to reason about.
    17  
    18  * [Why a transaction context is important](#scenario)
    19  * [How to use a transaction context](#programming)
    20  * [What's in a transaction context](#structure)
    21  * [Using a context `stub`](#stub)
    22  * [Using a context `clientIdentity`](#clientIdentity)
    23  
    24  ## Scenario
    25  
    26  In the commercial paper sample,
    27  [papercontract](https://github.com/hyperledger/fabric-samples/blob/{BRANCH}/commercial-paper/organization/magnetocorp/contract/lib/papercontract.js)
    28  initially defines the name of the list of commercial papers for which it's
    29  responsible. Each transaction subsequently refers to this list; the issue
    30  transaction adds new papers to it, the buy transaction changes its owner, and
    31  the redeem transaction marks it as complete. This is a common pattern; when
    32  writing a smart contract it's often helpful to initialize and recall particular
    33  variables in sequential transactions.
    34  
    35  ![transaction.scenario](./develop.diagram.40.png) *A smart contract transaction
    36  context allows smart contracts to define and maintain user variables across
    37  transaction invocations. Refer to the text for a detailed explanation.*
    38  
    39  ## Programming
    40  
    41  When a smart contract is constructed, a developer can optionally override the
    42  built-in `Context` class `createContext` method to create a custom context:
    43  
    44  ```JavaScript
    45  createContext() {
    46      new CommercialPaperContext();
    47  }
    48  ```
    49  
    50  In our example, the `CommercialPaperContext` is specialized for
    51  `CommercialPaperContract`. See how the custom context, addressed through `this`,
    52  adds the specific variable `PaperList` to itself:
    53  
    54  ```JavaScript
    55  CommercialPaperContext extends Context {
    56      constructor () {
    57          this.paperList = new PaperList(this);
    58      }
    59  }
    60  ```
    61  
    62  When the createContext() method returns at point **(1)** in the diagram
    63  [above](#scenario), a custom context `ctx` has been created which contains
    64  `paperList` as one of its variables.
    65  
    66  Subsequently, whenever a smart contract transaction such as issue, buy or redeem
    67  is called, this context will be passed to it. See how at points **(2)**, **(3)**
    68  and **(4)** the same commercial paper context is passed into the transaction
    69  method using the `ctx` variable.
    70  
    71  See how the context is then used at point **(5)**:
    72  
    73  ```JavaScript
    74  ctx.paperList.addPaper(...);
    75  ctx.stub.putState(...);
    76  ```
    77  
    78  Notice how `paperList` created in `CommercialPaperContext` is available to the
    79  issue transaction. See how `paperList` is similarly used by the **redeem** and
    80  **buy** transactions; `ctx` makes the smart contracts efficient and easy to
    81  reason about.
    82  
    83  You can also see that there's another element in the context -- `ctx.stub` --
    84  which was not explictly added by `CommercialPaperContext`. That's because `stub`
    85  and other variables are part of the built-in context. Let's now examine the
    86  structure of this built-in context, these implicit variables and how to use
    87  them.
    88  
    89  ## Structure
    90  
    91  As we've seen from the [example](#programming), a transaction context can
    92  contain any number of user variables such as `paperList`.
    93  
    94  The transaction context also contains two built-in elements that provide access
    95  to a wide range of Fabric functionality ranging from the client application that
    96  submitted the transaction to ledger access.
    97  
    98    * `ctx.stub` is used to access APIs that provide a broad range of transaction
    99      processing operations from `putState()` and `getState()` to access the
   100      ledger, to `getTxID()` to retrieve the current transaction ID.
   101  
   102    * `ctx.clientIdentity` is used to get information about the identity of the
   103      user who submitted the transaction.
   104  
   105  We'll use the following diagram to show you what a smart contract can do using
   106  the `stub` and `clientIdentity` using the APIs available to it:
   107  
   108  ![context.apis](./develop.diagram.41.png) *A smart contract can access a
   109  range of functionality in a smart contract via the transaction context `stub`
   110  and `clientIdentity`. Refer to the text for a detailed explanation.*
   111  
   112  ## Stub
   113  
   114  The APIs in the stub fall into the following categories:
   115  
   116  * **World state data APIs**. See interaction point **(1)**. These APIs enable
   117    smart contracts to get, put and delete state corresponding to individual
   118    objects from the world state, using their key:
   119  
   120      * [getState()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getState__anchor)
   121      * [putState()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#putState__anchor)
   122      * [deleteState()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#deleteState__anchor)
   123  
   124    <br> These basic APIs are complemented by query APIs which enable contracts to
   125    retrieve a set of states, rather than an individual state. See interaction
   126    point **(2)**. The set is either defined by a range of key values, using full
   127    or partial keys, or a query according to values in the underlying world state
   128    [database](../ledger/ledger.html#world-state-database-options).  For large
   129    queries, the result sets can be paginated to reduce storage requirements:
   130  
   131      * [getStateByRange()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateByRange__anchor)
   132      * [getStateByRangeWithPagination()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateByRangeWithPagination__anchor)
   133      * [getStateByPartialCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateByPartialCompositeKey__anchor)
   134      * [getStateByPartialCompositeKeyWithPagination()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateByPartialCompositeKeyWithPagination__anchor)
   135      * [getQueryResult()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getQueryResult__anchor)
   136      * [getQueryResultWithPagination()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getQueryResultWithPagination__anchor)
   137  
   138  * **Private data APIs**. See interaction point **(3)**. These APIs enable smart
   139    contracts to interact with a private data collection. They are analogous to
   140    the APIs for world state interactions, but for private data. There are APIs to
   141    get, put and delete a private data state by its key:
   142  
   143      * [getPrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateData__anchor)
   144      * [putPrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#putPrivateData__anchor)
   145      * [deletePrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#deletePrivateData__anchor)
   146  
   147    <br> This set is complemented by set of APIs to query private data **(4)**.
   148    These APIs allow smart contracts to retrieve a set of states from a private
   149    data collection, according to a range of key values, either full or partial
   150    keys, or a query according to values in the underlying world state
   151    [database](../ledger/ledger.html#world-state-database-options). There are
   152    currently no pagination APIs for private data collections.
   153  
   154      * [getPrivateDataByRange()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataByRange__anchor)
   155      * [getPrivateDataByPartialCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataByPartialCompositeKey__anchor)
   156      * [getPrivateDataQueryResult()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataQueryResult__anchor)
   157  
   158  * **Transaction APIs**. See interaction point **(5)**. These APIs are used by a
   159    smart contract to retrieve details about the current transaction proposal
   160    being processed by the smart contract. This includes the transaction
   161    identifier and the time when the transaction proposal was created.
   162  
   163      * [getTxID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTxID__anchor)
   164        returns the identifier of the current transaction proposal **(5)**.
   165      * [getTxTimestamp()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTxTimestamp__anchor)
   166        returns the timestamp when the current transaction proposal was created by
   167        the application **(5)**.
   168      * [getCreator()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getCreator__anchor)
   169        returns the raw identity (X.509 or otherwise) of the creator of
   170        transaction proposal. If this is an X.509 certificate then it is often
   171        more appropriate to use [`ctx.ClientIdentity`](#clientidentity).
   172      * [getSignedProposal()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getSignedProposal__anchor)
   173        returns a signed copy of the current transaction proposal being processed
   174        by the smart contract.
   175      * [getBinding()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getBinding__anchor)
   176        is used to prevent transactions being maliciously or accidentally replayed
   177        using a nonce. (For practical purposes, a nonce is a random number
   178        generated by the client application and incorporated in a cryptographic
   179        hash.) For example, this API could be used by a smart contract at **(1)**
   180        to detect a replay of the transaction **(5)**.
   181      * [getTransient()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTransient__anchor)
   182        allows a smart contract to access the transient data an application passes
   183        to a smart contract. See interaction points **(9)** and **(10)**.
   184        Transient data is private to the application-smart contract interaction.
   185        It is not recorded on the ledger and is often used in conjunction with
   186        private data collections **(3)**.
   187  
   188    <br>
   189  
   190  * **Key APIs** are used by smart contracts to manipulate state key in the world
   191    state or a private data collection. See interaction points **2** and **4**.
   192  
   193    The simplest of these APIs allows smart contracts to form and split composite
   194    keys from their individual components. Slightly more advanced are the
   195    `ValidationParameter()` APIs which get and set the state based endorsement
   196    policies for world state **(2)** and private data **(4)**. Finally,
   197    `getHistoryForKey()` retrieves the history for a state by returning the set of
   198    stored values, including the transaction identifiers that performed the state
   199    update, allowing the transactions to be read from the blockchain **(10)**.
   200  
   201      * [createCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRACNH}/api/fabric-shim.ChaincodeStub.html#createCompositeKey__anchor)
   202      * [splitCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#splitCompositeKey__anchor)
   203      * [setStateValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setStateValidationParameter__anchor)
   204      * [getStateValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateValidationParameter__anchor)
   205      * [getPrivateDataValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataValidationParameter__anchor)
   206      * [setPrivateDataValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setPrivateDataValidationParameter__anchor)
   207      * [getHistoryForKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getHistoryForKey__anchor)
   208  
   209    <br>
   210  
   211  * **Event APIs** are used to manage event processing in a smart contract.
   212  
   213      * [setEvent()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setEvent__anchor)
   214  
   215  
   216        Smart contracts use this API to add user events to a transaction response.
   217        See interaction point **(5)**. These events are ultimately recorded on the
   218        blockchain and sent to listening applications at interaction point
   219        **(11)**.
   220  
   221      <br>
   222  
   223  * **Utility APIs** are a collection of useful APIs that don't easily fit in a
   224    pre-defined category, so we've grouped them together! They include retrieving
   225    the current channel name and passing control to a different chaincode on the
   226    same peer.
   227  
   228      * [getChannelID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getChannelID__anchor)
   229  
   230        See interaction point **(13)**.  A smart contract running on any peer can
   231        use this API to determined on which channel the application invoked the
   232        smart contract.
   233  
   234      * [invokeChaincode()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#invokeChaincode__anchor)
   235  
   236        See interaction point **(14)**.  Peer3 owned by MagnetoCorp has multiple
   237        smart contracts installed on it.  These smart contracts are able to call
   238        each other using this API. The smart contracts must be collocated; it is
   239        not possible to call a smart contract on a different peer.
   240  
   241      <br> Some of these utility APIs are only used if you're using low-level
   242    chaincode, rather than smart contracts. These APIs are primarily for the
   243    detailed manipulation of chaincode input; the smart contract `Contract` class
   244    does all of this parameter marshalling automatically for developers.
   245  
   246      * [getFunctionAndParameters()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getFunctionAndParameters__anchor)
   247      * [getStringArgs()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStringArgs__anchor)
   248      * [getArgs()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getArgs__anchor)
   249  
   250  ## ClientIdentity
   251  
   252  In most cases, the application submitting a transaction will be using an X.509
   253  certificate. In the [example](#structure), an X.509 certificate **(6)** issued
   254  by `CA1` **(7)** is being used by `Isabella` **(8)** in her application to sign
   255  the proposal in transaction `t6` **(5)**.
   256  
   257  `ClientIdentity` takes the information returned by `getCreator()` and puts a set
   258  of X.509 utility APIs on top of it to make it easier to use for this common use
   259  case.
   260  
   261  * [getX509Certificate()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getX509Certificate__anchor)
   262    returns the full X.509 certificate of the transaction submitter, including all
   263    its attributes and their values. See interaction point **(6)**.
   264  * [getAttributeValue()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getAttributeValue__anchor)
   265    returns the value of a particular X.509 attribute, for example, the
   266    organizational unit `OU`, or distinguished name `DN`. See interaction point
   267    **(6)**.
   268  * [assertAttributeValue()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#assertAttributeValue__anchor)
   269    returns `TRUE` if the specified attribute of the X.509 attribute has a
   270    specified value. See interaction point **(6)**.
   271  * [getID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getID__anchor)
   272    returns the unique identity of the transaction submitter, according to their
   273    distinguished name and the issuing CA's distinguished name. The format is
   274    `x509::{subject DN}::{issuer DN}`. See interaction point **(6)**.
   275  * [getMSPID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getMSPID__anchor)
   276    returns the channel MSP of the transaction submitter. This allows a smart
   277    contract to make processing decisions based on the submitter's organizational
   278    identity. See interaction point **(15)** or **(16)**.
   279  
   280  <!--- Licensed under Creative Commons Attribution 4.0 International License
   281  https://creativecommons.org/licenses/by/4.0/ -->