mirror of
https://github.com/corda/corda.git
synced 2025-02-04 10:11:14 +00:00
Fixes the hello, world tutorial on M14 as well.
This commit is contained in:
parent
2e0fd0548f
commit
129e5088cf
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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``
|
||||
|
@ -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.
|
||||
|
@ -8,8 +8,9 @@ The CorDapp Template
|
||||
====================
|
||||
|
||||
When writing a new CorDapp, you’ll 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
|
||||
---------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user