github.com/kaituanwang/hyperledger@v2.0.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/master/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 139 * **Private data APIs**. See interaction point **(3)**. These APIs enable smart 140 contracts to interact with a private data collection. They are analogous to 141 the APIs for world state interactions, but for private data. There are APIs to 142 get, put and delete a private data state by its key: 143 144 * [getPrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateData__anchor) 145 * [putPrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#putPrivateData__anchor) 146 * [deletePrivateData()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#deletePrivateData__anchor) 147 148 <br> This set is complemented by set of APIs to query private data **(4)**. 149 These APIs allow smart contracts to retrieve a set of states from a private 150 data collection, according to a range of key values, either full or partial 151 keys, or a query according to values in the underlying world state 152 [database](../ledger/ledger.html#world-state-database-options). There are 153 currently no pagination APIs for private data collections. 154 155 * [getPrivateDataByRange()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataByRange__anchor) 156 * [getPrivateDataByPartialCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataByPartialCompositeKey__anchor) 157 * [getPrivateDataQueryResult()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataQueryResult__anchor) 158 159 160 * **Transaction APIs**. See interaction point **(5)**. These APIs are used by a 161 smart contract to retrieve details about the current transaction proposal 162 being processed by the smart contract. This includes the transaction 163 identifier and the time when the transaction proposal was created. 164 165 * [getTxID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTxID__anchor) 166 returns the identifier of the current transaction proposal **(5)**. 167 * [getTxTimestamp()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTxTimestamp__anchor) 168 returns the timestamp when the current transaction proposal was created by 169 the application **(5)**. 170 * [getCreator()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getCreator__anchor) 171 returns the raw identity (X.509 or otherwise) of the creator of 172 transaction proposal. If this is an X.509 certificate then it is often 173 more appropriate to use [`ctx.ClientIdentity`](#clientidentity). 174 * [getSignedProposal()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getSignedProposal__anchor) 175 returns a signed copy of the current transaction proposal being processed 176 by the smart contract. 177 * [getBinding()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getBinding__anchor) 178 is used to prevent transactions being maliciously or accidentally replayed 179 using a nonce. (For practical purposes, a nonce is a random number 180 generated by the client application and incorporated in a cryptographic 181 hash.) For example, this API could be used by a smart contract at **(1)** 182 to detect a replay of the transaction **(5)**. 183 * [getTransient()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getTransient__anchor) 184 allows a smart contract to access the transient data an application passes 185 to a smart contract. See interaction points **(9)** and **(10)**. 186 Transient data is private to the application-smart contract interaction. 187 It is not recorded on the ledger and is often used in conjunction with 188 private data collections **(3)**. 189 190 <br> 191 192 * **Key APIs** are used by smart contracts to manipulate state key in the world 193 state or a private data collection. See interaction points **2** and **4**. 194 195 The simplest of these APIs allows smart contracts to form and split composite 196 keys from their individual components. Slightly more advanced are the 197 `ValidationParameter()` APIs which get and set the state based endorsement 198 policies for world state **(2)** and private data **(4)**. Finally, 199 `getHistoryForKey()` retrieves the history for a state by returning the set of 200 stored values, including the transaction identifiers that performed the state 201 update, allowing the transactions to be read from the blockchain **(10)**. 202 203 * [createCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#createCompositeKey__anchor) 204 * [splitCompositeKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#splitCompositeKey__anchor) 205 * [setStateValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setStateValidationParameter__anchor) 206 * [getStateValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getStateValidationParameter__anchor) 207 * [getPrivateDataValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getPrivateDataValidationParameter__anchor) 208 * [setPrivateDataValidationParameter()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setPrivateDataValidationParameter__anchor) 209 * [getHistoryForKey()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getHistoryForKey__anchor) 210 211 <br> 212 213 * **Event APIs** are used manage event processing in a smart contract. 214 215 * [setEvent()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#setEvent__anchor) 216 217 Smart contracts use this API to add user events to a transaction response. 218 See interaction point **(5)**. These events are ultimately recorded on the 219 blockchain and sent to listening applications at interaction point 220 **(11)**. 221 222 <br> 223 224 * **Utility APIs** are a collection of useful APIs that don't easily fit in a 225 pre-defined category, so we've grouped them together! They include retrieving 226 the current channel name and passing control to a different chaincode on the 227 same peer. 228 229 * [getChannelID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ChaincodeStub.html#getChannelID__anchor) 230 231 See interaction point **(13)**. A smart contract running on any peer can 232 use this API to determined on which channel the application invoked the 233 smart contract. 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 251 ## ClientIdentity 252 253 In most cases, the application submitting a transaction will be using an X.509 254 certificate. In the [example](#structure), an X.509 certificate **(6)** issued 255 by `CA1` **(7)** is being used by `Isabella` **(8)** in her application to sign 256 the proposal in transaction `t6` **(5)**. 257 258 `ClientIdentity` takes the information returned by `getCreator()` and puts a set 259 of X.509 utility APIs on top of it to make it easier to use for this common use 260 case. 261 262 * [getX509Certificate()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getX509Certificate__anchor) 263 returns the full X.509 certificate of the transaction submitter, including all 264 its attributes and their values. See interaction point **(6)**. 265 * [getAttributeValue()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getAttributeValue__anchor) 266 returns the value of a particular X.509 attribute, for example, the 267 organizational unit `OU`, or distinguished name `DN`. See interaction point 268 **(6)**. 269 * [assertAttributeValue()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#assertAttributeValue__anchor) 270 returns `TRUE` if the specified attribute of the X.509 attribute has a 271 specified value. See interaction point **(6)**. 272 * [getID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getID__anchor) 273 returns the unique identity of the transaction submitter, according to their 274 distinguished name and the issuing CA's distinguished name. The format is 275 `x509::{subject DN}::{issuer DN}`. See interaction point **(6)**. 276 * [getMSPID()](https://hyperledger.github.io/fabric-chaincode-node/{BRANCH}/api/fabric-shim.ClientIdentity.html#getMSPID__anchor) 277 returns the channel MSP of the transaction submitter. This allows a smart 278 contract to make processing decisions based on the submitter's organizational 279 identity. See interaction point **(15)** or **(16)**. 280 281 <!--- Licensed under Creative Commons Attribution 4.0 International License 282 https://creativecommons.org/licenses/by/4.0/ -->