|
| 1 | +## Contract tutorials |
| 2 | + |
| 3 | +This tutorial will teach you how to write Java based Hyperledger Fabric Contract; the code examples have been created using the IBM Blockchain Platform VSCode extension. |
| 4 | + |
| 5 | +## Writing your own contract |
| 6 | + |
| 7 | +Either gradle or maven can be used for building your code; here the example is shown with gradle. |
| 8 | + |
| 9 | +### Create Gradle project |
| 10 | +You can use `fabric-contract-example/gradle` as staring point. Make sure that your project build creates a runnable jar that contains all dependencies named `chaincode.jar` as result. |
| 11 | + |
| 12 | +The main class is very important for Contracts and must be set to `org.hyperledger.fabric.contract.ContractRouter`. All these are set correctly in the examples but for reference the important parts are |
| 13 | + |
| 14 | +``` |
| 15 | +plugins { |
| 16 | + id 'com.github.johnrengelman.shadow' version '2.0.3' |
| 17 | +} |
| 18 | +... |
| 19 | +
|
| 20 | +... |
| 21 | +shadowJar { |
| 22 | + baseName = 'chaincode' |
| 23 | + version = null |
| 24 | + classifier = null |
| 25 | +
|
| 26 | + manifest { |
| 27 | + attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter' |
| 28 | + } |
| 29 | +} |
| 30 | +``` |
| 31 | + |
| 32 | +### Writing the contract |
| 33 | + |
| 34 | +Typically a Contract will be working with one or more 'assets', so in this example we are using a `MyAssestContract` class. Within a given chaincode container, |
| 35 | + (the docker container that starts when chaincode is instantiated), you can have one or more contract classes. Each contract class has one or more |
| 36 | + 'transaction functions' these can be executed from the SDK or from other contracts. |
| 37 | + |
| 38 | +With the VSCode extension you can create a starter project, or you can use the same Yeoman generator from the command line. |
| 39 | + |
| 40 | +``` |
| 41 | +# if you don't have Yeoman already |
| 42 | +npm install -g yo |
| 43 | +
|
| 44 | +npm install -g generator-fabric |
| 45 | +``` |
| 46 | + |
| 47 | +You can then run the generator to create a sample Java Contract project that uses Gradle 4.6 |
| 48 | +This is an example output of running the generator |
| 49 | + |
| 50 | +``` |
| 51 | + yo fabric:contract |
| 52 | +? Please specify the contract language: Java |
| 53 | +? Please specify the contract name: MyJavaContract |
| 54 | +? Please specify the contract version: 0.0.1 |
| 55 | +? Please specify the contract description: My first Java contract |
| 56 | +? Please specify the contract author: ANOther |
| 57 | +? Please specify the contract license: Apache-2.0 |
| 58 | +? Please specify the asset type: MyAsset |
| 59 | +``` |
| 60 | + |
| 61 | +### Code overview |
| 62 | + |
| 63 | +As well as the gradle project files, a `org.example.MyAsset.java` and a `org.example.MyAssetContract.java` are |
| 64 | +created. |
| 65 | + |
| 66 | +All contract classes like `MyAssetContract` must implement the `ContractInterface` and have a `@Contract` annotation |
| 67 | +to mark this as a Contract. The annotation allows you to specify meta information, such as version, author |
| 68 | +and description. Refer to the JavaDoc for the full specificaiton. |
| 69 | + |
| 70 | +The `@Default` annotation is useful, as it marks the class as a the default contract - when referring to the |
| 71 | +transaction function from the client SDK it permits a shorthand to be used. |
| 72 | + |
| 73 | +It is recommened to have a no-argument constructor in the contract. |
| 74 | + |
| 75 | +Each method you wish to be a transaction function must be marked by a `@Transaction()` annotation. |
| 76 | +The first parameter to each of these must accept a `org.hyperledger.fabric.contract.Context` object. This |
| 77 | +object is the 'transactional context' and provides information about the current transaction being executed |
| 78 | +and also provides access to the APIs to check and update the ledger state. |
| 79 | + |
| 80 | +Transaciton functions can have as many other parameters as they wish. |
| 81 | + |
| 82 | +Standard Java primitives and strings can be passed; any other Java Object IS NOT supported, eg passing a HashMap. |
| 83 | +More complex types can be defined if they are suitably defined. Arrays are supported types are permitted. |
| 84 | + |
| 85 | +The `MyAsset` class is an example of the more a complex datatype that can be passed. Such a class is |
| 86 | +marked used the `@DataType` annotation, with each property within the object marked by a `@Property` annotation. |
| 87 | + |
| 88 | +Richer constraints on datatype and parameters can be applied; see the JavaDoc for details. |
| 89 | + |
| 90 | +#### Building contract |
| 91 | + |
| 92 | +Run build command. |
| 93 | + |
| 94 | +```bash |
| 95 | +gradle clean build shadowJar |
| 96 | +``` |
| 97 | +Assuming there are no build errors, you can proceed to chaincode testing. |
| 98 | + |
0 commit comments