mirror of
https://github.com/corda/corda.git
synced 2025-05-09 12:02:56 +00:00
Updates tutorials (general fixes, link to solutions repos)
* Updates tutorial to make imports to be added clearer, and to reflect new repo structure. * Adds links to the solution repos for tut 1. * Further fixes based on dry-run.
This commit is contained in:
parent
d1ea881aef
commit
929341e7ee
@ -33,6 +33,7 @@ dependencies {
|
|||||||
compile project(':core')
|
compile project(':core')
|
||||||
compile project(':client:jfx')
|
compile project(':client:jfx')
|
||||||
compile project(':node-driver')
|
compile project(':node-driver')
|
||||||
|
compile project(':webserver')
|
||||||
testCompile project(':verifier')
|
testCompile project(':verifier')
|
||||||
testCompile project(':test-utils')
|
testCompile project(':test-utils')
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.corda.docs.java.tutorial.helloworld;
|
package com.template;
|
||||||
|
|
||||||
import net.corda.core.contracts.CommandData;
|
import net.corda.core.contracts.CommandData;
|
||||||
import net.corda.core.contracts.Contract;
|
import net.corda.core.contracts.Contract;
|
@ -1,17 +1,21 @@
|
|||||||
package net.corda.docs.java.tutorial.helloworld;
|
package net.corda.docs.java.tutorial.helloworld;
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import co.paralleluniverse.fibers.Suspendable;
|
import co.paralleluniverse.fibers.Suspendable;
|
||||||
|
import com.template.TemplateContract;
|
||||||
|
import net.corda.core.flows.*;
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
import net.corda.core.contracts.Command;
|
import net.corda.core.contracts.Command;
|
||||||
import net.corda.core.contracts.CommandData;
|
import net.corda.core.contracts.CommandData;
|
||||||
import net.corda.core.flows.*;
|
|
||||||
import net.corda.core.identity.Party;
|
import net.corda.core.identity.Party;
|
||||||
import net.corda.core.transactions.SignedTransaction;
|
import net.corda.core.transactions.SignedTransaction;
|
||||||
import net.corda.core.transactions.TransactionBuilder;
|
import net.corda.core.transactions.TransactionBuilder;
|
||||||
import net.corda.core.utilities.ProgressTracker;
|
import net.corda.core.utilities.ProgressTracker;
|
||||||
|
|
||||||
import static net.corda.docs.java.tutorial.helloworld.TemplateContract.TEMPLATE_CONTRACT_ID;
|
import static com.template.TemplateContract.TEMPLATE_CONTRACT_ID;
|
||||||
|
|
||||||
|
// Replace TemplateFlow's definition with:
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
public class IOUFlow extends FlowLogic<Void> {
|
public class IOUFlow extends FlowLogic<Void> {
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package net.corda.docs.java.tutorial.helloworld;
|
package net.corda.docs.java.tutorial.helloworld;
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import net.corda.core.contracts.ContractState;
|
import net.corda.core.contracts.ContractState;
|
||||||
import net.corda.core.identity.AbstractParty;
|
import net.corda.core.identity.AbstractParty;
|
||||||
import net.corda.core.identity.Party;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.corda.core.identity.Party;
|
||||||
|
|
||||||
|
// Replace TemplateState's definition with:
|
||||||
public class IOUState implements ContractState {
|
public class IOUState implements ContractState {
|
||||||
private final int value;
|
private final int value;
|
||||||
private final Party lender;
|
private final Party lender;
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
package net.corda.docs.java.tutorial.twoparty;
|
package net.corda.docs.java.tutorial.twoparty;
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import net.corda.core.contracts.CommandData;
|
import net.corda.core.contracts.CommandData;
|
||||||
import net.corda.core.contracts.CommandWithParties;
|
|
||||||
import net.corda.core.contracts.Contract;
|
import net.corda.core.contracts.Contract;
|
||||||
import net.corda.core.identity.Party;
|
|
||||||
import net.corda.core.transactions.LedgerTransaction;
|
import net.corda.core.transactions.LedgerTransaction;
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import net.corda.core.contracts.CommandWithParties;
|
||||||
|
import net.corda.core.identity.Party;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
|
import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
|
||||||
import static net.corda.core.contracts.ContractsDSL.requireThat;
|
import static net.corda.core.contracts.ContractsDSL.requireThat;
|
||||||
|
|
||||||
|
// Replace TemplateContract's definition with:
|
||||||
public class IOUContract implements Contract {
|
public class IOUContract implements Contract {
|
||||||
|
public static final String IOU_CONTRACT_ID = "com.template.IOUContract";
|
||||||
|
|
||||||
// Our Create command.
|
// Our Create command.
|
||||||
public static class Create implements CommandData {
|
public static class Create implements CommandData {
|
||||||
}
|
}
|
||||||
|
@ -45,15 +45,14 @@ public class IOUFlow extends FlowLogic<Void> {
|
|||||||
// We retrieve the notary identity from the network map.
|
// We retrieve the notary identity from the network map.
|
||||||
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
|
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
|
||||||
|
|
||||||
|
// DOCSTART 02
|
||||||
// We create a transaction builder.
|
// We create a transaction builder.
|
||||||
final TransactionBuilder txBuilder = new TransactionBuilder();
|
final TransactionBuilder txBuilder = new TransactionBuilder();
|
||||||
txBuilder.setNotary(notary);
|
txBuilder.setNotary(notary);
|
||||||
|
|
||||||
// DOCSTART 02
|
|
||||||
// We create the transaction components.
|
// We create the transaction components.
|
||||||
IOUState outputState = new IOUState(iouValue, getOurIdentity(), otherParty);
|
IOUState outputState = new IOUState(iouValue, getOurIdentity(), otherParty);
|
||||||
String outputContract = IOUContract.class.getName();
|
StateAndContract outputContractAndState = new StateAndContract(outputState, IOUContract.IOU_CONTRACT_ID);
|
||||||
StateAndContract outputContractAndState = new StateAndContract(outputState, outputContract);
|
|
||||||
List<PublicKey> requiredSigners = ImmutableList.of(getOurIdentity().getOwningKey(), otherParty.getOwningKey());
|
List<PublicKey> requiredSigners = ImmutableList.of(getOurIdentity().getOwningKey(), otherParty.getOwningKey());
|
||||||
Command cmd = new Command<>(new IOUContract.Create(), requiredSigners);
|
Command cmd = new Command<>(new IOUContract.Create(), requiredSigners);
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package net.corda.docs.java.tutorial.twoparty;
|
package net.corda.docs.java.tutorial.twoparty;
|
||||||
|
|
||||||
// DOCSTART 01
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
import co.paralleluniverse.fibers.Suspendable;
|
import co.paralleluniverse.fibers.Suspendable;
|
||||||
import net.corda.core.contracts.ContractState;
|
import net.corda.core.contracts.ContractState;
|
||||||
import net.corda.core.flows.*;
|
import net.corda.core.flows.*;
|
||||||
import net.corda.core.transactions.SignedTransaction;
|
import net.corda.core.transactions.SignedTransaction;
|
||||||
import net.corda.core.utilities.ProgressTracker;
|
import net.corda.core.utilities.ProgressTracker;
|
||||||
import net.corda.docs.java.tutorial.helloworld.IOUFlow;
|
|
||||||
import net.corda.docs.java.tutorial.helloworld.IOUState;
|
|
||||||
|
|
||||||
import static net.corda.core.contracts.ContractsDSL.requireThat;
|
import static net.corda.core.contracts.ContractsDSL.requireThat;
|
||||||
|
|
||||||
|
// Define IOUFlowResponder:
|
||||||
@InitiatedBy(IOUFlow.class)
|
@InitiatedBy(IOUFlow.class)
|
||||||
public class IOUFlowResponder extends FlowLogic<Void> {
|
public class IOUFlowResponder extends FlowLogic<Void> {
|
||||||
private final FlowSession otherPartySession;
|
private final FlowSession otherPartySession;
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package net.corda.docs.tutorial.helloworld
|
package net.corda.docs.tutorial.helloworld
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.contracts.Command
|
|
||||||
import net.corda.core.flows.FinalityFlow
|
import net.corda.core.flows.FinalityFlow
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.InitiatingFlow
|
import net.corda.core.flows.InitiatingFlow
|
||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
|
import net.corda.core.contracts.Command
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.utilities.ProgressTracker
|
import net.corda.core.utilities.ProgressTracker
|
||||||
|
|
||||||
|
// Replace TemplateFlow's definition with:
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@StartableByRPC
|
@StartableByRPC
|
||||||
class IOUFlow(val iouValue: Int,
|
class IOUFlow(val iouValue: Int,
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package net.corda.docs.tutorial.helloworld
|
package net.corda.docs.tutorial.helloworld
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import net.corda.core.contracts.ContractState
|
import net.corda.core.contracts.ContractState
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
|
||||||
|
// Replace TemplateState's definition with:
|
||||||
class IOUState(val value: Int,
|
class IOUState(val value: Int,
|
||||||
val lender: Party,
|
val lender: Party,
|
||||||
val borrower: Party) : ContractState {
|
val borrower: Party) : ContractState {
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package net.corda.docs.tutorial.twoparty
|
package net.corda.docs.tutorial.twoparty
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import net.corda.core.contracts.CommandData
|
import net.corda.core.contracts.CommandData
|
||||||
import net.corda.core.contracts.Contract
|
import net.corda.core.contracts.Contract
|
||||||
import net.corda.core.contracts.requireSingleCommand
|
|
||||||
import net.corda.core.contracts.requireThat
|
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
|
import net.corda.core.contracts.*
|
||||||
|
|
||||||
|
// Replace IOUContract's contract ID and definition with:
|
||||||
|
val IOU_CONTRACT_ID = "com.template.IOUContract"
|
||||||
|
|
||||||
class IOUContract : Contract {
|
class IOUContract : Contract {
|
||||||
// Our Create command.
|
// Our Create command.
|
||||||
class Create : CommandData
|
class Create : CommandData
|
||||||
@ -20,7 +24,7 @@ class IOUContract : Contract {
|
|||||||
"There should be one output state of type IOUState." using (tx.outputs.size == 1)
|
"There should be one output state of type IOUState." using (tx.outputs.size == 1)
|
||||||
|
|
||||||
// IOU-specific constraints.
|
// IOU-specific constraints.
|
||||||
val out = tx.outputsOfType<net.corda.docs.tutorial.helloworld.IOUState>().single()
|
val out = tx.outputsOfType<IOUState>().single()
|
||||||
"The IOU's value must be non-negative." using (out.value > 0)
|
"The IOU's value must be non-negative." using (out.value > 0)
|
||||||
"The lender and the borrower cannot be the same entity." using (out.lender != out.borrower)
|
"The lender and the borrower cannot be the same entity." using (out.lender != out.borrower)
|
||||||
|
|
||||||
|
@ -6,9 +6,17 @@ import net.corda.core.contracts.Command
|
|||||||
import net.corda.core.contracts.StateAndContract
|
import net.corda.core.contracts.StateAndContract
|
||||||
import net.corda.core.flows.*
|
import net.corda.core.flows.*
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
|
import net.corda.core.messaging.CordaRPCOps
|
||||||
|
import net.corda.core.serialization.SerializationWhitelist
|
||||||
import net.corda.core.transactions.TransactionBuilder
|
import net.corda.core.transactions.TransactionBuilder
|
||||||
import net.corda.core.utilities.ProgressTracker
|
import net.corda.core.utilities.ProgressTracker
|
||||||
import kotlin.reflect.jvm.jvmName
|
import net.corda.webserver.services.WebServerPluginRegistry
|
||||||
|
import java.util.function.Function
|
||||||
|
import javax.ws.rs.GET
|
||||||
|
import javax.ws.rs.Path
|
||||||
|
import javax.ws.rs.Produces
|
||||||
|
import javax.ws.rs.core.MediaType
|
||||||
|
import javax.ws.rs.core.Response
|
||||||
// DOCEND 01
|
// DOCEND 01
|
||||||
|
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
@ -25,14 +33,13 @@ class IOUFlow(val iouValue: Int,
|
|||||||
// We retrieve the notary identity from the network map.
|
// We retrieve the notary identity from the network map.
|
||||||
val notary = serviceHub.networkMapCache.notaryIdentities[0]
|
val notary = serviceHub.networkMapCache.notaryIdentities[0]
|
||||||
|
|
||||||
// We create a transaction builder
|
// DOCSTART 02
|
||||||
|
// We create a transaction builder.
|
||||||
val txBuilder = TransactionBuilder(notary = notary)
|
val txBuilder = TransactionBuilder(notary = notary)
|
||||||
|
|
||||||
// DOCSTART 02
|
|
||||||
// We create the transaction components.
|
// We create the transaction components.
|
||||||
val outputState = IOUState(iouValue, ourIdentity, otherParty)
|
val outputState = IOUState(iouValue, ourIdentity, otherParty)
|
||||||
val outputContract = IOUContract::class.jvmName
|
val outputContractAndState = StateAndContract(outputState, IOU_CONTRACT_ID)
|
||||||
val outputContractAndState = StateAndContract(outputState, outputContract)
|
|
||||||
val cmd = Command(IOUContract.Create(), listOf(ourIdentity.owningKey, otherParty.owningKey))
|
val cmd = Command(IOUContract.Create(), listOf(ourIdentity.owningKey, otherParty.owningKey))
|
||||||
|
|
||||||
// We add the items to the builder.
|
// We add the items to the builder.
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package net.corda.docs.tutorial.twoparty
|
package net.corda.docs.tutorial.twoparty
|
||||||
|
|
||||||
// DOCSTART 01
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import net.corda.core.contracts.requireThat
|
|
||||||
import net.corda.core.flows.FlowLogic
|
import net.corda.core.flows.FlowLogic
|
||||||
import net.corda.core.flows.FlowSession
|
import net.corda.core.flows.FlowSession
|
||||||
import net.corda.core.flows.InitiatedBy
|
import net.corda.core.flows.InitiatedBy
|
||||||
import net.corda.core.flows.SignTransactionFlow
|
import net.corda.core.flows.SignTransactionFlow
|
||||||
import net.corda.core.transactions.SignedTransaction
|
|
||||||
import net.corda.docs.tutorial.helloworld.IOUFlow
|
import net.corda.docs.tutorial.helloworld.IOUFlow
|
||||||
import net.corda.docs.tutorial.helloworld.IOUState
|
import net.corda.docs.tutorial.helloworld.IOUState
|
||||||
|
|
||||||
|
// DOCSTART 01
|
||||||
|
// Add these imports:
|
||||||
|
import net.corda.core.contracts.requireThat
|
||||||
|
import net.corda.core.transactions.SignedTransaction
|
||||||
|
|
||||||
|
// Define IOUFlowResponder:
|
||||||
@InitiatedBy(IOUFlow::class)
|
@InitiatedBy(IOUFlow::class)
|
||||||
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>() {
|
class IOUFlowResponder(val otherPartySession: FlowSession) : FlowLogic<Unit>() {
|
||||||
@Suspendable
|
@Suspendable
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
Writing the flow
|
Writing the flow
|
||||||
================
|
================
|
||||||
A flow encodes a sequence of steps that a node can run to achieve a specific ledger update. By installing new flows on
|
A flow encodes a sequence of steps that a node can perform to achieve a specific ledger update. By installing new flows
|
||||||
a node, we allow the node to handle new business processes. The flow we define will allow a node to issue an
|
on a node, we allow the node to handle new business processes. The flow we define will allow a node to issue an
|
||||||
``IOUState`` onto the ledger.
|
``IOUState`` onto the ledger.
|
||||||
|
|
||||||
Flow outline
|
Flow outline
|
||||||
@ -40,8 +40,8 @@ FlowLogic
|
|||||||
---------
|
---------
|
||||||
All flows must subclass ``FlowLogic``. You then define the steps taken by the flow by overriding ``FlowLogic.call``.
|
All flows must subclass ``FlowLogic``. You then define the steps taken by the flow by overriding ``FlowLogic.call``.
|
||||||
|
|
||||||
Let's define our ``IOUFlow`` in either ``TemplateFlow.java`` or ``App.kt``. Delete both the existing flows in the
|
Let's define our ``IOUFlow`` in either ``TemplateFlow.java`` or ``App.kt``. Delete the two existing flows in the
|
||||||
template, and replace them with the following:
|
template (``Initiator`` and ``Responder``), and replace them with the following:
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
|
@ -107,9 +107,15 @@ commands.
|
|||||||
|
|
||||||
We want to create an IOU of 100 with PartyB. We start the ``IOUFlow`` by typing:
|
We want to create an IOU of 100 with PartyB. We start the ``IOUFlow`` by typing:
|
||||||
|
|
||||||
.. code:: bash
|
.. container:: codeset
|
||||||
|
|
||||||
start IOUFlow iouValue: 99, otherParty: "O=PartyB,L=New York,C=US"
|
.. code-block:: java
|
||||||
|
|
||||||
|
start IOUFlow arg0: 99, arg1: "O=PartyB,L=New York,C=US"
|
||||||
|
|
||||||
|
.. code-block:: kotlin
|
||||||
|
|
||||||
|
start IOUFlow iouValue: 99, otherParty: "O=PartyB,L=New York,C=US"
|
||||||
|
|
||||||
This single command will cause PartyA and PartyB to automatically agree an IOU. This is one of the great advantages of
|
This single command will cause PartyA and PartyB to automatically agree an IOU. This is one of the great advantages of
|
||||||
the flow framework - it allows you to reduce complex negotiation and update processes into a single function call.
|
the flow framework - it allows you to reduce complex negotiation and update processes into a single function call.
|
||||||
@ -118,13 +124,7 @@ If the flow worked, it should have recorded a new IOU in the vaults of both Part
|
|||||||
|
|
||||||
We can check the contents of each node's vault by running:
|
We can check the contents of each node's vault by running:
|
||||||
|
|
||||||
.. container:: codeset
|
.. code-block:: base
|
||||||
|
|
||||||
.. code-block:: java
|
|
||||||
|
|
||||||
run vaultQuery contractStateType: com.template.state.IOUState
|
|
||||||
|
|
||||||
.. code-block:: kotlin
|
|
||||||
|
|
||||||
run vaultQuery contractStateType: com.template.IOUState
|
run vaultQuery contractStateType: com.template.IOUState
|
||||||
|
|
||||||
@ -174,6 +174,11 @@ parts:
|
|||||||
* The ``IOUState``, representing IOUs on the ledger
|
* The ``IOUState``, representing IOUs on the ledger
|
||||||
* The ``IOUFlow``, orchestrating the process of agreeing the creation of an IOU on-ledger
|
* The ``IOUFlow``, orchestrating the process of agreeing the creation of an IOU on-ledger
|
||||||
|
|
||||||
|
After completing this tutorial, your CorDapp should look like this:
|
||||||
|
|
||||||
|
* Java: https://github.com/corda/corda-tut1-solution-java
|
||||||
|
* Kotlin: https://github.com/corda/corda-tut1-solution-kotlin
|
||||||
|
|
||||||
Next steps
|
Next steps
|
||||||
----------
|
----------
|
||||||
There are a number of improvements we could make to this CorDapp:
|
There are a number of improvements we could make to this CorDapp:
|
||||||
@ -183,4 +188,4 @@ There are a number of improvements we could make to this CorDapp:
|
|||||||
* We could add an API, to make it easier to interact with the CorDapp
|
* We could add an API, to make it easier to interact with the CorDapp
|
||||||
|
|
||||||
But for now, the biggest priority is to add an ``IOUContract`` imposing constraints on the evolution of each
|
But for now, the biggest priority is to add an ``IOUContract`` imposing constraints on the evolution of each
|
||||||
``IOUState`` over time. This will be the focus of our next tutorial.
|
``IOUState`` over time. This will be the focus of our next tutorial.
|
@ -24,7 +24,6 @@ interface is defined as follows:
|
|||||||
val participants: List<AbstractParty>
|
val participants: List<AbstractParty>
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
The first thing you'll probably notice about this interface declaration is that its not written in Java or another
|
The first thing you'll probably notice about this interface declaration is that its not written in Java or another
|
||||||
common language. The core Corda platform, including the interface declaration above, is entirely written in Kotlin.
|
common language. The core Corda platform, including the interface declaration above, is entirely written in Kotlin.
|
||||||
|
|
||||||
@ -70,7 +69,7 @@ later is often as simple as adding an additional property to your class definiti
|
|||||||
|
|
||||||
Defining IOUState
|
Defining IOUState
|
||||||
-----------------
|
-----------------
|
||||||
Let's get started by opening ``TemplateState.java`` (for Java) or ``App.kt`` (for Kotlin) and updating
|
Let's get started by opening ``TemplateState.java`` (for Java) or ``StatesAndContracts.kt`` (for Kotlin) and updating
|
||||||
``TemplateState`` to define an ``IOUState``:
|
``TemplateState`` to define an ``IOUState``:
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
@ -41,34 +41,33 @@ https://docs.corda.net/tutorial-cordapp.html#opening-the-example-cordapp-in-inte
|
|||||||
|
|
||||||
Template structure
|
Template structure
|
||||||
------------------
|
------------------
|
||||||
The template has a number of files, but we can ignore most of them. To implement our IOU CorDapp in Java, we'll only
|
The template has a number of files, but we can ignore most of them. We will only be modifying the following files:
|
||||||
need to modify two files. For Kotlin, we'll simply be modifying the ``App.kt`` file:
|
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
.. code-block:: java
|
.. code-block:: java
|
||||||
|
|
||||||
// 1. The state
|
// 1. The state
|
||||||
src/main/java/com/template/TemplateState.java
|
cordapp-contracts-states/src/main/java/com/template/TemplateState.java
|
||||||
|
|
||||||
// 2. The flow
|
// 2. The flow
|
||||||
src/main/java/com/template/TemplateFlow.java
|
cordapp/src/main/java/com/template/TemplateFlow.java
|
||||||
|
|
||||||
.. code-block:: kotlin
|
.. code-block:: kotlin
|
||||||
|
|
||||||
src/main/kotlin/com/template/App.kt
|
// 1. The state
|
||||||
|
cordapp-contracts-states/src/main/kotlin/com/template/StatesAndContracts.kt
|
||||||
|
|
||||||
|
// 2. The flow
|
||||||
|
cordapp/src/main/kotlin/com/template/App.kt
|
||||||
|
|
||||||
Clean up
|
Clean up
|
||||||
--------
|
--------
|
||||||
To prevent build errors later on, we should delete the following files before we begin:
|
To prevent build errors later on, we should delete the following files before we begin:
|
||||||
|
|
||||||
* Java:
|
* Java: ``cordapp/src/main/java/com/template/TemplateClient.java``
|
||||||
* ``src/main/java/com/template/TemplateClient.java``
|
|
||||||
* ``src/test/java/com/template/FlowTests.java``
|
|
||||||
|
|
||||||
* Kotlin:
|
* Kotlin: ``cordapp/src/main/kotlin/com/template/TemplateClient.kt``
|
||||||
* ``src/main/kotlin/com/template/TemplateClient.kt``
|
|
||||||
* ``src/test/kotlin/com/template/FlowTests.kt``
|
|
||||||
|
|
||||||
Progress so far
|
Progress so far
|
||||||
---------------
|
---------------
|
||||||
|
@ -77,7 +77,7 @@ We can picture this transaction as follows:
|
|||||||
Defining IOUContract
|
Defining IOUContract
|
||||||
--------------------
|
--------------------
|
||||||
Let's write a contract that enforces these constraints. We'll do this by modifying either ``TemplateContract.java`` or
|
Let's write a contract that enforces these constraints. We'll do this by modifying either ``TemplateContract.java`` or
|
||||||
``App.kt`` and updating ``TemplateContract`` to define an ``IOUContract``:
|
``StatesAndContracts.kt`` and updating ``TemplateContract`` to define an ``IOUContract``:
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ We'll do this by modifying the flow we wrote in the previous tutorial.
|
|||||||
|
|
||||||
Verifying the transaction
|
Verifying the transaction
|
||||||
-------------------------
|
-------------------------
|
||||||
In ``IOUFlow.java``/``IOUFlow.kt``, change the imports block to the following:
|
In ``IOUFlow.java``/``App.kt``, change the imports block to the following:
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
@ -31,7 +31,8 @@ In ``IOUFlow.java``/``IOUFlow.kt``, change the imports block to the following:
|
|||||||
:start-after: DOCSTART 01
|
:start-after: DOCSTART 01
|
||||||
:end-before: DOCEND 01
|
:end-before: DOCEND 01
|
||||||
|
|
||||||
And update ``IOUFlow.call`` by changing the code following the creation of the ``TransactionBuilder`` as follows:
|
And update ``IOUFlow.call`` by changing the code following the retrieval of the notary's identity from the network as
|
||||||
|
follows:
|
||||||
|
|
||||||
.. container:: codeset
|
.. container:: codeset
|
||||||
|
|
||||||
@ -138,6 +139,11 @@ Our CorDapp now imposes restrictions on the issuance of IOUs. Most importantly,
|
|||||||
from both the lender and the borrower before an IOU can be created on the ledger. This prevents either the lender or
|
from both the lender and the borrower before an IOU can be created on the ledger. This prevents either the lender or
|
||||||
the borrower from unilaterally updating the ledger in a way that only benefits themselves.
|
the borrower from unilaterally updating the ledger in a way that only benefits themselves.
|
||||||
|
|
||||||
|
After completing this tutorial, your CorDapp should look like this:
|
||||||
|
|
||||||
|
* Java: https://github.com/corda/corda-tut2-solution-java
|
||||||
|
* Kotlin: https://github.com/corda/corda-tut2-solution-kotlin
|
||||||
|
|
||||||
You should now be ready to develop your own CorDapps. You can also find a list of sample CorDapps
|
You should now be ready to develop your own CorDapps. You can also find a list of sample CorDapps
|
||||||
`here <https://www.corda.net/samples/>`_. As you write CorDapps, you'll also want to learn more about the
|
`here <https://www.corda.net/samples/>`_. As you write CorDapps, you'll also want to learn more about the
|
||||||
:doc:`Corda API <corda-api>`.
|
:doc:`Corda API <corda-api>`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user