corda/docs/source/hello-world-state.rst

154 lines
5.9 KiB
ReStructuredText
Raw Normal View History

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.
Next, we'll be writing our ``IOUContract`` to control the evolution of these shared facts over time.