Skip to content
This repository has been archived by the owner on May 15, 2020. It is now read-only.

Java yo cordapp #85

Open
wants to merge 3 commits into
base: release-V4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion yo-cordapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ See https://docs.corda.net/getting-set-up.html.

See https://docs.corda.net/tutorial-cordapp.html#running-the-example-cordapp.

Java
``./gradlew deployNodesJava``

Kotlin
``./gradlew deployNodesKotlin``

then
``./build/nodes/runnodes``


### Sending Yo!s

We will interact with the nodes via their shell. When the nodes are up and running, use the following command to send a
Expand All @@ -28,4 +38,4 @@ X500 name in the node shell. Note you can't sent a Yo! to yourself because that'

To see all the Yo's! other nodes have sent you in your vault (you do not store the Yo's! you send yourself), run:

run vaultQuery contractStateType: com.yo.states.YoState
run vaultQuery contractStateType: net.corda.examples.yo.states.YoState
56 changes: 51 additions & 5 deletions yo-cordapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ allprojects {
maven { url 'https://jitpack.io' }
}


tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters" // Required for shell commands.
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
languageVersion = "1.2"
Expand Down Expand Up @@ -77,8 +82,10 @@ dependencies {
cordaRuntime "$corda_release_group:corda:$corda_release_version"

// CorDapp dependencies.
cordapp project(":workflows")
cordapp project(":contracts")
cordapp project(":workflows-kotlin")
cordapp project(":contracts-kotlin")
cordapp project(":workflows-java")
cordapp project(":contracts-java")

cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}"
Expand All @@ -94,13 +101,52 @@ cordapp {
}
}

task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
task deployNodesJava(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
nodeDefaults {
projectCordapp {
deploy = false
}
cordapp project(':contracts-java')
cordapp project(':workflows-java')
}
node {
name "O=Notary,L=London,C=GB"
notary = [validating : false]
p2pPort 10002
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10043")
}
}
node {
name "O=PartyA,L=London,C=GB"
p2pPort 10005
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10046")
}
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
}
node {
name "O=PartyB,L=New York,C=US"
p2pPort 10008
rpcSettings {
address("localhost:10009")
adminAddress("localhost:10049")
}
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
}

}


task deployNodesKotlin(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
nodeDefaults {
projectCordapp {
deploy = false
}
cordapp project(':contracts')
cordapp project(':workflows')
cordapp project(':contracts-kotlin')
cordapp project(':workflows-kotlin')
}
node {
name "O=Notary,L=London,C=GB"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package net.corda.examples.yo.contracts;

import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.CommandWithParties;
import net.corda.core.contracts.Contract;
import net.corda.core.transactions.LedgerTransaction;
import net.corda.examples.yo.states.YoState;
import org.jetbrains.annotations.NotNull;

import static net.corda.core.contracts.ContractsDSL.*;

// ************
// * Contract *
// ************
// Contract and state.
public class YoContract implements Contract {
// Used to identify our contract when building a transaction.
public static final String ID = "net.corda.examples.yo.contracts.YoContract";

// Contract code.
@Override
public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException {
CommandWithParties<Commands.Send> command = requireSingleCommand(tx.getCommands(), Commands.Send.class);
requireThat(req -> {
req.using("There can be no inputs when Yo'ing other parties", tx.getInputs().isEmpty());
req.using("There must be one output: The Yo!", tx.getOutputs().size() == 1);
YoState yo = tx.outputsOfType(YoState.class).get(0);
req.using("No sending Yo's to yourself!", !yo.getTarget().equals(yo.getOrigin()));
req.using("The Yo! must be signed by the sender.", command.getSigners().contains(yo.getOrigin().getOwningKey()));
return null;
});
}

// Used to indicate the transaction's intent.
public interface Commands extends CommandData {
class Send implements Commands {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package net.corda.examples.yo.states;

import com.google.common.collect.ImmutableList;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
import net.corda.core.identity.Party;
import net.corda.core.serialization.ConstructorForDeserialization;
import net.corda.core.serialization.CordaSerializable;
import net.corda.examples.yo.contracts.YoContract;
import org.jetbrains.annotations.NotNull;

import java.util.List;

// *********
// * State *
// *********
@BelongsToContract(YoContract.class)
public class YoState implements ContractState {
private final Party origin;
private final Party target;
private final String yo;

@ConstructorForDeserialization
public YoState(Party origin, Party target, String yo) {
this.origin = origin;
this.target = target;
this.yo = yo;
}

public YoState(Party origin, Party target) {
this.origin = origin;
this.target = target;
this.yo = "Yo!";
}

public Party getOrigin() {
return origin;
}

public Party getTarget() {
return target;
}

public String getYo() {
return yo;
}

@NotNull
@Override
public List<AbstractParty> getParticipants() {
return ImmutableList.of(target);
}

@Override
public String toString() {
return origin.getName() + ": " + yo;
}
}
21 changes: 21 additions & 0 deletions yo-cordapp/contracts-kotlin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apply plugin: 'net.corda.plugins.cordapp'

cordapp {
targetPlatformVersion corda_platform_version
minimumPlatformVersion corda_platform_version
contract {
name "yo CorDapp"
vendor "Corda Open Source"
licence "Apache License, Version 2.0"
versionId 1
}
}

dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

// Corda dependencies.
cordaCompile "$corda_release_group:corda-core:$corda_release_version"

testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
}
6 changes: 4 additions & 2 deletions yo-cordapp/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
include 'workflows'
include 'contracts'
include 'workflows-kotlin'
include 'contracts-kotlin'
include 'workflows-java'
include 'contracts-java'
58 changes: 58 additions & 0 deletions yo-cordapp/workflows-java/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.quasar-utils'

cordapp {
targetPlatformVersion corda_platform_version
minimumPlatformVersion corda_platform_version
workflow {
name "yo Flows"
vendor "Corda Open Source"
licence "Apache License, Version 2.0"
versionId 1
}
}

sourceSets {
main {
resources {
srcDir rootProject.file("config/dev")
}
}
test {
resources {
srcDir rootProject.file("config/test")
}
}
integrationTest {
kotlin {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integrationTest/java')
}
}
}

configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
}

dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"

// Corda dependencies.
cordaCompile "$corda_release_group:corda-core:$corda_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"

testCompile "$corda_release_group:corda-node-driver:$corda_release_version"

// CorDapp dependencies.
cordapp project(":contracts-java")
}

task integrationTest(type: Test, dependsOn: []) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package net.corda.examples.yo;

import net.corda.core.identity.CordaX500Name;
import net.corda.testing.core.TestIdentity;
import net.corda.testing.driver.Driver;
import net.corda.testing.driver.DriverParameters;
import net.corda.testing.driver.NodeHandle;
import net.corda.testing.driver.NodeParameters;
import org.junit.Test;

import java.util.Objects;
import java.util.concurrent.ExecutionException;

public class DriverBasedTest {
private final TestIdentity bankA = new TestIdentity(new CordaX500Name("BankA", "", "GB"));
private final TestIdentity bankB = new TestIdentity(new CordaX500Name("BankB", "", "US"));

@Test
public void nodeTest() {
Driver.driver(new DriverParameters().withStartNodesInProcess(true).withIsDebug(true), driverDSL -> {
NodeHandle partyAHandle = null;
NodeHandle partyBHandle = null;
try {
// Start a pair of nodes and wait for them both to be ready.
partyAHandle = driverDSL.startNode(new NodeParameters().withProvidedName(bankA.getName())).get();
partyBHandle = driverDSL.startNode(new NodeParameters().withProvidedName(bankB.getName())).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}

// From each node, make an RPC call to retrieve another node's name from the network map, to verify that the
// nodes have started and can communicate.

// This is a very basic test: in practice tests would be starting flows, and verifying the states in the vault
// and other important metrics to ensure that your CorDapp is working as intended.
assert partyAHandle != null;
assert partyBHandle != null;
assert (bankB.getName().equals(Objects.requireNonNull(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName())).getName()));
assert (bankA.getName().equals(Objects.requireNonNull(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName())).getName()));
return null;
});
}
}
Loading