Fixes the hello, world tutorial.

This commit is contained in:
Joel Dudley 2017-08-16 08:36:00 +01:00 committed by GitHub
parent b76d036843
commit 435dcf6af4
5 changed files with 56 additions and 58 deletions

View File

@ -79,18 +79,19 @@ Defining IOUContract
--------------------
Let's write a contract that enforces these constraints. We'll do this by modifying either ``TemplateContract.java`` or
``TemplateContract.kt`` and updating ``TemplateContract`` to define an ``IOUContract``:
``App.kt`` and updating ``TemplateContract`` to define an ``IOUContract``:
.. container:: codeset
.. code-block:: kotlin
package com.iou
...
import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash
open class IOUContract : Contract {
...
class IOUContract : Contract {
// Our Create command.
class Create : CommandData
@ -109,7 +110,7 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
// Constraints on the signers.
"There must only be one signer." using (command.signers.toSet().size == 1)
"The signer must be the borrower." using (command.signers.contains(out.borrower.owningKey))
"The signer must be the lender." using (command.signers.contains(out.lender.owningKey))
}
}
@ -119,9 +120,10 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
.. code-block:: java
package com.iou;
package com.template.contract;
import com.google.common.collect.ImmutableSet;
import com.template.state.IOUState;
import net.corda.core.contracts.AuthenticatedObject;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
@ -146,7 +148,7 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
check.using("There should be one output state of type IOUState.", tx.getOutputs().size() == 1);
// IOU-specific constraints.
final IOUState out = (IOUState) tx.getOutputs().getData().get(0);
final IOUState out = (IOUState) tx.getOutputs().get(0).getData();
final Party lender = out.getLender();
final Party borrower = out.getBorrower();
check.using("The IOU's value must be non-negative.",out.getValue() > 0);
@ -154,7 +156,7 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
// Constraints on the signers.
check.using("There must only be one signer.", ImmutableSet.of(command.getSigners()).size() == 1);
check.using("The signer must be the borrower.", command.getSigners().contains(borrower.getOwningKey()));
check.using("The signer must be the lender.", command.getSigners().contains(lender.getOwningKey()));
return null;
});
@ -165,6 +167,8 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
@Override public final SecureHash getLegalContractReference() { return legalContractReference; }
}
If you're following along in Java, you'll also need to rename ``TemplateContract.java`` to ``IOUContract.java``.
Let's walk through this code step by step.
The Create command
@ -254,7 +258,7 @@ other statements - in this case, we're extracting the transaction's single ``IOU
Signer constraints
~~~~~~~~~~~~~~~~~~
Finally, we require the borrower's signature on the transaction. A transaction's required signers is equal to the union
Finally, we require the lender's signature on the transaction. A transaction's required signers is equal to the union
of all the signers listed on the commands. We therefore extract the signers from the ``Create`` command we
retrieved earlier.

View File

@ -33,24 +33,20 @@ FlowLogic
Flows are implemented as ``FlowLogic`` subclasses. You define the steps taken by the flow by overriding
``FlowLogic.call``.
We'll write our flow in either ``TemplateFlow.java`` or ``TemplateFlow.kt``. Overwrite the existing template code with
the following:
We'll write our flow in either ``TemplateFlow.java`` or ``App.kt``. Overwrite both the existing flows in the template
with the following:
.. container:: codeset
.. code-block:: kotlin
package com.iou
...
import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Command
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker
import net.corda.core.flows.FinalityFlow
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.flows.*
...
@InitiatingFlow
@StartableByRPC
@ -79,7 +75,7 @@ the following:
txBuilder.verify(serviceHub)
// Signing the transaction.
val signedTx = serviceHub.toSignedTransaction(txBuilder)
val signedTx = serviceHub.signInitialTransaction(txBuilder)
// Finalising the transaction.
subFlow(FinalityFlow(signedTx))
@ -88,19 +84,17 @@ the following:
.. code-block:: java
package com.iou;
package com.template.flow;
import co.paralleluniverse.fibers.Suspendable;
import com.template.contract.IOUContract;
import com.template.state.IOUState;
import net.corda.core.contracts.Command;
import net.corda.core.flows.FlowException;
import net.corda.core.flows.FlowLogic;
import net.corda.core.flows.InitiatingFlow;
import net.corda.core.flows.StartableByRPC;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
import net.corda.flows.FinalityFlow;
@InitiatingFlow
@StartableByRPC
@ -118,6 +112,11 @@ the following:
this.otherParty = otherParty;
}
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
/**
* The flow logic is encapsulated within the call() method.
*/
@ -128,7 +127,7 @@ the following:
final Party me = getServiceHub().getMyInfo().getLegalIdentity();
final Party notary = getServiceHub().getNetworkMapCache().getAnyNotary(null);
// We create a transaction builder
// We create a transaction builder.
final TransactionBuilder txBuilder = new TransactionBuilder();
txBuilder.setNotary(notary);
@ -141,7 +140,7 @@ the following:
txBuilder.verify(getServiceHub());
// Signing the transaction.
final SignedTransaction signedTx = getServiceHub().toSignedTransaction(txBuilder);
final SignedTransaction signedTx = getServiceHub().signInitialTransaction(txBuilder);
// Finalising the transaction.
subFlow(new FinalityFlow(signedTx));
@ -150,6 +149,8 @@ the following:
}
}
If you're following along in Java, you'll also need to rename ``TemplateFlow.java`` to ``IOUFlow.java``.
We now have our own ``FlowLogic`` subclass that overrides ``FlowLogic.call``. There's a few things to note:
* ``FlowLogic.call`` has a return type that matches the type parameter passed to ``FlowLogic`` - this is type returned
@ -163,6 +164,9 @@ We now have our own ``FlowLogic`` subclass that overrides ``FlowLogic.call``. Th
* ``@InitiatingFlow`` means that this flow can be started directly by the node
* ``StartableByRPC`` allows the node owner to start this flow via an RPC call
* We override the progress tracker, even though we are not providing any progress tracker steps yet. The progress
tracker is required for the node shell to establish when the flow has ended
Let's walk through the steps of ``FlowLogic.call`` one-by-one:
Retrieving participant information

View File

@ -9,6 +9,11 @@ Running our CorDapp
Now that we've written a CorDapp, it's time to test it by running it on some real Corda nodes.
Clean up
--------
Before running our node, delete the ``client/TemplateClient.java`` (for Java) or ``client/TemplateClient.kt`` (for
Kotlin) file. We won't be using it, and it will cause build errors unless we remove it.
Deploying our CorDapp
---------------------
Let's take a look at the nodes we're going to deploy. Open the project's build file under ``java-source/build.gradle``

View File

@ -64,31 +64,26 @@ you wish to add them later, its as simple as adding an additional property to yo
Defining IOUState
-----------------
Let's open ``TemplateState.java`` (for Java) or ``TemplateState.kt`` (for Kotlin) and update ``TemplateState`` to
Let's open ``TemplateState.java`` (for Java) or ``App.kt`` (for Kotlin) and update ``TemplateState`` to
define an ``IOUState``:
.. container:: codeset
.. code-block:: kotlin
package com.iou
import net.corda.core.contracts.ContractState
import net.corda.core.identity.Party
class IOUState(val value: Int,
val lender: Party,
val borrower: Party,
override val contract: TemplateContract) : ContractState {
val borrower: Party) : ContractState {
override val contract = TemplateContract()
override val participants get() = listOf(lender, borrower)
}
.. code-block:: java
package com.iou;
package com.template.state;
import com.google.common.collect.ImmutableList;
import com.template.contract.TemplateContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
import net.corda.core.identity.Party;
@ -99,7 +94,7 @@ define an ``IOUState``:
private final int value;
private final Party lender;
private final Party borrower;
private final IOUContract contract = new IOUContract();
private final TemplateContract contract = new TemplateContract();
public IOUState(int value, Party lender, Party borrower) {
this.value = value;
@ -121,7 +116,7 @@ define an ``IOUState``:
@Override
// TODO: Once we've defined IOUContract, come back and update this.
public IOUContract getContract() {
public TemplateContract getContract() {
return contract;
}
@ -131,6 +126,8 @@ define an ``IOUState``:
}
}
If you're following along in Java, you'll also need to rename ``TemplateState.java`` to ``IOUState.java``.
We've made the following changes:
* We've renamed ``TemplateState`` to ``IOUState``

View File

@ -25,11 +25,11 @@ Open a terminal window in the directory where you want to download the CorDapp t
.. code-block:: text
# Clone the template from GitHub:
git clone https://github.com/corda/cordapp-template-java.git ; cd cordapp-template
git clone https://github.com/corda/cordapp-template-java.git ; cd cordapp-template-java
*or*
git clone https://github.com/corda/cordapp-template-kotlin.git ; cd cordapp-template
git clone https://github.com/corda/cordapp-template-kotlin.git ; cd cordapp-template-kotlin
# Retrieve a list of the stable Milestone branches using:
git branch -a --list *release-M*
@ -39,11 +39,8 @@ Open a terminal window in the directory where you want to download the CorDapp t
Template structure
------------------
We can write our CorDapp in either Java or Kotlin, and will be providing the code in both languages throughout. If
you want to write the CorDapp in Java, you'll be modifying the files under ``java-source``. If you prefer to use
Kotlin, you'll be modifying the files under ``kotlin-source``.
To implement our IOU CorDapp, we'll only need to modify three files:
We can write our CorDapp in either Java or Kotlin, and will be providing the code in both languages throughout. To
implement our IOU CorDapp in Java, we'll only need to modify three files:
.. container:: codeset
@ -58,16 +55,7 @@ To implement our IOU CorDapp, we'll only need to modify three files:
// 3. The flow
java-source/src/main/java/com/template/flow/TemplateFlow.java
.. code-block:: kotlin
// 1. The state
kotlin-source/src/main/kotlin/com/template/state/TemplateState.kt
// 2. The contract
kotlin-source/src/main/kotlin/com/template/contract/TemplateContract.kt
// 3. The flow
kotlin-source/src/main/kotlin/com/template/flow/TemplateFlow.kt
For Kotlin, we'll simply be modifying the ``App.kt`` file.
Progress so far
---------------