2017-06-16 13:05:52 +00:00
|
|
|
.. highlight:: kotlin
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
|
|
<script type="text/javascript" src="_static/codesets.js"></script>
|
|
|
|
|
|
|
|
Writing the state
|
|
|
|
=================
|
|
|
|
|
|
|
|
In Corda, shared facts on the ledger are represented as states. Our first task will be to define a new state type to
|
|
|
|
represent an IOU.
|
|
|
|
|
|
|
|
The ContractState interface
|
|
|
|
---------------------------
|
|
|
|
In Corda, any JVM class that implements the ``ContractState`` interface is a valid state. ``ContractState`` is
|
|
|
|
defined as follows:
|
|
|
|
|
|
|
|
.. container:: codeset
|
|
|
|
|
|
|
|
.. code-block:: kotlin
|
|
|
|
|
|
|
|
interface ContractState {
|
|
|
|
// The contract that imposes constraints on how this state can evolve over time.
|
|
|
|
val contract: Contract
|
|
|
|
|
|
|
|
// The list of entities considered to have a stake in this state.
|
|
|
|
val participants: List<AbstractParty>
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
Learning some Kotlin will be very useful for understanding how Corda works internally, and usually only takes an
|
|
|
|
experienced Java developer a day or so to pick up. However, learning Kotlin isn't essential. Because Kotlin code
|
|
|
|
compiles down to JVM bytecode, CorDapps written in other JVM languages can interoperate with Corda.
|
|
|
|
|
|
|
|
If you do want to dive into Kotlin, there's an official
|
|
|
|
`getting started guide <https://kotlinlang.org/docs/tutorials/>`_, and a series of
|
|
|
|
`Kotlin Koans <https://kotlinlang.org/docs/tutorials/koans.html>`_.
|
|
|
|
|
|
|
|
We can see that the ``ContractState`` interface declares two properties:
|
|
|
|
|
|
|
|
* ``contract``: the contract controlling transactions involving this state
|
|
|
|
* ``participants``: the list of entities that have to approve state changes such as changing the state's notary or
|
|
|
|
upgrading the state's contract
|
|
|
|
|
|
|
|
Beyond this, our state is free to define any properties, methods, helpers or inner classes it requires to accurately
|
|
|
|
represent a given class of shared facts on the ledger.
|
|
|
|
|
|
|
|
``ContractState`` also has several child interfaces that you may wish to implement depending on your state, such as
|
2017-07-07 11:06:28 +00:00
|
|
|
``LinearState`` and ``OwnableState``. See :doc:`api-states` for more information.
|
2017-06-16 13:05:52 +00:00
|
|
|
|
|
|
|
Modelling IOUs
|
|
|
|
--------------
|
|
|
|
How should we define the ``IOUState`` representing IOUs on the ledger? Beyond implementing the ``ContractState``
|
|
|
|
interface, our ``IOUState`` will also need properties to track the relevant features of the IOU:
|
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
* The lender of the IOU
|
|
|
|
* The borrower of the IOU
|
2017-06-16 13:05:52 +00:00
|
|
|
* The value of the IOU
|
|
|
|
|
|
|
|
There are many more fields you could include, such as the IOU's currency. We'll abstract them away for now. If
|
|
|
|
you wish to add them later, its as simple as adding an additional property to your class definition.
|
|
|
|
|
|
|
|
Defining IOUState
|
|
|
|
-----------------
|
2017-08-16 07:36:00 +00:00
|
|
|
Let's open ``TemplateState.java`` (for Java) or ``App.kt`` (for Kotlin) and update ``TemplateState`` to
|
2017-06-16 13:05:52 +00:00
|
|
|
define an ``IOUState``:
|
|
|
|
|
|
|
|
.. container:: codeset
|
|
|
|
|
|
|
|
.. code-block:: kotlin
|
|
|
|
|
|
|
|
class IOUState(val value: Int,
|
2017-07-07 11:06:28 +00:00
|
|
|
val lender: Party,
|
2017-08-16 07:36:00 +00:00
|
|
|
val borrower: Party) : ContractState {
|
|
|
|
override val contract = TemplateContract()
|
2017-07-07 11:06:28 +00:00
|
|
|
override val participants get() = listOf(lender, borrower)
|
2017-06-16 13:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.. code-block:: java
|
|
|
|
|
2017-08-16 07:36:00 +00:00
|
|
|
package com.template.state;
|
2017-06-16 13:05:52 +00:00
|
|
|
|
|
|
|
import com.google.common.collect.ImmutableList;
|
2017-08-16 07:36:00 +00:00
|
|
|
import com.template.contract.TemplateContract;
|
2017-06-16 13:05:52 +00:00
|
|
|
import net.corda.core.contracts.ContractState;
|
|
|
|
import net.corda.core.identity.AbstractParty;
|
|
|
|
import net.corda.core.identity.Party;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
public class IOUState implements ContractState {
|
|
|
|
private final int value;
|
2017-07-07 11:06:28 +00:00
|
|
|
private final Party lender;
|
|
|
|
private final Party borrower;
|
2017-08-16 07:36:00 +00:00
|
|
|
private final TemplateContract contract = new TemplateContract();
|
2017-06-16 13:05:52 +00:00
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
public IOUState(int value, Party lender, Party borrower) {
|
2017-06-16 13:05:52 +00:00
|
|
|
this.value = value;
|
2017-07-07 11:06:28 +00:00
|
|
|
this.lender = lender;
|
|
|
|
this.borrower = borrower;
|
2017-06-16 13:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getValue() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
public Party getLender() {
|
|
|
|
return lender;
|
2017-06-16 13:05:52 +00:00
|
|
|
}
|
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
public Party getBorrower() {
|
|
|
|
return borrower;
|
2017-06-16 13:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
// TODO: Once we've defined IOUContract, come back and update this.
|
2017-08-16 07:36:00 +00:00
|
|
|
public TemplateContract getContract() {
|
2017-06-16 13:05:52 +00:00
|
|
|
return contract;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<AbstractParty> getParticipants() {
|
2017-07-07 11:06:28 +00:00
|
|
|
return ImmutableList.of(lender, borrower);
|
2017-06-16 13:05:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-16 07:36:00 +00:00
|
|
|
If you're following along in Java, you'll also need to rename ``TemplateState.java`` to ``IOUState.java``.
|
|
|
|
|
2017-06-16 13:05:52 +00:00
|
|
|
We've made the following changes:
|
|
|
|
|
|
|
|
* We've renamed ``TemplateState`` to ``IOUState``
|
2017-07-07 11:06:28 +00:00
|
|
|
* We've added properties for ``value``, ``lender`` and ``borrower`` (along with any getters and setters in Java):
|
|
|
|
|
|
|
|
* ``value`` is just a standard int (in Java)/Int (in Kotlin)
|
|
|
|
* ``lender`` and ``borrower`` are of type ``Party``. ``Party`` is a built-in Corda type that represents an entity on
|
|
|
|
the network.
|
2017-06-16 13:05:52 +00:00
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
* We've overridden ``participants`` to return a list of the ``lender`` and ``borrower``
|
2017-06-16 13:05:52 +00:00
|
|
|
|
2017-07-07 11:06:28 +00:00
|
|
|
* Actions such as changing a state's contract or notary will require approval from all the ``participants``
|
2017-06-16 13:05:52 +00:00
|
|
|
|
|
|
|
We've left ``IOUState``'s contract as ``TemplateContract`` for now. We'll update this once we've defined the
|
|
|
|
``IOUContract``.
|
|
|
|
|
|
|
|
Progress so far
|
|
|
|
---------------
|
|
|
|
We've defined an ``IOUState`` that can be used to represent IOUs as shared facts on the ledger. As we've seen, states in
|
|
|
|
Corda are simply JVM classes that implement the ``ContractState`` interface. They can have any additional properties and
|
|
|
|
methods you like.
|
|
|
|
|
2017-08-10 13:53:35 +00:00
|
|
|
Next, we'll be writing our ``IOUContract`` to control the evolution of these shared facts over time.
|