Skip to content

Commit

Permalink
Applies tutorial fixes back onto M14.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Dudley committed Aug 16, 2017
1 parent 129e508 commit 8cedce7
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 149 deletions.
11 changes: 5 additions & 6 deletions docs/source/hello-world-contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ transfer them or redeem them for cash. One way to enforce this behaviour would b

* Its value must be non-negative
* The lender and the borrower cannot be the same entity
* The IOU's borrower must sign the transaction
* The IOU's lender must sign the transaction

We can picture this transaction as follows:

Expand Down Expand Up @@ -122,7 +122,6 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
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;
Expand Down Expand Up @@ -155,7 +154,7 @@ Let's write a contract that enforces these constraints. We'll do this by modifyi
check.using("The lender and the borrower cannot be the same entity.", lender != borrower);
// Constraints on the signers.
check.using("There must only be one signer.", ImmutableSet.of(command.getSigners()).size() == 1);
check.using("There must only be one signer.", command.getSigners().size() == 1);
check.using("The signer must be the lender.", command.getSigners().contains(lender.getOwningKey()));
return null;
Expand All @@ -179,7 +178,7 @@ The first thing we add to our contract is a *command*. Commands serve two functi
example, a transaction proposing the creation of an IOU could have to satisfy different constraints to one redeeming
an IOU
* They allow us to define the required signers for the transaction. For example, IOU creation might require signatures
from the borrower alone, whereas the transfer of an IOU might require signatures from both the IOU's borrower and lender
from the lender only, whereas the transfer of an IOU might require signatures from both the IOU's borrower and lender

Our contract has one command, a ``Create`` command. All commands must implement the ``CommandData`` interface.

Expand Down Expand Up @@ -219,7 +218,7 @@ following are true:
* The transaction has inputs
* The transaction doesn't have exactly one output
* The IOU itself is invalid
* The transaction doesn't require the borrower's signature
* The transaction doesn't require the lender's signature

Command constraints
~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -270,7 +269,7 @@ We've now written an ``IOUContract`` constraining the evolution of each ``IOUSta
* Creating an ``IOUState`` requires an issuance transaction with no inputs, a single ``IOUState`` output, and a
``Create`` command
* The ``IOUState`` created by the issuance transaction must have a non-negative value, and the lender and borrower
must be different entities.
must be different entities

Before we move on, make sure you go back and modify ``IOUState`` to point to the new ``IOUContract`` class.

Expand Down
54 changes: 14 additions & 40 deletions docs/source/hello-world-running.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,25 @@ Kotlin) file. We won't be using it, and it will cause build errors unless we rem

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``
or ``kotlin-source/build.gradle`` and scroll down to the ``task deployNodes`` section. This section defines four
nodes - the Controller, and NodeA, NodeB and NodeC:
Let's take a look at the nodes we're going to deploy. Open the project's ``build.gradle`` file and scroll down to the
``task deployNodes`` section. This section defines three nodes - the Controller, NodeA, and NodeB:

.. container:: codeset

.. code-block:: kotlin
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['build']) {
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes"
networkMap "CN=Controller,O=R3,OU=corda,L=London,C=GB"
networkMap "CN=Controller,O=R3,OU=corda,L=London,C=UK"
node {
name "CN=Controller,O=R3,OU=corda,L=London,C=GB"
name "CN=Controller,O=R3,OU=corda,L=London,C=UK"
advertisedServices = ["corda.notary.validating"]
p2pPort 10002
rpcPort 10003
webPort 10004
cordapps = []
}
node {
name "CN=NodeA,O=NodeA,L=London,C=GB"
name "CN=NodeA,O=NodeA,L=London,C=UK"
advertisedServices = []
p2pPort 10005
rpcPort 10006
Expand All @@ -53,15 +51,6 @@ nodes - the Controller, and NodeA, NodeB and NodeC:
cordapps = []
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
node {
name "CN=NodeC,O=NodeC,L=Paris,C=FR"
advertisedServices = []
p2pPort 10011
rpcPort 10012
webPort 10013
cordapps = []
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
}
We have three standard nodes, plus a special Controller node that is running the network map service, and is also
Expand All @@ -85,8 +74,8 @@ We can do that now by running the following commands from the root of the projec
Running the nodes
-----------------
Running ``deployNodes`` will build the nodes under both ``java-source/build/nodes`` and ``kotlin-source/build/nodes``.
If we navigate to one of these folders, we'll see four node folder. Each node folder has the following structure:
Running ``deployNodes`` will build the nodes under ``build/nodes``. If we navigate to one of these folders, we'll see
the three node folders. Each node folder has the following structure:

.. code:: python
Expand All @@ -102,17 +91,11 @@ Let's start the nodes by running the following commands from the root of the pro

.. code:: python
// On Windows for a Java CorDapp
java-source/build/nodes/runnodes.bat
// On Windows for a Kotlin CorDapp
kotlin-source/build/nodes/runnodes.bat
// On Mac for a Java CorDapp
java-source/build/nodes/runnodes
// On Windows
build/nodes/runnodes.bat
// On Mac for a Kotlin CorDapp
kotlin-source/build/nodes/runnodes
// On Mac
build/nodes/runnodes
This will start a terminal window for each node, and an additional terminal window for each node's webserver - eight
terminal windows in all. Give each node a moment to start - you'll know it's ready when its terminal windows displays
Expand Down Expand Up @@ -143,10 +126,8 @@ We want to create an IOU of 100 with Node B. We start the ``IOUFlow`` by typing:
start IOUFlow iouValue: 99, otherParty: "NodeB"
Node A and Node B will automatically agree an IOU.
If the flow worked, it should have led to the recording of a new IOU in the vaults of both Node A and Node B. Equally
importantly, Node C - although it sits on the same network - should not be aware of this transaction.
Node A and Node B will automatically agree an IOU. If the flow worked, it should have led to the recording of a new IOU
in the vaults of both Node A and Node B.

We can check the flow has worked by using an RPC operation to check the contents of each node's vault. Typing ``run``
will display a list of the available commands. We can examine the contents of a node's vault by running:
Expand Down Expand Up @@ -183,13 +164,6 @@ The vaults of Node A and Node B should both display the following output:
index: 0
second: "(observable)"
But the vault of Node C should output nothing!
.. code:: python
first: []
second: "(observable)"
Conclusion
----------
We have written a simple CorDapp that allows IOUs to be issued onto the ledger. Like all CorDapps, our
Expand Down
13 changes: 8 additions & 5 deletions docs/source/hello-world-template.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,25 @@ 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. To
implement our IOU CorDapp in Java, we'll only need to modify three files:
implement our IOU CorDapp in Java, we'll need to modify three files. For Kotlin, we'll simply be modifying the
``App.kt`` file:

.. container:: codeset

.. code-block:: java
// 1. The state
java-source/src/main/java/com/template/state/TemplateState.java
src/main/java/com/template/state/TemplateState.java
// 2. The contract
java-source/src/main/java/com/template/contract/TemplateContract.java
src/main/java/com/template/contract/TemplateContract.java
// 3. The flow
java-source/src/main/java/com/template/flow/TemplateFlow.java
src/main/java/com/template/flow/TemplateFlow.java
For Kotlin, we'll simply be modifying the ``App.kt`` file.
.. code-block:: kotlin
src/main/kotlin/com/template/App.kt
Progress so far
---------------
Expand Down
Binary file modified docs/source/resources/simple-tutorial-transaction.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 15 additions & 5 deletions docs/source/tut-two-party-contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,33 @@ Remember that each state references a contract. The contract imposes constraints
If the transaction does not obey the constraints of all the contracts of all its states, it cannot become a valid
ledger update.

We need to modify our contract so that the lender's signature is required in any IOU creation transaction. This will
only require changing a single line of code. In ``IOUContract.java``/``IOUContract.kt``, update the final line of the
``requireThat`` block as follows:
We need to modify our contract so that the borrower's signature is required in any IOU creation transaction. This will
only require changing a single line of code. In ``IOUContract.java``/``IOUContract.kt``, update the final two lines of
the ``requireThat`` block as follows:

.. container:: codeset

.. code-block:: kotlin
// Constraints on the signers.
"There must be two signers." using (command.signers.toSet().size == 2)
"The borrower and lender must be signers." using (command.signers.containsAll(listOf(
out.borrower.owningKey, out.lender.owningKey)))
.. code-block:: java
...
import com.google.common.collect.ImmutableList;
...
// Constraints on the signers.
check.using("There must be two signers.", command.getSigners().size() == 2);
check.using("The borrower and lender must be signers.", command.getSigners().containsAll(
ImmutableList.of(borrower.getOwningKey(), lender.getOwningKey())));
Progress so far
---------------
Our contract now imposes an additional constraint - the lender must also sign an IOU creation transaction. Next, we
need to update ``IOUFlow`` so that it actually gathers the counterparty's signature as part of the flow.
Our contract now imposes an additional constraint - the borrower must also sign an IOU creation transaction. Next, we
need to update ``IOUFlow`` so that it actually gathers the borrower's signature as part of the flow.

0 comments on commit 8cedce7

Please sign in to comment.