Fixes the hello, world tutorial on M14 as well.

This commit is contained in:
Joel Dudley 2017-08-15 15:58:35 +01:00 committed by GitHub
parent 2e0fd0548f
commit 129e5088cf
5 changed files with 61 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
@ -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);
@ -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
@ -229,7 +233,7 @@ Signing the transaction
Now that we have a valid transaction proposal, we need to sign it. Once the transaction is signed, no-one will be able
to modify the transaction without invalidating our signature, effectively making the transaction immutable.
The call to ``ServiceHub.signInitialTransaction`` returns a ``SignedTransaction`` - an object that pairs the
The call to ``ServiceHub.toSignedTransaction`` returns a ``SignedTransaction`` - an object that pairs the
transaction itself with a list of signatures over that transaction.
Finalising the transaction

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) : ContractState {
override val contract: IOUContract = IOUContract()
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``
@ -153,4 +150,4 @@ We've defined an ``IOUState`` that can be used to represent IOUs as shared facts
Corda are simply JVM classes that implement the ``ContractState`` interface. They can have any additional properties and
methods you like.
Next, we'll be writing our ``IOUContract`` to control the evolution of these shared facts over time.
Next, we'll be writing our ``IOUContract`` to control the evolution of these shared facts over time.

View File

@ -8,8 +8,9 @@ The CorDapp Template
====================
When writing a new CorDapp, youll generally want to base it on the
`Cordapp Template <https://github.com/corda/cordapp-template>`_. The Cordapp Template allows you to quickly deploy
your CorDapp onto a local test network of dummy nodes to evaluate its functionality.
`Java Cordapp Template <https://github.com/corda/cordapp-template-java>`_ or the equivalent
`Kotlin Cordapp Template <https://github.com/corda/cordapp-template-kotlin>`_. The Cordapp Template allows you to
quickly deploy your CorDapp onto a local test network of dummy nodes to evaluate its functionality.
Note that there's no need to download and install Corda itself. As long as you're working from a stable Milestone
branch, the required libraries will be downloaded automatically from an online repository.
@ -24,7 +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.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-kotlin
# Retrieve a list of the stable Milestone branches using:
git branch -a --list *release-M*
@ -34,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
@ -53,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
---------------