From ee1e72d64c705877d2499c89db3fe4db59c14236 Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Tue, 31 Oct 2017 17:55:49 +0000 Subject: [PATCH] Rewrite of docs on what a Cordapp is, how to write one, and how to build one. --- docs/source/building-a-cordapp-index.rst | 7 +- docs/source/corda-nodes-index.rst | 2 +- docs/source/cordapp-build-systems.rst | 139 ++++++++++-------- docs/source/cordapp-overview.rst | 39 ++--- docs/source/deploying-a-node.rst | 175 ++++++++++++++--------- docs/source/quickstart-index.rst | 1 - docs/source/serialization.rst | 1 - docs/source/writing-a-cordapp.rst | 146 +++++++++++++++++++ docs/source/writing-cordapps.rst | 61 -------- 9 files changed, 362 insertions(+), 209 deletions(-) create mode 100644 docs/source/writing-a-cordapp.rst delete mode 100644 docs/source/writing-cordapps.rst diff --git a/docs/source/building-a-cordapp-index.rst b/docs/source/building-a-cordapp-index.rst index e073aef623..bbad288ee5 100644 --- a/docs/source/building-a-cordapp-index.rst +++ b/docs/source/building-a-cordapp-index.rst @@ -1,12 +1,13 @@ -Building a CorDapp -================== +CorDapps +======== .. toctree:: :maxdepth: 1 cordapp-overview - writing-cordapps + writing-a-cordapp cordapp-build-systems + building-against-master api-index flow-cookbook cheat-sheet \ No newline at end of file diff --git a/docs/source/corda-nodes-index.rst b/docs/source/corda-nodes-index.rst index 6389d7c23b..16a95a19a1 100644 --- a/docs/source/corda-nodes-index.rst +++ b/docs/source/corda-nodes-index.rst @@ -6,9 +6,9 @@ Corda nodes deploying-a-node running-a-node + corda-configuration-file clientrpc shell node-database node-administration - corda-configuration-file out-of-process-verification \ No newline at end of file diff --git a/docs/source/cordapp-build-systems.rst b/docs/source/cordapp-build-systems.rst index 398bfa0dc1..7d8eeaeff8 100644 --- a/docs/source/cordapp-build-systems.rst +++ b/docs/source/cordapp-build-systems.rst @@ -1,47 +1,30 @@ -CorDapp Build Systems -===================== +Building a CorDapp +================== -Cordapps run on the Corda platform and integrate with it and each other. To learn more about the basics of a Cordapp -please read :doc:`cordapp-overview`. To learn about writing a Cordapp as a developer please read :doc:`writing-cordapps`. +.. contents:: -This article will specifically deal with how to build cordapps, specifically with Gradle. +Cordapps run on the Corda platform and integrate with it and each other. This article explains how to build CorDapps. +To learn what a CorDapp is, please read :doc:`cordapp-overview`. -CorDapp JAR format ------------------- +CorDapp format +-------------- +A CorDapp is a semi-fat JAR that contains all of the CorDapp's dependencies *except* the Corda core libraries and any +other CorDapps it depends on. -The first step to integrating a Cordapp with Corda is to ensure it is in the correct format. The correct format of a JAR -is a semi-fat JAR that contains all of its own dependencies *except* the Corda core libraries and other Cordapps. +For example, if a Cordapp depends on ``corda-core``, ``your-other-cordapp`` and ``apache-commons``, then the Cordapp +JAR will contain: -For example if your Cordapp depends on ``corda-core``, ``your-other-cordapp`` and ``apache-commons`` then the Cordapp -JAR will contain all classes and resources from the ``apache-commons`` JAR and its dependencies and *nothing* from the -other two JARs. +* All classes and resources from the ``apache-commons`` JAR and its dependencies +* *Nothing* from the other two JARs -.. note:: The rest of this tutorial assumes you are using ``gradle``, the ``cordformation`` plugin and have forked from - one of our cordapp templates. +Build tools +----------- +In the instructions that follow, we assume you are using ``gradle`` and the ``cordformation`` plugin to build your +CorDapp. See the `example build file `_ +from the CorDapp template. -The ``jar`` task included by default in the cordapp templates will automatically build your JAR in this format as long -as your dependencies are correctly set. - -The filename of the jar must include some sort of unique identifier to deduplicate it from other releases of the same -CorDapp. This is typically done by appending the version string. It should not change once the jar has been deployed on -a node. If it is then make sure no one is checking ``FlowContext.appName`` (see :doc:`versioning`). - -Building against Corda ----------------------- - -To build against Corda you must do the following to your ``build.gradle``; - -* Add the ``net.corda:corda:`` JAR as a ``cordaRuntime`` dependency. -* Add each compile dependency (eg ``corda-core``) as a ``cordaCompile`` dependency. - -To make use of the Corda test facilities you must; - -* Add ``net.corda:corda-test-utils:`` as a ``testCompile`` dependency (eg; a default Java/Kotlin compile task). - -.. warning:: Never include ``corda-test-utils`` as a ``compile`` or ``cordaCompile`` dependency. - -These configurations work by the ``cordformation`` plugin adding ``cordaCompile`` as a new configuration that ``compile`` -extends from, and ``cordaRuntime`` which ``runtime`` extends from. +Setting your dependencies +------------------------- Choosing your Corda version ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,11 +32,15 @@ The following two lines of the ``build.gradle`` file define the Corda version us .. sourcecode:: groovy - ext.corda_release_version = '0.13.0' - ext.corda_gradle_plugins_version = '0.13.3' + ext.corda_release_version = '1.0.0' + ext.corda_gradle_plugins_version = '1.0.0' -In this case, our CorDapp will use the Milestone 13 release of Corda, and version 13.3 of the Corda gradle plugins. You -can find the latest published version of both here: https://bintray.com/r3/corda. +In this case, our CorDapp will use: + +* Version 1.0 of Corda +* Version 1.0 of the Corda gradle plugins + +You can find the latest published version of both here: https://bintray.com/r3/corda. ``corda_gradle_plugins_versions`` are given in the form ``major.minor.patch``. You should use the same ``major`` and ``minor`` versions as the Corda version you are using, and the latest ``patch`` version. A list of all the available @@ -61,34 +48,39 @@ versions can be found here: https://bintray.com/r3/corda/cordformation. In certain cases, you may also wish to build against the unstable Master branch. See :doc:`building-against-master`. -Building against CorDapps -------------------------- +Corda dependencies +^^^^^^^^^^^^^^^^^^ +The ``cordformation`` plugin adds: -To build against a Cordapp you must add it as a ``cordapp`` dependency to your ``build.gradle``. +* ``cordaCompile`` as a new configuration that ``compile`` extends from +* ``cordaRuntime`` which ``runtime`` extends from -Other Dependencies ------------------- +To build against Corda you must add the following to your ``build.gradle`` file; +* The ``net.corda:corda:`` JAR as a ``cordaRuntime`` dependency +* Each compile dependency (eg ``corda-core``) as a ``cordaCompile`` dependency + +To use Corda's test facilities you must add ``net.corda:corda-test-utils:`` as a ``testCompile`` dependency +(i.e. a default Java/Kotlin test compile task). + +.. warning:: Never include ``corda-test-utils`` as a ``compile`` or ``cordaCompile`` dependency. + +Dependencies on other CorDapps +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Sometimes, a CorDapp you build will depend on states, contracts or flows defined in another CorDapp. You must include +the CorDapp your CorDapp depends upon as a ``cordapp`` dependency in your ``build.gradle`` file. + +Other dependencies +^^^^^^^^^^^^^^^^^^ If your CorDapps have any additional external dependencies, they can be specified like normal Kotlin/Java dependencies in Gradle. See the example below, specifically the ``apache-commons`` include. For further information about managing dependencies, see `the Gradle docs `_. -Installing CorDapps -------------------- - -At runtime, nodes will load any plugins present in their ``plugins`` folder. Therefore in order to install a cordapp to -a node the cordapp JAR must be added to the ``/plugins/`` folder, where ``node_dir`` is the folder in which the -node's JAR and configuration files are stored). - -The ``deployNodes`` gradle task, if correctly configured, will automatically place your cordapp JAR as well as any -dependent cordapp JARs specified into the directory automatically. - Example -------- - -The following is a sample of what a gradle dependencies block for a cordapp could look like. The cordapp template +^^^^^^^ +The following is a sample of what a gradle dependencies block for a CorDapp could look like. The CorDapp template is already correctly configured and this is for reference only; .. container:: codeset @@ -108,6 +100,9 @@ is already correctly configured and this is for reference only; testCompile "net.corda:corda-test-utils:$corda_release_version" // Corda Plugins: dependent flows and services + // Identifying a CorDapp by its module in the same project. + cordapp project(":cordapp-contracts-states") + // Identifying a CorDapp by its fully-qualified name. cordapp "net.corda:bank-of-corda-demo:1.0" // Some other dependencies @@ -118,3 +113,29 @@ is already correctly configured and this is for reference only; compile "org.apache.commons:commons-lang3:3.6" } +Creating the CorDapp JAR +------------------------ +The gradle ``jar`` task included in the CorDapp template build file will automatically build your CorDapp JAR correctly +as long as your dependencies are set correctly. + +Note that the hash of the resulting CorDapp JAR is not deterministic, as it depends on variables such as the timestamp +at creation. Nodes running the same CorDapp must therefore ensure they are using the exact same CorDapp jar, and not +different versions of the JAR created from identical sources. + +The filename of the JAR must include a unique identifier to deduplicate it from other releases of the same CorDapp. +This is typically done by appending the version string to the CorDapp's name. This unique identifier should not change +once the JAR has been deployed on a node. If it does, make sure no one is relying on ``FlowContext.appName`` in their +flows (see :doc:`versioning`). + +Installing the CorDapp jar +-------------------------- + +.. note:: Before installing a CorDapp, you must create one or more nodes to install it on. For instructions, please see + :doc:`deploying-a-node`. + +At runtime, nodes will load any plugins present in their ``plugins`` folder. Therefore in order to install a CorDapp on +a node, the CorDapp JAR must be added to the ``/plugins/`` folder, where ``node_dir`` is the folder in which +the node's JAR and configuration files are stored. + +The ``deployNodes`` gradle task, if correctly configured, will automatically place your CorDapp JAR as well as any +dependent CorDapp JARs specified into the ``plugins`` folder automatically. \ No newline at end of file diff --git a/docs/source/cordapp-overview.rst b/docs/source/cordapp-overview.rst index 6ac7bbedd3..36c845036a 100644 --- a/docs/source/cordapp-overview.rst +++ b/docs/source/cordapp-overview.rst @@ -1,25 +1,30 @@ What is a CorDapp? ================== -Corda is a platform. Its functionality is extended by developers through the writing of Corda distributed -applications (CorDapps). CorDapps are installed at the level of the individual node, rather than on the network -itself. - -Each CorDapp allows a node to handle new business processes, for example asset trading (see :ref:`irs-demo`). -It does so by defining new flows on the node that, once started by the node owner, conduct the process of negotiating -a specific ledger update with other nodes on the network. The node's owner can then start these flows as required, -either through remote procedure calls (RPC) or HTTP requests that leverage the RPC interface. +CorDapps (Corda Distributed Applications) are distributed applications that run on the Corda platform. The goal of a +CorDapp is to allow nodes to reach agreement on updates to the ledger. They achieve this goal by defining flows that +Corda node owners can invoke through RPC calls: .. image:: resources/node-diagram.png -CorDapp developers will usually define not only these flows, but also any states and contracts that these flows use. -They will also have to define any web APIs that will run on the node's standalone web server, any static web content, -and any new services that they want their CorDapp to offer. +CorDapps are made up of the following key components: -CorDapps are made up of definitions for the following components: +* States, defining the facts over which agreement is reached (see :doc:`Key Concepts - States `) +* Contracts, defining what constitutes a valid ledger update (see + :doc:`Key Concepts - Contracts `) +* Services, providing long-lived utilities within the node +* Serialisation whitelists, restricting what types your node will receive off the wire -* States -* Contracts -* Flows -* Web APIs and static web content -* Services \ No newline at end of file +Each CorDapp is installed at the level of the individual node, rather than on the network itself. For example, a node +owner may choose to install the Bond Trading CorDapp, with the following components: + +* A ``BondState``, used to represent bonds as shared facts on the ledger +* A ``BondContract``, used to govern which ledger updates involving ``BondState`` states are valid +* Three flows: + + * An ``IssueBondFlow``, allowing new ``BondState`` states to be issued onto the ledger + * A ``TradeBondFlow``, allowing existing ``BondState`` states to be bought and sold on the ledger + * An ``ExitBondFlow``, allowing existing ``BondState`` states to be exited from the ledger + +After installing this CorDapp, the node owner will be able to use the flows defined by the CorDapp to agree ledger +updates related to issuance, sale, purchase and exit of bonds. \ No newline at end of file diff --git a/docs/source/deploying-a-node.rst b/docs/source/deploying-a-node.rst index 562df5952f..555e2eb028 100644 --- a/docs/source/deploying-a-node.rst +++ b/docs/source/deploying-a-node.rst @@ -1,97 +1,140 @@ Deploying a node ================ -Using Gradle to build nodes ---------------------------- -Nodes are usually built using a Gradle task. The canonical Gradle file for building nodes is the one used by the -CorDapp template. Both a `Java version `_ and -a `Kotlin version `_ are available. +Node structure +-------------- +Each Corda node has the following structure: -Cordform is the local node deployment system for CorDapps. The nodes generated are intended for experimenting, -debugging, and testing node configurations, but not for production or testnet deployment. +.. sourcecode:: none -Here is an example Gradle task called ``deployNodes`` that uses the Cordform plugin to deploy three nodes, plus a -notary/network map node: + . + ├── certificates // The node's doorman certificates + ├── corda-webserver.jar // The built-in node webserver + ├── corda.jar // The core Corda libraries + ├── logs // The node logs + ├── node.conf // The node's configuration files + ├── persistence.mv.db // The node's database + └── plugins // The CorDapps jars installed on the node + +The node is configured by editing its ``node.conf`` file. You install CorDapps on the node by dropping the CorDapp JARs +into the ``plugins`` folder. + +Node naming +----------- +A node's name must be a valid X500 name that obeys the following additional constraints: + +* The fields of the name have the following maximum character lengths: + + * Common name: 64 + * Organisation: 128 + * Organisation unit: 64 + * Locality: 64 + * State: 64 + +* The country code is a valid ISO 3166-1 two letter code in upper-case + +* The organisation, locality and country attributes are present + +* The organisation field of the name obeys the following constraints: + + * Has at least two letters + * No leading or trailing whitespace + * No double-spacing + * Upper-case first letter + * Does not contain the words "node" or "server" + * Does not include the characters ',' or '=' or '$' or '"' or '\'' or '\\' + * Is in NFKC normalization form + * Only the latin, common and inherited unicode scripts are supported + +The deployNodes task +-------------------- +The CorDapp template defines a ``deployNodes`` task that allows you to automatically generate and configure a set of +nodes: .. sourcecode:: groovy task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { directory "./build/nodes" - networkMap "O=Controller,OU=corda,L=London,C=UK" + networkMap "O=Controller,L=London,C=GB" node { - name "O=Controller,OU=corda,L=London,C=UK" + name "O=Controller,L=London,C=GB" + // The notary will offer a validating notary service. + // Set to `corda.notary.simple` for a non-validating notary. advertisedServices = ["corda.notary.validating"] - p2pPort 10002 - rpcPort 10003 - webPort 10004 - cordapps = [] + p2pPort 10002 + rpcPort 10003 + // No webport property, so no webserver will be created. + h2Port 10004 + sshdPort 22 + // Includes the corda-finance CorDapp on our node. + cordapps = ["net.corda:corda-finance:$corda_release_version"] } node { - name "CN=NodeA,O=NodeA,L=London,C=UK" + name "O=PartyA,L=London,C=GB" advertisedServices = [] - p2pPort 10005 - rpcPort 10006 - webPort 10007 - cordapps = [] - rpcUsers = [[ user: "user1", "password": "test", "permissions": []]] + p2pPort 10005 + rpcPort 10006 + webPort 10007 + h2Port 10008 + sshdPort 22 + cordapps = ["net.corda:corda-finance:$corda_release_version"] + // Grants user1 all RPC permissions. + rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]] } node { - name "CN=NodeB,O=NodeB,L=New York,C=US" + name "O=PartyB,L=New York,C=US" advertisedServices = [] - p2pPort 10008 - rpcPort 10009 - webPort 10010 - 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": []]] + p2pPort 10009 + rpcPort 10010 + webPort 10011 + h2Port 10012 + sshdPort 22 + cordapps = ["net.corda:corda-finance:$corda_release_version"] + // Grants user1 the ability to start the MyFlow flow. + rpcUsers = [[ user: "user1", "password": "test", "permissions": ["StartFlow.net.corda.flows.MyFlow"]]] } } -You can extend ``deployNodes`` to generate any number of nodes you like. The only requirement is that you must specify -one node as running the network map service, by putting their name in the ``networkMap`` field. In our example, the -``Controller`` is set as the network map service. +Running this task will create three nodes in the ``build/nodes`` folder: + +* A ``Controller`` node that: + + * Serves as the network map + * Offers a validating notary service + * Will not have a webserver (since ``webPort`` is not defined) + * Is running the ``corda-finance`` CorDapp + +* ``PartyA`` and ``PartyB`` nodes that: + + * Are pointing at the ``Controller`` as the network map service + * Are not offering any services + * Will have a webserver (since ``webPort`` is defined) + * Are running the ``corda-finance`` CorDapp + * Have an RPC user, ``user1``, that can be used to log into the node via RPC + +Additionally, all three nodes will include any CorDapps defined in the project's source folders, even though these +CorDapps are not listed in each node's ``cordapps`` entry. This means that running the ``deployNodes`` task from the +template CorDapp, for example, would automatically build and add the template CorDapp to each node. + +You can extend ``deployNodes`` to generate additional nodes. The only requirement is that you must specify +a single node to run the network map service, by putting their name in the ``networkMap`` field. .. warning:: When adding nodes, make sure that there are no port clashes! -If your CorDapp is written in Java, you should also add the following Gradle snippet so that you can pass named arguments to your flows via the Corda shell: - -.. sourcecode:: groovy - - tasks.withType(JavaCompile) { - options.compilerArgs << "-parameters" - } - -Any CorDapps defined in the project's source folders are also automatically registered with all the nodes defined in -``deployNodes``, even if the CorDapps are not listed in each node's ``cordapps`` entry. - -Deploying your nodes --------------------- -You deploy a set of nodes by running your ``build.gradle`` file's Cordform task. For example, if we were using the -standard ``deployNodes`` task defined above, we'd create our nodes by running the following commands in a terminal -window from the root of the project: +Running deployNodes +------------------- +To create the nodes defined in our ``deployNodes`` task, we'd run the following command in a terminal window from the +root of the project: * Unix/Mac OSX: ``./gradlew deployNodes`` * Windows: ``gradlew.bat deployNodes`` -After the build process has finished, you will find the newly-built nodes under ``kotlin-source/build/nodes``. There -will be one folder generated for each node you built, plus a ``runnodes`` shell script (or batch file on Windows) to -run all the nodes at once. Each node in the ``nodes`` folder has the following structure: +This will create the nodes in the ``build/nodes`` folder. -.. sourcecode:: none +.. warning:: Outside of development environments, do not store your node directories in the build folder. - . nodeName - ├── corda.jar // The Corda runtime - ├── node.conf // The node's configuration - └── plugins // Any installed CorDapps +There will be a node folder generated for each node you defined, plus a ``runnodes`` shell script (or batch file on +Windows) to run all the nodes at once. If you make any changes to your ``deployNodes`` task, you will need to re-run +the task to see the changes take effect. -.. note:: Outside of development environments, do not store your node directories in the build folder. - -If you make any changes to your ``deployNodes`` task, you will need to re-run the task to see the changes take effect. +You can now run the nodes by following the instructions in :doc:`Running a node `. \ No newline at end of file diff --git a/docs/source/quickstart-index.rst b/docs/source/quickstart-index.rst index 02e9045ac9..a42b469e95 100644 --- a/docs/source/quickstart-index.rst +++ b/docs/source/quickstart-index.rst @@ -7,5 +7,4 @@ Quickstart getting-set-up tutorial-cordapp Sample CorDapps - building-against-master CLI-vs-IDE \ No newline at end of file diff --git a/docs/source/serialization.rst b/docs/source/serialization.rst index 92d542dd71..c153a60ff6 100644 --- a/docs/source/serialization.rst +++ b/docs/source/serialization.rst @@ -23,7 +23,6 @@ Classes get onto the whitelist via one of three mechanisms: class itself, on any of the super classes or on any interface implemented by the class or super classes or any interface extended by an interface implemented by the class or superclasses. #. By implementing the ``SerializationWhitelist`` interface and specifying a list of `whitelist` classes. - See :doc:`writing-cordapps`. #. Via the built in Corda whitelist (see the class ``DefaultWhitelist``). Whilst this is not user editable, it does list common JDK classes that have been whitelisted for your convenience. diff --git a/docs/source/writing-a-cordapp.rst b/docs/source/writing-a-cordapp.rst new file mode 100644 index 0000000000..dd8d1662d3 --- /dev/null +++ b/docs/source/writing-a-cordapp.rst @@ -0,0 +1,146 @@ +Writing a CorDapp +================= + +.. contents:: + +Overview +-------- +CorDapps can be written in either Java, Kotlin, or a combination of the two. Each CorDapp component takes the form +of a JVM class that subclasses or implements a Corda library type: + +* Flows subclass ``FlowLogic`` +* States implement ``ContractState`` +* Contracts implement ``Contract`` +* Services subclass ``SingletonSerializationToken`` +* Serialisation whitelists implement ``SerializationWhitelist`` + +Web content and RPC clients +--------------------------- +For testing purposes, CorDapps may also include: + +* **APIs and static web content**: These are served by Corda's built-in webserver. This webserver is not + production-ready, and should be used for testing purposes only + +* **RPC clients**: These are programs that automate the process of interacting with a node via RPC + +In production, a production-ready webserver should be used, and these files should be moved into a different module or +project so that they do not bloat the CorDapp at build time. + +Structure +--------- +You should base the structure of your project on the Java or Kotlin templates: + +* `Java Template CorDapp `_ +* `Kotlin Template CorDapp `_ + +The project should be split into two modules: + +* A ``cordapp-contracts-states`` module containing classes such as contracts and states that will be sent across the + wire as part of a flow +* A ``cordapp`` module containing the remaining classes + +Each module will be compiled into its own CorDapp. This minimises the size of the JAR that has to be sent across the +wire when nodes are agreeing ledger updates. + +Module one - cordapp-contracts-states +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Here is the structure of the ``src`` directory for the ``cordapp-contracts-states`` module: + +.. parsed-literal:: + + . + └── main + └── java + └── com + └── template + ├── TemplateContract.java + └── TemplateState.java + +The directory only contains two class definitions: + +* ``TemplateContract`` +* ``TemplateState`` + +These are definitions for classes that we expect to have to send over the wire. They will be compiled into their own +CorDapp. + +Module two - cordapp +^^^^^^^^^^^^^^^^^^^^ +Here is the structure of the ``src`` directory for the ``cordapp`` module: + +.. parsed-literal:: + + . + ├── main + │   ├── java + │   │   └── com + │   │   └── template + │   │   ├── TemplateApi.java + │   │   ├── TemplateClient.java + │   │   ├── TemplateFlow.java + │   │   ├── TemplateSerializationWhitelist.java + │   │   └── TemplateWebPlugin.java + │   └── resources + │   ├── META-INF + │   │   └── services + │   │   ├── net.corda.core.serialization.SerializationWhitelist + │   │   └── net.corda.webserver.services.WebServerPluginRegistry + │   ├── certificates + │   └── templateWeb + ├── test + │ └── java + │ └── com + │ └── template + │ ├── ContractTests.java + │ ├── FlowTests.java + │ └── NodeDriver.java + └── integrationTest +    └── java +    └── com +    └── template +    └── DriverBasedTest.java + +The ``src`` directory is structured as follows: + +* ``main`` contains the source of the CorDapp +* ``test`` contains example unit tests, as well as a node driver for running the CorDapp from IntelliJ +* ``integrationTest`` contains an example integration test + +Within ``main``, we have the following directories: + +* ``resources/META-INF/services`` contains registries of the CorDapp's serialisation whitelists and web plugins +* ``resources/certificates`` contains dummy certificates for test purposes +* ``resources/templateWeb`` contains a dummy front-end +* ``java`` (or ``kotlin`` in the Kotlin template), which includes the source-code for our CorDapp + +The source-code for our CorDapp breaks down as follows: + +* ``TemplateFlow.java``, which contains a dummy ``FlowLogic`` subclass +* ``TemplateState.java``, which contains a dummy ``ContractState`` implementation +* ``TemplateContract.java``, which contains a dummy ``Contract`` implementation +* ``TemplateSerializationWhitelist.java``, which contains a dummy ``SerializationWhitelist`` implementation + +In developing your CorDapp, you should start by modifying these classes to define the components of your CorDapp. A +single CorDapp can define multiple flows, states, and contracts. + +The template also includes a web API and RPC client: + +* ``TemplateApi.java`` +* ``TemplateClient.java`` +* ``TemplateWebPlugin.java`` + +These are for testing purposes and would be removed in a production CorDapp. + +Resources +--------- +In writing a CorDapp, you should consult the following resources: + +* :doc:`Getting Set Up ` to set up your development environment +* The :doc:`Hello, World! tutorial ` to write your first CorDapp +* :doc:`Building a CorDapp ` to build and run your CorDapp +* The :doc:`API docs ` to read about the API available in developing CorDapps + + * There is also a :doc:`cheatsheet ` recapping the key types + +* The :doc:`Flow cookbook ` to see code examples of how to perform common flow tasks +* `Sample CorDapps `_ showing various parts of Corda's functionality \ No newline at end of file diff --git a/docs/source/writing-cordapps.rst b/docs/source/writing-cordapps.rst deleted file mode 100644 index 55eda0e091..0000000000 --- a/docs/source/writing-cordapps.rst +++ /dev/null @@ -1,61 +0,0 @@ -Writing a CorDapp -================= - -When writing a CorDapp, you are writing a set of files in a JVM language that defines one or more of the following -Corda components: - -* States (i.e. classes implementing ``ContractState``) -* Contracts (i.e. classes implementing ``Contract``) -* Flows (i.e. classes extending ``FlowLogic``) -* Web APIs -* Services - -CorDapp structure ------------------ -Your CorDapp project's structure should be based on the structure of the -`Java Template CorDapp `_ or the -`Kotlin Template CorDapp `_, depending on which language you intend -to use. - -The ``src`` directory of the Template CorDapp, where we define our CorDapp's source-code, has the following structure: - -.. parsed-literal:: - - src - ├── main - │ ├── java - │ │ └── com - │ │ └── template - │ │ ├── Main.java - │ │ ├── api - │ │ │ └── TemplateApi.java - │ │ ├── client - │ │ │ └── TemplateClientRPC.java - │ │ ├── contract - │ │ │ └── TemplateContract.java - │ │ ├── flow - │ │ │ └── TemplateFlow.java - │ │ ├── plugin - │ │ │ └── TemplatePlugin.java - │ │ ├── service - │ │ │ └── TemplateService.java - │ │ └── state - │ │ └── TemplateState.java - │ └── resources - │ ├── META-INF - │ │ └── services - │ │ ├── net.corda.core.serialization.SerializationWhitelist - │ │ └── net.corda.webserver.services.WebServerPluginRegistry - │ ├── certificates - │ │ ├── sslkeystore.jks - │ │ └── truststore.jks - │ └──templateWeb - │ ├── index.html - │ └── js - │ └── template-js.js - └── test - └── java - └── com - └── template - └── contract - └── TemplateTests.java \ No newline at end of file