diff --git a/.gitignore b/.gitignore
index c504d501..d08af3e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,8 +5,9 @@
**/bin/
*/.gradle/
*/.idea/*
-*/.vscode/*
+**/.vscode/*
**/out/
**/logs/
+**/node_modules/
corda-nodeinfo/corda-nodeinfo.iml
*~*
diff --git a/Accounts/README.md b/Accounts/README.md
index ab4c69b3..f304320a 100644
--- a/Accounts/README.md
+++ b/Accounts/README.md
@@ -1,14 +1,21 @@
-## samples-java/Accounts
+## Accounts CorDapp Samples
-This folder features Corda Accounts sample projects.
+This folder features Corda Accounts sample projects. Learn more about [Accounts](https://training.corda.net/libraries/accounts-lib/).
### [Supply Chain](./supplychain):
-This CorDapp mimics a supply chain transaction, where the deal is incorporated among different teams in the companies on both side of the trade.
+
+This CorDapp mimics a supply chain transaction, where the deal is incorporated among different teams in the companies on both side of the trade.
+
+
+
### [Tic Tac Thor](./tictacthor):
-This CorDapp recreates the game of Tic Tac Toe via Corda. It primarilly demonstrates how you can have linear state transactions between cross-node accounts.
+This CorDapp recreates the game of Tic Tac Toe via Corda. It primarily demonstrates how you can have LinearState transactions between cross-node accounts.
+
+
+
-### [Worldcup Ticket Booking](./worldcupticketbooking):
-This CorDapp demonstrates an ticket booking system with a collaboration of Corda Account Libray and TokenSDK.
+### [World Cup Ticket Booking](./worldcupticketbooking):
+This sample shows you how to integrate accounts and tokens. This sample talks about a scenario where typically when the Cricket season starts, BCCI (Board of Control for Cricket) starts selling tickets. As of now there are multiple dealers whom the BCCI issues tickets and further these dealers sell tickets to their client. We are trying to simulate similar functionality maintaining the entire issuance and selling of the tickets on Corda Platform.
\ No newline at end of file
diff --git a/Accounts/constants.properties b/Accounts/constants.properties
index 0b0f28b2..adcdb361 100644
--- a/Accounts/constants.properties
+++ b/Accounts/constants.properties
@@ -1,12 +1,12 @@
cordaReleaseGroup=net.corda
cordaCoreReleaseGroup=net.corda
-cordaVersion=4.5-RC02
-cordaCoreVersion=4.5-RC02
-gradlePluginsVersion=5.0.10
+cordaVersion=4.10
+cordaCoreVersion=4.10
+gradlePluginsVersion=5.0.12
kotlinVersion=1.2.71
junitVersion=4.12
quasarVersion=0.7.10
-log4jVersion =2.11.2
-platformVersion=5
+log4jVersion =2.17.1
+platformVersion=12
slf4jVersion=1.7.25
nettyVersion=4.1.22.Final
diff --git a/Accounts/supplychain/Business Flow.png b/Accounts/supplychain/Business_Flow.png
similarity index 100%
rename from Accounts/supplychain/Business Flow.png
rename to Accounts/supplychain/Business_Flow.png
diff --git a/Accounts/supplychain/README.md b/Accounts/supplychain/README.md
index a3cde403..87168170 100644
--- a/Accounts/supplychain/README.md
+++ b/Accounts/supplychain/README.md
@@ -1,18 +1,24 @@
# Accounts_SupplyChain
-For More information regarding the Accounts Library, please read at: https://github.com/corda/accounts/blob/master/docs.md
+For more information regarding the Accounts Library, please read at: https://github.com/corda/accounts/blob/master/docs.md
This sample describes a mock/simple supply chain business flow.
-From the above chart, you can see the flow is going back and forth between different parties' accounts. Please follow the instruction below to experience the Accounts library.
-# Setting up
+From the above chart, you can see the flow is going back and forth between different parties' accounts. Please follow the instruction below to experience the [Accounts](https://training.corda.net/libraries/accounts-lib/) library.
+
+
+## Pre-Requisites
+
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.9/community/getting-set-up.html).
+
+## Runnning the nodes
Go into the project directory and build the project
```
-./gradlew clean deployNodes
+./gradlew clean build deployNodes
```
Run the project
```
@@ -20,7 +26,7 @@ Run the project
```
Now, you should have four Corda terminals opened automatically.
-# Shell Instructions (Part 1) - Creating & Sharing Accounts
+## Shell Instructions (Part 1) - Creating & Sharing Accounts
Go to the Buyer's node terminal and paste in the following code: (You can select all 7 lines and copy to the terminal all at once)
```
flow start CreateNewAccount acctName: BuyerProcurement
@@ -32,7 +38,7 @@ flow start ShareAccountTo acctNameShared: BuyerFinance, shareTo: Seller
flow start ShareAccountTo acctNameShared: BuyerWarehouse, shareTo: ShippingCo
flow start ShareAccountTo acctNameShared: BuyerWarehouse, shareTo: Seller
```
-This is creating 3 accounts under Buyer's node and sharing with their specific conterpartie's node or account.
+This is creating 3 accounts under Buyer's node and sharing with their specific counterparty's node or account.
Go to the Seller's node terminal and paste in the following code:
```
@@ -44,14 +50,14 @@ flow start ShareAccountTo acctNameShared: SellerSales, shareTo: Buyer
flow start ShareAccountTo acctNameShared: SellerFinance, shareTo: Buyer
flow start ShareAccountTo acctNameShared: SellerInventory, shareTo: ShippingCo
```
-This is creating 3 accounts under Seller's node and sharing with their specific conterpartie's node or account.
+This is creating 3 accounts under Seller's node and sharing with their specific counterparty's node or account.
-[Optional]: You can run a vaultQuery to see the accoutnInfo that been stored at each node by using:
+[Optional]: You can run a vaultQuery to see the [AccountInfo](https://training.corda.net/libraries/accounts-lib/#design) that been stored at each node by using:
```
run vaultQuery contractStateType: com.r3.corda.lib.accounts.contracts.states.AccountInfo
```
-# Shell Instructions (Part 2) - Executing Business Flows
-## Step 1: Seller's sales team send inovice of $500 to Buyer's procurement team
+## Shell Instructions (Part 2) - Executing Business Flows
+### Step 1: Seller's sales team send invoice for $500 to Buyer's procurement team
navigate to Seller's node terminal and run
```
flow start SendInvoice whoAmI: SellerSales, whereTo: BuyerProcurement, amount: 500
@@ -62,42 +68,42 @@ flow start ViewInboxByAccount acctname: BuyerProcurement
```
You see that the invoice state amount 500 is returned. You can also replace the BuyerProcurement with BuyerWarehouse to see that the non-relevant accounts has no visiblity about the invoice state.
-## Step 2: Buyer's procurement team will send an internal message to Buyer's Buyer's finance team
+### Step 2: Buyer's procurement team will send an internal message to Buyer's Buyer's finance team
Navigate to Buyer's node terminal and type in:
```
flow start InternalMessage fromWho: BuyerProcurement, whereTo: BuyerFinance, message: Send 500 to SellerFinance
```
[Optional verification]: run ```flow start ViewInboxByAccount acctname: BuyerFinance``` at Buyer' node terminal
-## Step 3: Buyer's finance team send a payment to Seller's finance team
-Navigatie to Buyer's node terminal and type in:
+### Step 3: Buyer's finance team send a payment to Seller's finance team
+Navigate to Buyer's node terminal and type in:
```
flow start SendPayment whoAmI: BuyerFinance, whereTo: SellerFinance, amount: 500
```
[Optional verification]: run ```flow start ViewInboxByAccount acctname: SellerFinance``` at Seller's node terminal
-## Step 4: Seller's finance team send an internal message to Seller's inventory team to instruct them to send the cargo
+### Step 4: Seller's finance team send an internal message to Seller's inventory team to instruct them to send the cargo
Navigate to Seller's node terminal and type in
```
flow start InternalMessage fromWho: SellerFinance, whereTo: SellerInventory, message: send Cargo to Buyer
```
[Optional verification]: run ```flow start ViewInboxByAccount acctname: SellerInventory``` at Seller's node terminal
-## step 5: Seller's inventory team send a shipping work order for shipping company
+### step 5: Seller's inventory team send a shipping work order for shipping company
Navigate to Seller's node terminal and type in
```
flow start SendShippingRequest whoAmI: SellerInventory, whereTo: BuyerWarehouse, shipper: ShippingCo, Cargo: 10 boxes of Books
```
-[Optional verification]: run ```run vaultQuery contractStateType: com.accounts_SupplyChain.states.ShippingRequestState``` at ShippingCo's node terminal
+[Optional verification]: run ```run vaultQuery contractStateType: ShippingRequestState``` at ShippingCo's node terminal
-## Step 6: Shipping company sends the cargo to Buyer's warehouse
+### Step 6: Shipping company sends the cargo to Buyer's warehouse
Navigate to ShippingCo's node terminal and type in
```
flow start SendCargo pickupFrom: SellerInventory, shipTo: BuyerWarehouse, cargo: Books
```
[Optional verification]: run ```flow start ViewInboxByAccount acctname: BuyerWarehouse``` at Buyer's node terminal
-## Now, the entire business chain is completed.
+### Now, the entire business chain is completed.
diff --git a/Accounts/supplychain/build.gradle b/Accounts/supplychain/build.gradle
index 3efc9205..4d70ff49 100644
--- a/Accounts/supplychain/build.gradle
+++ b/Accounts/supplychain/build.gradle
@@ -3,7 +3,6 @@ buildscript {
file("$projectDir/../constants.properties").withInputStream { constants.load(it) }
ext {
-
corda_release_group = constants.getProperty("cordaReleaseGroup")
corda_core_release_group = constants.getProperty("cordaCoreReleaseGroup")
corda_release_version = constants.getProperty("cordaVersion")
@@ -15,9 +14,11 @@ buildscript {
log4j_version = constants.getProperty("log4jVersion")
slf4j_version = constants.getProperty("slf4jVersion")
corda_platform_version = constants.getProperty("platformVersion").toInteger()
- //accounts
- accounts_release_version = '1.0'
+
+ //account
accounts_release_group = 'com.r3.corda.lib.accounts'
+ accounts_release_version = '1.0'
+ //CI
confidential_id_release_group = "com.r3.corda.lib.ci"
confidential_id_release_version = "1.0"
}
@@ -25,8 +26,7 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
+ maven { url 'https://download.corda.net/maven/corda-releases' }
}
dependencies {
@@ -42,12 +42,14 @@ allprojects {
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
- maven { url "https://repo.gradle.org/gradle/libs-releases-local" }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
+ maven { url 'https://jitpack.io' }
+ //SDK lib
+ maven { url 'https://download.corda.net/maven/corda-lib' }
+ //Gradle Plugins
+ maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
tasks.withType(JavaCompile) {
@@ -62,9 +64,6 @@ allprojects {
}
}
-
-
-
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
@@ -90,6 +89,8 @@ dependencies {
cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}"
cordaCompile "org.slf4j:jul-to-slf4j:$slf4j_version"
+ cordaDriver "net.corda:corda-shell:4.10"
+
//accounts
cordapp "$accounts_release_group:accounts-contracts:$accounts_release_version"
@@ -97,29 +98,6 @@ dependencies {
cordapp "$accounts_release_group:accounts-workflows:$accounts_release_version"
}
-cordapp {
- info {
- name "CorDapp supplychain"
- vendor "Corda Open Source"
- targetPlatformVersion corda_platform_version
- minimumPlatformVersion corda_platform_version
- }
-}
-
-task ganache {
- subprojects {
- if (it.project.name != "clients") {
- dependsOn jar
- doLast {
- copy {
- from "${buildDir}/libs"
- into "${rootDir}/build/libs"
- }
- }
- }
- }
-}
-
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
nodeDefaults {
projectCordapp {
@@ -131,6 +109,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapp project(":contracts")
cordapp project(":workflows")
+ runSchemaMigration = true
}
node {
name "O=Notary,L=London,C=GB"
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InvoiceStateContract.java b/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InvoiceStateContract.java
deleted file mode 100644
index e0f94689..00000000
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InvoiceStateContract.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.supplychain.contracts;
-
-import net.corda.core.contracts.CommandData;
-import net.corda.core.contracts.Contract;
-import net.corda.core.transactions.LedgerTransaction;
-
-// ************
-// * Contract *
-// ************
-public class InvoiceStateContract implements Contract {
- // This is used to identify our contract when building a transaction.
- public static final String ID = "com.supplychain.contracts.InvoiceStateContract";
-
- // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
- // does not throw an exception.
- @Override
- public void verify(LedgerTransaction tx) {}
-
- // Used to indicate the transaction's intent.
- public interface Commands extends CommandData {
- class Create implements Commands {}
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InvoiceState.java b/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InvoiceState.java
deleted file mode 100644
index 164111f6..00000000
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InvoiceState.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.supplychain.states;
-
-import com.supplychain.contracts.InvoiceStateContract;
-import net.corda.core.contracts.BelongsToContract;
-import net.corda.core.contracts.ContractState;
-import net.corda.core.identity.AbstractParty;
-import net.corda.core.identity.AnonymousParty;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-// *********
-// * State *
-// *********
-@BelongsToContract(InvoiceStateContract.class)
-public class InvoiceState implements ContractState {
-
- private int amount;
- private AnonymousParty sender;
- private AnonymousParty recipient;
- private UUID invoiceID;
- private List participants;
-
- public InvoiceState(int amount, AnonymousParty sender, AnonymousParty recipient, UUID invoiceID) {
- this.amount = amount;
- this.sender = sender;
- this.recipient = recipient;
- this.invoiceID = invoiceID;
- this.participants = new ArrayList();
- participants.add(recipient);
- participants.add(sender);
- }
-
- public int getAmount() {
- return amount;
- }
-
- public void setAmount(int amount) {
- this.amount = amount;
- }
-
- public AnonymousParty getSender() {
- return sender;
- }
-
- public void setSender(AnonymousParty sender) {
- this.sender = sender;
- }
-
- public AnonymousParty getRecipient() {
- return recipient;
- }
-
- public void setRecipient(AnonymousParty recipient) {
- this.recipient = recipient;
- }
-
- public UUID getInvoiceID() {
- return invoiceID;
- }
-
- public void setInvoiceID(UUID invoiceID) {
- this.invoiceID = invoiceID;
- }
-
- @Override
- public List getParticipants() {
- return this.participants;
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/CargoStateContract.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/CargoStateContract.java
similarity index 82%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/CargoStateContract.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/CargoStateContract.java
index 741765fe..6a2a704c 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/CargoStateContract.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/CargoStateContract.java
@@ -1,4 +1,4 @@
-package com.supplychain.contracts;
+package net.corda.samples.supplychain.contracts;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
@@ -9,7 +9,7 @@
// ************
public class CargoStateContract implements Contract {
// This is used to identify our contract when building a transaction.
- public static final String ID = "com.supplychain.contracts.CargoStateContract";
+ public static final String ID = "net.corda.samples.supplychain.contracts.CargoStateContract";
// A transaction is valid if the verify() function of the contract of all the transaction's input and output states
// does not throw an exception.
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InternalMessageStateContract.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InternalMessageStateContract.java
similarity index 81%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InternalMessageStateContract.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InternalMessageStateContract.java
index 6550d8a6..bc99bb7b 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/InternalMessageStateContract.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InternalMessageStateContract.java
@@ -1,4 +1,4 @@
-package com.supplychain.contracts;
+package net.corda.samples.supplychain.contracts;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
@@ -9,7 +9,7 @@
// ************
public class InternalMessageStateContract implements Contract {
// This is used to identify our contract when building a transaction.
- public static final String ID = "com.supplychain.contracts.InternalMessageStateContract";
+ public static final String ID = "net.corda.samples.supplychain.contracts.InternalMessageStateContract";
// A transaction is valid if the verify() function of the contract of all the transaction's input and output states
// does not throw an exception.
diff --git a/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InvoiceStateContract.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InvoiceStateContract.java
new file mode 100644
index 00000000..4336423f
--- /dev/null
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/InvoiceStateContract.java
@@ -0,0 +1,56 @@
+package net.corda.samples.supplychain.contracts;
+
+import net.corda.core.contracts.CommandData;
+import net.corda.core.contracts.CommandWithParties;
+import net.corda.core.contracts.Contract;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.transactions.LedgerTransaction;
+import net.corda.samples.supplychain.states.InvoiceState;
+
+import java.util.List;
+
+import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
+import static net.corda.core.contracts.ContractsDSL.requireThat;
+
+// ************
+// * Contract *
+// ************
+public class InvoiceStateContract implements Contract {
+ // This is used to identify our contract when building a transaction.
+ public static final String ID = "net.corda.samples.supplychain.contracts.InvoiceStateContract";
+
+ // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
+ // does not throw an exception.
+ @Override
+ public void verify(LedgerTransaction tx) throws IllegalArgumentException {
+ /*
+ * We can use the requireSingleCommand function to extract command data from transaction.
+ * However, it is possible to have multiple commands in a signle transaction.
+ */
+ final CommandWithParties command = requireSingleCommand(tx.getCommands(), InvoiceStateContract.Commands.class);
+
+ List inputs = tx.getInputStates();
+ List outputs = tx.getOutputStates();
+
+ if (command.getValue() instanceof InvoiceStateContract.Commands.Create) {
+
+ // Using Corda DSL function requireThat to replicate conditions-checks
+ requireThat(require -> {
+ require.using("No inputs should be consumed when creating a new Invoice State.", inputs.isEmpty());
+ require.using("Transaction must have exactly one output.", outputs.size() == 1);
+ InvoiceState output = (InvoiceState) outputs.get(0);
+ require.using("Invoice amount must be a valid number (Greater than zero)", output.getAmount() > 0);
+ return null;
+ });
+
+ } else {
+ throw new IllegalArgumentException("Command not found!");
+ }
+
+ }
+
+ // Used to indicate the transaction's intent.
+ public interface Commands extends CommandData {
+ class Create implements Commands {}
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/PaymentStateContract.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/PaymentStateContract.java
similarity index 82%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/PaymentStateContract.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/PaymentStateContract.java
index acbe7986..81a7b16d 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/PaymentStateContract.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/PaymentStateContract.java
@@ -1,4 +1,4 @@
-package com.supplychain.contracts;
+package net.corda.samples.supplychain.contracts;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
@@ -9,7 +9,7 @@
// ************
public class PaymentStateContract implements Contract {
// This is used to identify our contract when building a transaction.
- public static final String ID = "com.supplychain.contracts.PaymentStateContract";
+ public static final String ID = "net.corda.samples.supplychain.contracts.PaymentStateContract";
// A transaction is valid if the verify() function of the contract of all the transaction's input and output states
// does not throw an exception.
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/ShippingRequestStateContract.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/ShippingRequestStateContract.java
similarity index 81%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/ShippingRequestStateContract.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/ShippingRequestStateContract.java
index e9dcb906..ab0c0cfa 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/contracts/ShippingRequestStateContract.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/contracts/ShippingRequestStateContract.java
@@ -1,4 +1,4 @@
-package com.supplychain.contracts;
+package net.corda.samples.supplychain.contracts;
import net.corda.core.contracts.CommandData;
import net.corda.core.contracts.Contract;
@@ -9,7 +9,7 @@
// ************
public class ShippingRequestStateContract implements Contract {
// This is used to identify our contract when building a transaction.
- public static final String ID = "com.supplychain.contracts.ShippingRequestStateContract";
+ public static final String ID = "net.corda.samples.supplychain.contracts.ShippingRequestStateContract";
// A transaction is valid if the verify() function of the contract of all the transaction's input and output states
// does not throw an exception.
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/CargoState.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/CargoState.java
similarity index 93%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/states/CargoState.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/CargoState.java
index 13e71b3f..38ac721a 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/CargoState.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/CargoState.java
@@ -1,6 +1,6 @@
-package com.supplychain.states;
+package net.corda.samples.supplychain.states;
-import com.supplychain.contracts.CargoStateContract;
+import net.corda.samples.supplychain.contracts.CargoStateContract;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InternalMessageState.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InternalMessageState.java
similarity index 91%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InternalMessageState.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InternalMessageState.java
index 29c5713e..5d7a34a3 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/InternalMessageState.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InternalMessageState.java
@@ -1,6 +1,6 @@
-package com.supplychain.states;
+package net.corda.samples.supplychain.states;
-import com.supplychain.contracts.InternalMessageStateContract;
+import net.corda.samples.supplychain.contracts.InternalMessageStateContract;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
diff --git a/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InvoiceState.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InvoiceState.java
new file mode 100644
index 00000000..699cc532
--- /dev/null
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/InvoiceState.java
@@ -0,0 +1,71 @@
+package net.corda.samples.supplychain.states;
+
+import net.corda.samples.supplychain.contracts.InvoiceStateContract;
+import net.corda.core.contracts.BelongsToContract;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.identity.AbstractParty;
+import net.corda.core.identity.AnonymousParty;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+// *********
+// * State *
+// *********
+@BelongsToContract(InvoiceStateContract.class)
+public class InvoiceState implements ContractState {
+
+ private int amount;
+ private AnonymousParty sender;
+ private AnonymousParty recipient;
+ private UUID invoiceID;
+ private List participants;
+
+ public InvoiceState(int amount, AnonymousParty sender, AnonymousParty recipient, UUID invoiceID) {
+ this.amount = amount;
+ this.sender = sender;
+ this.recipient = recipient;
+ this.invoiceID = invoiceID;
+ this.participants = new ArrayList();
+ participants.add(recipient);
+ participants.add(sender);
+ }
+
+ public int getAmount() {
+ return amount;
+ }
+
+ public void setAmount(int amount) {
+ this.amount = amount;
+ }
+
+ public AnonymousParty getSender() {
+ return sender;
+ }
+
+ public void setSender(AnonymousParty sender) {
+ this.sender = sender;
+ }
+
+ public AnonymousParty getRecipient() {
+ return recipient;
+ }
+
+ public void setRecipient(AnonymousParty recipient) {
+ this.recipient = recipient;
+ }
+
+ public UUID getInvoiceID() {
+ return invoiceID;
+ }
+
+ public void setInvoiceID(UUID invoiceID) {
+ this.invoiceID = invoiceID;
+ }
+
+ @Override
+ public List getParticipants() {
+ return this.participants;
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/PaymentState.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/PaymentState.java
similarity index 92%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/states/PaymentState.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/PaymentState.java
index 9e75a41b..00d3531e 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/PaymentState.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/PaymentState.java
@@ -1,6 +1,6 @@
-package com.supplychain.states;
+package net.corda.samples.supplychain.states;
-import com.supplychain.contracts.PaymentStateContract;
+import net.corda.samples.supplychain.contracts.PaymentStateContract;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
diff --git a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/ShippingRequestState.java b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/ShippingRequestState.java
similarity index 93%
rename from Accounts/supplychain/contracts/src/main/java/com/supplychain/states/ShippingRequestState.java
rename to Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/ShippingRequestState.java
index 3ff5ee22..ebfd2cf1 100644
--- a/Accounts/supplychain/contracts/src/main/java/com/supplychain/states/ShippingRequestState.java
+++ b/Accounts/supplychain/contracts/src/main/java/net/corda/samples/supplychain/states/ShippingRequestState.java
@@ -1,6 +1,6 @@
-package com.supplychain.states;
+package net.corda.samples.supplychain.states;
-import com.supplychain.contracts.ShippingRequestStateContract;
+import net.corda.samples.supplychain.contracts.ShippingRequestStateContract;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.ContractState;
import net.corda.core.identity.AbstractParty;
diff --git a/Accounts/supplychain/contracts/src/test/java/com/supplychain/contracts/ContractTests.java b/Accounts/supplychain/contracts/src/test/java/com/supplychain/contracts/ContractTests.java
deleted file mode 100644
index 63beb3ba..00000000
--- a/Accounts/supplychain/contracts/src/test/java/com/supplychain/contracts/ContractTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.supplychain.contracts;
-
-import net.corda.testing.node.MockServices;
-import org.junit.Test;
-
-public class ContractTests {
- private final MockServices ledgerServices = new MockServices();
-
- @Test
- public void dummyTest() {
-
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/ContractTests.java b/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/ContractTests.java
new file mode 100644
index 00000000..f40dd8f7
--- /dev/null
+++ b/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/ContractTests.java
@@ -0,0 +1,38 @@
+package net.corda.samples.supplychain.contracts;
+
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.states.InvoiceState;
+import net.corda.testing.core.TestIdentity;
+import net.corda.testing.node.MockServices;
+import org.junit.Test;
+
+import java.util.UUID;
+
+import static net.corda.testing.node.NodeTestUtils.ledger;
+
+public class ContractTests {
+ private final MockServices ledgerServices = new MockServices();
+ TestIdentity Operator = new TestIdentity(new CordaX500Name("Alice", "TestLand", "US"));
+ TestIdentity Operator2 = new TestIdentity(new CordaX500Name("Bob", "TestLand", "US"));
+
+ @Test
+ public void InvoiceAmountMustBeGreaterThanZero() {
+ InvoiceState tokenPass = new InvoiceState(10, new AnonymousParty(Operator.getPublicKey()),new AnonymousParty(Operator2.getPublicKey()),new UniqueIdentifier().getId());
+ InvoiceState tokenfail = new InvoiceState(-1, new AnonymousParty(Operator.getPublicKey()),new AnonymousParty(Operator2.getPublicKey()),new UniqueIdentifier().getId());
+ ledger(ledgerServices, l -> {
+ l.transaction(tx -> {
+ tx.output(InvoiceStateContract.ID, tokenfail);
+ tx.command(Operator.getPublicKey(), new InvoiceStateContract.Commands.Create()); // Wrong type.
+ return tx.fails();
+ });
+ l.transaction(tx -> {
+ tx.output(InvoiceStateContract.ID, tokenPass);
+ tx.command(Operator.getPublicKey(), new InvoiceStateContract.Commands.Create()); // Wrong type.
+ return tx.verifies();
+ });
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/StateTests.java b/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/StateTests.java
new file mode 100644
index 00000000..5031f6be
--- /dev/null
+++ b/Accounts/supplychain/contracts/src/test/java/net/corda/samples/supplychain/contracts/StateTests.java
@@ -0,0 +1,17 @@
+package net.corda.samples.supplychain.contracts;
+
+import net.corda.samples.supplychain.states.InvoiceState;
+import net.corda.testing.node.MockServices;
+import org.junit.Test;
+
+public class StateTests {
+ private final MockServices ledgerServices = new MockServices();
+
+ @Test
+ public void hasAmountFieldOfCorrectType() throws NoSuchFieldException {
+ // Does the message field exist?
+ InvoiceState.class.getDeclaredField("amount");
+ // Is the message field of the correct type?
+ assert(InvoiceState.class.getDeclaredField("amount").getType().equals(int.class));
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/gradle.properties b/Accounts/supplychain/gradle.properties
index 834d4552..6b3850f8 100644
--- a/Accounts/supplychain/gradle.properties
+++ b/Accounts/supplychain/gradle.properties
@@ -1,3 +1,3 @@
-name=Test
+name=Supplychain Cordapp
group=com.supplychain
-version=0.1
\ No newline at end of file
+version=1.0
\ No newline at end of file
diff --git a/Accounts/supplychain/gradle/wrapper/gradle-wrapper.properties b/Accounts/supplychain/gradle/wrapper/gradle-wrapper.properties
index 2a2a3a8e..ae01072d 100644
--- a/Accounts/supplychain/gradle/wrapper/gradle-wrapper.properties
+++ b/Accounts/supplychain/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/Accounts/supplychain/repositories.gradle b/Accounts/supplychain/repositories.gradle
index 2874c2ab..9797c0ea 100644
--- a/Accounts/supplychain/repositories.gradle
+++ b/Accounts/supplychain/repositories.gradle
@@ -1,8 +1,7 @@
repositories {
mavenLocal()
mavenCentral()
- jcenter()
maven { url 'https://jitpack.io' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
diff --git a/Accounts/supplychain/workflows/src/integrationTest/java/com/supplychain/DriverBasedTest.java b/Accounts/supplychain/workflows/src/integrationTest/java/com/supplychain/DriverBasedTest.java
deleted file mode 100644
index a6bc2380..00000000
--- a/Accounts/supplychain/workflows/src/integrationTest/java/com/supplychain/DriverBasedTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.supplychain;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.core.concurrent.CordaFuture;
-import net.corda.core.identity.CordaX500Name;
-import net.corda.testing.core.TestIdentity;
-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.List;
-
-import static net.corda.testing.driver.Driver.driver;
-import static org.junit.Assert.assertEquals;
-
-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(new DriverParameters().withIsDebug(true).withStartNodesInProcess(true), dsl -> {
- // Start a pair of nodes and wait for them both to be ready.
- List> handleFutures = ImmutableList.of(
- dsl.startNode(new NodeParameters().withProvidedName(bankA.getName())),
- dsl.startNode(new NodeParameters().withProvidedName(bankB.getName()))
- );
-
- try {
- NodeHandle partyAHandle = handleFutures.get(0).get();
- NodeHandle partyBHandle = handleFutures.get(1).get();
-
- // 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.
- assertEquals(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName()).getName(), bankB.getName());
- assertEquals(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName()).getName(), bankA.getName());
- } catch (Exception e) {
- throw new RuntimeException("Caught exception during test: ", e);
- }
-
- return null;
- });
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/integrationTest/java/net/corda/samples/supplychain/DriverBasedTest.java b/Accounts/supplychain/workflows/src/integrationTest/java/net/corda/samples/supplychain/DriverBasedTest.java
new file mode 100644
index 00000000..0a6262ef
--- /dev/null
+++ b/Accounts/supplychain/workflows/src/integrationTest/java/net/corda/samples/supplychain/DriverBasedTest.java
@@ -0,0 +1,48 @@
+package net.corda.samples.supplychain;
+
+import com.google.common.collect.ImmutableList;
+import net.corda.core.concurrent.CordaFuture;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.testing.core.TestIdentity;
+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.List;
+
+import static net.corda.testing.driver.Driver.driver;
+import static org.junit.Assert.assertEquals;
+
+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(new DriverParameters().withIsDebug(true).withStartNodesInProcess(true), dsl -> {
+ // Start a pair of nodes and wait for them both to be ready.
+ List> handleFutures = ImmutableList.of(
+ dsl.startNode(new NodeParameters().withProvidedName(bankA.getName())),
+ dsl.startNode(new NodeParameters().withProvidedName(bankB.getName()))
+ );
+
+ try {
+ NodeHandle partyAHandle = handleFutures.get(0).get();
+ NodeHandle partyBHandle = handleFutures.get(1).get();
+
+ // 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.
+ assertEquals(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName()).getName(), bankB.getName());
+ assertEquals(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName()).getName(), bankA.getName());
+ } catch (Exception e) {
+ throw new RuntimeException("Caught exception during test: ", e);
+ }
+
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/CreateNewAccount.java b/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/CreateNewAccount.java
deleted file mode 100644
index eb3d275c..00000000
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/CreateNewAccount.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.supplychain.accountUtilities;
-
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.*;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.flows.*;
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.workflows.services.AccountService;
-import net.corda.core.flows.FlowLogic;;
-import net.corda.core.flows.StartableByRPC;
-
-import java.util.UUID;
-
-@StartableByRPC
-@StartableByService
-@InitiatingFlow
-public class CreateNewAccount extends FlowLogic{
-
- private String acctName;
-
- public CreateNewAccount(String acctName) {
- this.acctName = acctName;
- }
-
-
- @Override
- public String call() throws FlowException {
- StateAndRef newAccount = null;
- try {
- newAccount = getServiceHub().cordaService(KeyManagementBackedAccountService.class).createAccount(acctName).get();
- } catch (Exception e) {
- e.printStackTrace();
- }
- AccountInfo acct = newAccount.getState().getData();
- return "" + acct.getName() + " team's account was created. UUID is : " + acct.getIdentifier();
- }
-}
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/NewKeyForAccount.java b/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/NewKeyForAccount.java
deleted file mode 100644
index 83e2c5e6..00000000
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/NewKeyForAccount.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.supplychain.accountUtilities;
-
-import co.paralleluniverse.fibers.Suspendable;
-import net.corda.core.flows.FlowException;
-import net.corda.core.flows.FlowLogic;
-import net.corda.core.flows.StartableByRPC;
-import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.PartyAndCertificate;
-import java.util.*;
-
-@StartableByRPC
-@StartableByService
-public class NewKeyForAccount extends FlowLogic{
-
- private final UUID accountID;
-
- public NewKeyForAccount(UUID accountID) {
- this.accountID = accountID;
- }
-
- @Override
- @Suspendable
- public PartyAndCertificate call() throws FlowException {
- return getServiceHub().getKeyManagementService().freshKeyAndCert(getOurIdentityAndCert(), false, accountID);
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ShareAccountTo.java b/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ShareAccountTo.java
deleted file mode 100644
index c828a0c9..00000000
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ShareAccountTo.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.supplychain.accountUtilities;
-
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.flows.FlowException;
-import net.corda.core.flows.FlowLogic;
-import net.corda.core.flows.StartableByRPC;
-import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.Party;
-import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
-import java.util.*;
-
-@StartableByRPC
-@StartableByService
-public class ShareAccountTo extends FlowLogic{
-
- private final Party shareTo;
- private final String acctNameShared;
-
- public ShareAccountTo(String acctNameShared, Party shareTo) {
- this.acctNameShared = acctNameShared;
- this.shareTo = shareTo;
- }
-
- @Override
- @Suspendable
- public String call() throws FlowException {
- List> allmyAccounts = getServiceHub().cordaService(KeyManagementBackedAccountService.class).ourAccounts();
- StateAndRef SharedAccount = allmyAccounts.stream()
- .filter(it -> it.getState().getData().getName().equals(acctNameShared))
- .findAny().get();
-
- subFlow(new ShareAccountInfo(SharedAccount, Arrays.asList(shareTo)));
- return "Shared " + acctNameShared + " with " + shareTo.getName().getOrganisation();
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/CreateNewAccount.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/CreateNewAccount.java
new file mode 100644
index 00000000..1e79bf3f
--- /dev/null
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/CreateNewAccount.java
@@ -0,0 +1,38 @@
+package net.corda.samples.supplychain.accountUtilities;
+
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.*;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.flows.*;
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.accounts.workflows.services.AccountService;
+import net.corda.core.flows.FlowLogic;;
+import net.corda.core.flows.StartableByRPC;
+
+import java.util.UUID;
+
+@StartableByRPC
+@StartableByService
+@InitiatingFlow
+public class CreateNewAccount extends FlowLogic{
+
+ private String acctName;
+
+ public CreateNewAccount(String acctName) {
+ this.acctName = acctName;
+ }
+
+
+ @Override
+ public String call() throws FlowException {
+ StateAndRef newAccount = null;
+ try {
+ newAccount = getServiceHub().cordaService(KeyManagementBackedAccountService.class).createAccount(acctName).get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ AccountInfo acct = newAccount.getState().getData();
+ return "" + acct.getName() + " team's account was created. UUID is : " + acct.getIdentifier();
+ }
+}
diff --git a/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/NewKeyForAccount.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/NewKeyForAccount.java
new file mode 100644
index 00000000..1d057192
--- /dev/null
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/NewKeyForAccount.java
@@ -0,0 +1,26 @@
+package net.corda.samples.supplychain.accountUtilities;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.flows.StartableByService;
+import net.corda.core.identity.PartyAndCertificate;
+import java.util.*;
+
+@StartableByRPC
+@StartableByService
+public class NewKeyForAccount extends FlowLogic{
+
+ private final UUID accountID;
+
+ public NewKeyForAccount(UUID accountID) {
+ this.accountID = accountID;
+ }
+
+ @Override
+ @Suspendable
+ public PartyAndCertificate call() throws FlowException {
+ return getServiceHub().getKeyManagementService().freshKeyAndCert(getOurIdentityAndCert(), false, accountID);
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ShareAccountTo.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ShareAccountTo.java
new file mode 100644
index 00000000..415dbcf5
--- /dev/null
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ShareAccountTo.java
@@ -0,0 +1,39 @@
+package net.corda.samples.supplychain.accountUtilities;
+
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.flows.StartableByService;
+import net.corda.core.identity.Party;
+import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
+import java.util.*;
+
+@StartableByRPC
+@StartableByService
+public class ShareAccountTo extends FlowLogic{
+
+ private final Party shareTo;
+ private final String acctNameShared;
+
+ public ShareAccountTo(String acctNameShared, Party shareTo) {
+ this.acctNameShared = acctNameShared;
+ this.shareTo = shareTo;
+ }
+
+ @Override
+ @Suspendable
+ public String call() throws FlowException {
+ List> allmyAccounts = getServiceHub().cordaService(KeyManagementBackedAccountService.class).ourAccounts();
+ StateAndRef SharedAccount = allmyAccounts.stream()
+ .filter(it -> it.getState().getData().getName().equals(acctNameShared))
+ .findAny().get();
+
+ subFlow(new ShareAccountInfo(SharedAccount, Arrays.asList(shareTo)));
+ return "Shared " + acctNameShared + " with " + shareTo.getName().getOrganisation();
+ }
+}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ViewInboxByAccount.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ViewInboxByAccount.java
similarity index 88%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ViewInboxByAccount.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ViewInboxByAccount.java
index d293539d..b97062bb 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/accountUtilities/ViewInboxByAccount.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/accountUtilities/ViewInboxByAccount.java
@@ -1,19 +1,14 @@
-package com.supplychain.accountUtilities;
+package net.corda.samples.supplychain.accountUtilities;
-import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
import com.r3.corda.lib.accounts.workflows.services.AccountService;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import com.supplychain.states.*;
-import net.corda.core.contracts.StateAndRef;
import net.corda.core.flows.FlowException;
import net.corda.core.flows.FlowLogic;
import net.corda.core.flows.StartableByRPC;
import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.Party;
-import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.samples.supplychain.states.*;
import java.util.*;
import java.util.stream.Collectors;
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/InternalMessage.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/InternalMessage.java
similarity index 87%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/InternalMessage.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/InternalMessage.java
index c7118533..eadf9f59 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/InternalMessage.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/InternalMessage.java
@@ -1,4 +1,4 @@
-package com.supplychain.flows;
+package net.corda.samples.supplychain.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,11 +6,10 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.supplychain.accountUtilities.NewKeyForAccount;
-import com.supplychain.contracts.InternalMessageStateContract;
-import com.supplychain.contracts.InvoiceStateContract;
-import com.supplychain.states.InternalMessageState;
-import com.supplychain.states.InvoiceState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.accountUtilities.NewKeyForAccount;
+import net.corda.samples.supplychain.contracts.InternalMessageStateContract;
+import net.corda.samples.supplychain.states.InternalMessageState;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
@@ -22,8 +21,6 @@
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
// ******************
@@ -84,7 +81,11 @@ public String call() throws FlowException {
//generating State for transfer
InternalMessageState output = new InternalMessageState(message,new AnonymousParty(myKey),targetAcctAnonymousParty);
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addOutputState(output)
.addCommand(new InternalMessageStateContract.Commands.Create(),Arrays.asList(targetAcctAnonymousParty.getOwningKey(),myKey));
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendCargo.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendCargo.java
similarity index 85%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendCargo.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendCargo.java
index cd2e3ce6..d51f2527 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendCargo.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendCargo.java
@@ -1,4 +1,4 @@
-package com.supplychain.flows;
+package net.corda.samples.supplychain.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,15 +6,17 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.supplychain.accountUtilities.NewKeyForAccount;
-import com.supplychain.contracts.CargoStateContract;
-import com.supplychain.states.CargoState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.accountUtilities.NewKeyForAccount;
+import net.corda.samples.supplychain.contracts.CargoStateContract;
+import net.corda.samples.supplychain.states.CargoState;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
+
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
@@ -55,7 +57,12 @@ public String call() throws FlowException {
//generating State for transfer
CargoState output = new CargoState(new AnonymousParty(myKey),targetAcctAnonymousParty,cargo,getOurIdentity());
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addOutputState(output)
.addCommand(new CargoStateContract.Commands.Create(), Arrays.asList(targetAcctAnonymousParty.getOwningKey(),getOurIdentity().getOwningKey()));
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendInvoice.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendInvoice.java
similarity index 85%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendInvoice.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendInvoice.java
index 4c3b3eb8..5d17627c 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendInvoice.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendInvoice.java
@@ -1,4 +1,4 @@
-package com.supplychain.flows;
+package net.corda.samples.supplychain.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,15 +6,17 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.supplychain.accountUtilities.NewKeyForAccount;
-import com.supplychain.contracts.InvoiceStateContract;
-import com.supplychain.states.InvoiceState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.accountUtilities.NewKeyForAccount;
+import net.corda.samples.supplychain.contracts.InvoiceStateContract;
+import net.corda.samples.supplychain.states.InvoiceState;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
+
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
@@ -55,7 +57,12 @@ public String call() throws FlowException {
//generating State for transfer
InvoiceState output = new InvoiceState(amount,new AnonymousParty(myKey),targetAcctAnonymousParty, UUID.randomUUID());
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addOutputState(output)
.addCommand(new InvoiceStateContract.Commands.Create(), Arrays.asList(targetAcctAnonymousParty.getOwningKey(),myKey));
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendPayment.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendPayment.java
similarity index 84%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendPayment.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendPayment.java
index e5309882..9a65d6df 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendPayment.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendPayment.java
@@ -1,4 +1,4 @@
-package com.supplychain.flows;
+package net.corda.samples.supplychain.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,18 +6,20 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.supplychain.accountUtilities.NewKeyForAccount;
-import com.supplychain.contracts.PaymentStateContract;
-import com.supplychain.states.PaymentState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.accountUtilities.NewKeyForAccount;
+import net.corda.samples.supplychain.contracts.PaymentStateContract;
+import net.corda.samples.supplychain.states.PaymentState;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
+
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
-import java.util.UUID;
import java.util.stream.Collectors;
@@ -54,7 +56,12 @@ public String call() throws FlowException {
//generating State for transfer
PaymentState output = new PaymentState(amount,new AnonymousParty(myKey),targetAcctAnonymousParty);
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addOutputState(output)
.addCommand(new PaymentStateContract.Commands.Create(), Arrays.asList(targetAcctAnonymousParty.getOwningKey(),myKey));
diff --git a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendShippingRequest.java b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendShippingRequest.java
similarity index 88%
rename from Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendShippingRequest.java
rename to Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendShippingRequest.java
index 56ddb99d..962770ee 100644
--- a/Accounts/supplychain/workflows/src/main/java/com/supplychain/flows/SendShippingRequest.java
+++ b/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendShippingRequest.java
@@ -1,17 +1,14 @@
-package com.supplychain.flows;
+package net.corda.samples.supplychain.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
import com.r3.corda.lib.accounts.workflows.services.AccountService;
-import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.supplychain.accountUtilities.NewKeyForAccount;
-import com.supplychain.contracts.InvoiceStateContract;
-import com.supplychain.contracts.ShippingRequestStateContract;
-import com.supplychain.states.InvoiceState;
-import com.supplychain.states.PaymentState;
-import com.supplychain.states.ShippingRequestState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.supplychain.accountUtilities.NewKeyForAccount;
+import net.corda.samples.supplychain.contracts.ShippingRequestStateContract;
+import net.corda.samples.supplychain.states.ShippingRequestState;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
@@ -23,7 +20,6 @@
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
-import java.util.UUID;
import java.util.stream.Collectors;
@@ -87,7 +83,12 @@ public String call() throws FlowException {
//generating State for transfer
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
ShippingRequestState output = new ShippingRequestState(new AnonymousParty(myKey),whereTo,shipper,cargo);
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addOutputState(output)
.addCommand(new ShippingRequestStateContract.Commands.Create(), Arrays.asList(shipper.getOwningKey(),myKey));
diff --git a/Accounts/supplychain/workflows/src/test/java/com/supplychain/ContractTests.java b/Accounts/supplychain/workflows/src/test/java/com/supplychain/ContractTests.java
deleted file mode 100644
index e0a55a0d..00000000
--- a/Accounts/supplychain/workflows/src/test/java/com/supplychain/ContractTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.supplychain;
-
-import net.corda.testing.node.MockServices;
-import org.junit.Test;
-
-public class ContractTests {
- private final MockServices ledgerServices = new MockServices();
-
- @Test
- public void dummyTest() {
-
- }
-}
\ No newline at end of file
diff --git a/Accounts/supplychain/workflows/src/test/java/com/supplychain/FlowTests.java b/Accounts/supplychain/workflows/src/test/java/com/supplychain/FlowTests.java
deleted file mode 100644
index ea71fc74..00000000
--- a/Accounts/supplychain/workflows/src/test/java/com/supplychain/FlowTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.supplychain;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.testing.node.MockNetwork;
-import net.corda.testing.node.MockNetworkParameters;
-import net.corda.testing.node.StartedMockNode;
-import net.corda.testing.node.TestCordapp;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlowTests {
- private final MockNetwork network = new MockNetwork(new MockNetworkParameters(ImmutableList.of(
- TestCordapp.findCordapp("com.supplychain.contracts"),
- TestCordapp.findCordapp("com.supplychain.flows")
- )));
- private final StartedMockNode a = network.createNode();
- private final StartedMockNode b = network.createNode();
-
- public FlowTests() {
- }
-
- @Before
- public void setup() {
- network.runNetwork();
- }
-
- @After
- public void tearDown() {
- network.stopNodes();
- }
-
- @Test
- public void dummyTest() {
-
- }
-}
diff --git a/Accounts/supplychain/workflows/src/test/java/com/supplychain/NodeDriver.java b/Accounts/supplychain/workflows/src/test/java/com/supplychain/NodeDriver.java
deleted file mode 100644
index ef32c93e..00000000
--- a/Accounts/supplychain/workflows/src/test/java/com/supplychain/NodeDriver.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.supplychain;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.core.identity.CordaX500Name;
-import net.corda.testing.driver.DriverParameters;
-import net.corda.testing.driver.NodeParameters;
-import net.corda.testing.node.User;
-import com.google.common.collect.ImmutableSet;
-
-import java.util.List;
-import static net.corda.testing.driver.Driver.driver;
-
-/**
- * Allows you to run your nodes through an IDE (as opposed to using deployNodes). Do not use in a production
- * environment.
- */
-public class NodeDriver {
- public static void main(String[] args) {
- final List rpcUsers =
- ImmutableList.of(new User("user1", "test", ImmutableSet.of("ALL")));
-
- driver(new DriverParameters().withStartNodesInProcess(true).withWaitForAllNodesToFinish(true), dsl -> {
- try {
- dsl.startNode(new NodeParameters()
- .withProvidedName(new CordaX500Name("PartyA", "London", "GB"))
- .withRpcUsers(rpcUsers)).get();
- dsl.startNode(new NodeParameters()
- .withProvidedName(new CordaX500Name("PartyB", "New York", "US"))
- .withRpcUsers(rpcUsers)).get();
- } catch (Throwable e) {
- System.err.println("Encountered exception in node startup: " + e.getMessage());
- e.printStackTrace();
- }
-
- return null;
- }
- );
- }
-}
diff --git a/Accounts/supplychain/workflows/src/test/java/net/corda/samples/supplychain/FlowTests.java b/Accounts/supplychain/workflows/src/test/java/net/corda/samples/supplychain/FlowTests.java
new file mode 100644
index 00000000..5332c1fb
--- /dev/null
+++ b/Accounts/supplychain/workflows/src/test/java/net/corda/samples/supplychain/FlowTests.java
@@ -0,0 +1,99 @@
+package net.corda.samples.supplychain;
+
+import com.google.common.collect.ImmutableList;
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.services.AccountService;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.node.NetworkParameters;
+import net.corda.core.node.services.Vault;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.samples.supplychain.accountUtilities.CreateNewAccount;
+import net.corda.samples.supplychain.accountUtilities.ShareAccountTo;
+import net.corda.samples.supplychain.flows.SendInvoice;
+import net.corda.samples.supplychain.states.InvoiceState;
+import net.corda.testing.node.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.time.Instant;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
+public class FlowTests {
+ private MockNetwork network;
+ private StartedMockNode a;
+ private StartedMockNode b;
+
+
+ private NetworkParameters testNetworkParameters =
+ new NetworkParameters(4, Arrays.asList(), 10485760, (10485760 * 5), Instant.now(),1, new LinkedHashMap<>());
+
+ @Before
+ public void setup() {
+
+ network = new MockNetwork(new MockNetworkParameters().withCordappsForAllNodes(ImmutableList.of(
+ TestCordapp.findCordapp("net.corda.samples.supplychain.contracts"),
+ TestCordapp.findCordapp("net.corda.samples.supplychain.flows"),
+ TestCordapp.findCordapp("com.r3.corda.lib.accounts.contracts"),
+ TestCordapp.findCordapp("com.r3.corda.lib.accounts.workflows"))).withNetworkParameters(testNetworkParameters)
+ .withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))))
+ );
+ a = network.createPartyNode(null);
+ b = network.createPartyNode(null);
+ network.runNetwork();
+ }
+
+ @After
+ public void tearDown() {
+ network.stopNodes();
+ }
+
+ @Test
+ public void AccountCreation() throws ExecutionException, InterruptedException {
+ CreateNewAccount createAcct = new CreateNewAccount("TestAccountA");
+ Future future = a.startFlow(createAcct);
+ network.runNetwork();
+ AccountService accountService = a.getServices().cordaService(KeyManagementBackedAccountService.class);
+ List> myAccount = accountService.accountInfo("TestAccountA");
+ assert (myAccount.size() != 0);
+ }
+
+ @Test
+ public void InvoiceFlowTest() throws ExecutionException, InterruptedException {
+ CreateNewAccount createAcct = new CreateNewAccount("TestAccountA");
+ Future future = a.startFlow(createAcct);
+ network.runNetwork();
+ ShareAccountTo shareAToB = new ShareAccountTo("TestAccountA",b.getInfo().getLegalIdentities().get(0));
+ Future future2 = a.startFlow(shareAToB);
+ network.runNetwork();
+
+ CreateNewAccount createAcct2 = new CreateNewAccount("TestAccountB");
+ Future future3 = b.startFlow(createAcct2);
+ network.runNetwork();
+
+ ShareAccountTo shareBToA = new ShareAccountTo("TestAccountB",a.getInfo().getLegalIdentities().get(0));
+ Future future4 = b.startFlow(shareBToA);
+ network.runNetwork();
+
+ SendInvoice invoiceflow = new SendInvoice("TestAccountA","TestAccountB",20);
+ Future future5 = a.startFlow(invoiceflow);
+ network.runNetwork();
+
+ //retrieve
+ AccountService accountService = b.getServices().cordaService(KeyManagementBackedAccountService.class);
+ AccountInfo myAccount = accountService.accountInfo("TestAccountB").get(0).getState().getData();
+ QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria()
+ .withExternalIds(Arrays.asList(myAccount.getIdentifier().getId()));
+ InvoiceState storedState = b.getServices().getVaultService().queryBy(InvoiceState.class,criteria).getStates()
+ .get(0).getState().getData();
+ assert (storedState.getAmount() == 20);
+ }
+
+
+}
diff --git a/Accounts/tictacthor/README.md b/Accounts/tictacthor/README.md
index df523102..5c388345 100644
--- a/Accounts/tictacthor/README.md
+++ b/Accounts/tictacthor/README.md
@@ -1,39 +1,45 @@
-# Tic Tac Thor
-This CorDapp recreates the game of Tic Tac Toe via Corda. It primarilly demonstrates how you can have linear state transactions between cross-node accounts.
+# Tic Tac Thor
+This CorDapp recreates the game of Tic Tac Toe via Corda. It primarily demonstrates how you can have [LinearState](https://docs.corda.net/docs/corda-os/api-states.html#linearstate) transactions between cross-node accounts.
+
+
+## Pre-Requisites
+
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.9/community/getting-set-up.html).
+
## Running the sample
Deploy and run the nodes by:
```
-./gradlew deployNodes
+./gradlew clean build deployNodes
./build/nodes/runnodes
```
-Then you will need to also start the spring server for the Cordapp by running the following commands seperately:
+Then you will need to also start the spring server for the CorDapp by running the following commands separately:
`./gradlew bootRunDevRel`will have the DevRel server running on 8080 port
, and `./gradlew bootRunSOE`will start the Solution Engineering server on 8090 port
-## Operating the Cordapp
-Now go to postman and excute the following in order: (All of the API are POST request!)
+## Operating the CorDapp
+Now go to postman and execute the following in order: (All the APIs are POST requests!)
1. Create an account on DevRel node: `http://localhost:8080/createAccount/PeterLi`
2. Create an account on SoE node: `http://localhost:8090/createAccount/DavidWinner`
3. Peter now requests game with David: `http://localhost:8080/requestGameWith/PeterLi/SolutionEng/DavidWinner`
-4. David has to accept the challenege: `http://localhost:8090/acceptGameInvite/DavidWinner/DevRel/PeterLi`
+4. David has to accept the challenge: `http://localhost:8090/acceptGameInvite/DavidWinner/DevRel/PeterLi`
5. Game Starts, and Peter makes the first move: `http://localhost:8080/startGameAndFirstMove/PeterLi/DavidWinner/0`
6. David's turn: `http://localhost:8090/submitMove/DavidWinner/PeterLi/4`
API Syntax: `http://localhost:8080/submitMove/WHO-AM-I/MY-COUNTERPART/POSITION`
-From here, you can start play the game by changing the very last number from the `submitMove`API call. The game board is representated by an 1-D array: What we just ran can transfer into a tic-tac-toe game board like the one we see on the right.
+From here, you can start play the game by changing the very last number from the `submitMove`API call. The game board is represented by an 1-D array: What we just ran can transfer into a tic-tac-toe game board like the one we see on the right.
```
│0│1│2│ │O│ │ │
│3│4│5│ -> │ │X│ │
│6│7│8│ │ │ │ │
```
-The Game will automatically end when one player win the game.
+The Game will automatically end when one player wins the game.
You can also run `run vaultQuery contractStateType: net.corda.samples.tictacthor.states.BoardState` at any given time to see the board games stored in vault.
-now if you want to fast fard the game, Play the following moves in order:
+now if you want to fast-forward the game, Play the following moves in order:
According to syntax: we should have `http://localhost:8080/submitMove/PeterLi/DavidWinner/3` for the first move below.
```
* Peter: 3 │O│ │ │
@@ -48,7 +54,7 @@ We can play a bit more about the accounts. Now let's create two accounts, a new
* Create an account on SoE node: `http://localhost:8090/createAccount/ThorG`
Now, try to have Anthony play a game with Thor while start a new game between Peter and David. It worked!
-One key feature about account is that, each account's data is segregated, meaning each account will not be able to see other account's data. In this sample cordapp, the game is queried by account name. Therefore, we see that each account only knows about the game that he participated. Account Peter doesn't know anything about the game between Thor and Anthony.
+One key feature about account is that, each account's data is segregated, meaning that it can be enforced that each account will not be able to see other account's data. In this sample CorDapp, the game is queried by account name. Therefore, we see that each account only knows about the game that he participated. Account Peter doesn't know anything about the game between Thor and Anthony.
## Credit
This project is inspired and evolved from a simple [tic-tac-toe](https://github.com/thorgilman/tictactoe) game on Corda by Thor Gilman.
diff --git a/Accounts/tictacthor/build.gradle b/Accounts/tictacthor/build.gradle
index 9fd8aeca..b33c32b0 100644
--- a/Accounts/tictacthor/build.gradle
+++ b/Accounts/tictacthor/build.gradle
@@ -15,9 +15,11 @@ buildscript {
log4j_version = constants.getProperty("log4jVersion")
slf4j_version = constants.getProperty("slf4jVersion")
corda_platform_version = constants.getProperty("platformVersion").toInteger()
+
//springboot
spring_boot_version = '2.0.2.RELEASE'
spring_boot_gradle_plugin_version = '2.0.2.RELEASE'
+
//account
accounts_release_group = 'com.r3.corda.lib.accounts'
accounts_release_version = '1.0'
@@ -29,12 +31,8 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
- maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
- // Corda dependencies for the patched Quasar version
- maven { url "https://software.r3.com/artifactory/corda-dependencies" } // access to the patched Quasar version
+
+ maven { url 'https://download.corda.net/maven/corda-releases' }
}
dependencies {
@@ -52,14 +50,14 @@ allprojects {
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
- // Can be removed post-release - used to get nightly snapshot build.
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://jitpack.io' }
- maven { url "https://repo.gradle.org/gradle/libs-releases-local" }
+ //SDK lib
+ maven { url 'https://download.corda.net/maven/corda-lib' }
+ //Gradle Plugins
+ maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
tasks.withType(JavaCompile) {
@@ -102,6 +100,7 @@ dependencies {
cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}"
cordaCompile "org.slf4j:jul-to-slf4j:$slf4j_version"
+ cordaDriver "net.corda:corda-shell:4.10"
//Account lib
cordapp "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
@@ -109,30 +108,6 @@ dependencies {
cordapp "$accounts_release_group:accounts-workflows:$accounts_release_version"
}
-cordapp {
- info {
- name "CorDapp tictacthor"
- vendor "Corda Open Source"
- targetPlatformVersion corda_platform_version
- minimumPlatformVersion corda_platform_version
- }
-}
-
-task ganache {
- subprojects {
- if (it.project.name != "clients") {
- dependsOn jar
- doLast {
- copy {
- from "${buildDir}/libs"
- into "${rootDir}/build/libs"
- }
- }
- }
- }
-}
-
-
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
nodeDefaults {
projectCordapp {
@@ -143,6 +118,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapp("$confidential_id_release_group:ci-workflows:$confidential_id_release_version")
cordapp("$accounts_release_group:accounts-contracts:$accounts_release_version")
cordapp("$accounts_release_group:accounts-workflows:$accounts_release_version")
+ runSchemaMigration = true
}
node {
name "O=Notary,L=London,C=GB"
@@ -172,15 +148,6 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
}
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
}
-// node {
-// name "O=Observer,L=Chicago,C=US,CN=John"
-// p2pPort 10011
-// rpcSettings {
-// address("localhost:10010")
-// adminAddress("localhost:10050")
-// }
-// rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
-// }
}
task installQuasar(type: Copy) {
diff --git a/Accounts/tictacthor/clients/build.gradle b/Accounts/tictacthor/clients/build.gradle
index b17168b1..bbba1aea 100644
--- a/Accounts/tictacthor/clients/build.gradle
+++ b/Accounts/tictacthor/clients/build.gradle
@@ -8,6 +8,12 @@ sourceSets {
}
}
+configurations {
+ all {
+ exclude group: 'ch.qos.logback', module: 'logback-classic'
+ }
+}
+
dependencies {
// Corda dependencies.
compile "$corda_release_group:corda-rpc:$corda_release_version"
@@ -27,17 +33,17 @@ dependencies {
}
springBoot {
- mainClassName = "com.tictacthor.webserver.Server"
+ mainClassName = "net.corda.samples.tictacthor.webserver"
}
task bootRunDevRel(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.main.runtimeClasspath
- main = 'com.tictacthor.webserver.Starter'
+ main = 'net.corda.samples.tictacthor.webserver.Starter'
args '--server.port=8080', '--config.rpc.host=localhost', '--config.rpc.port=10006', '--config.rpc.username=user1', '--config.rpc.password=test'
}
task bootRunSOE(type: JavaExec, dependsOn: jar) {
classpath = sourceSets.main.runtimeClasspath
- main = 'com.tictacthor.webserver.Starter'
+ main = 'net.corda.samples.tictacthor.webserver.Starter'
args '--server.port=8090', '--config.rpc.host=localhost', '--config.rpc.port=10009', '--config.rpc.username=user1', '--config.rpc.password=test'
}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/Client.java b/Accounts/tictacthor/clients/src/main/java/com/tictacthor/Client.java
deleted file mode 100644
index 892d7a17..00000000
--- a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/Client.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.tictacthor;
-
-import net.corda.client.rpc.CordaRPCClient;
-import net.corda.core.messaging.CordaRPCOps;
-import net.corda.core.node.NodeInfo;
-import net.corda.core.utilities.NetworkHostAndPort;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-
-import static net.corda.core.utilities.NetworkHostAndPort.parse;
-
-/**
- * Connects to a Corda node via RPC and performs RPC operations on the node.
- *
- * The RPC connection is configured using command line arguments.
- */
-public class Client {
- private static final Logger logger = LoggerFactory.getLogger(Client.class);
-
- public static void main(String[] args) {
- // Create an RPC connection to the node.
- if (args.length != 3) throw new IllegalArgumentException("Usage: Client ");
- final NetworkHostAndPort nodeAddress = parse(args[0]);
- final String rpcUsername = args[1];
- final String rpcPassword = args[2];
- final CordaRPCClient client = new CordaRPCClient(nodeAddress);
- final CordaRPCOps proxy = client.start(rpcUsername, rpcPassword).getProxy();
-
- // Interact with the node.
- // For example, here we print the nodes on the network.
- final List nodes = proxy.networkMapSnapshot();
- logger.info("{}", nodes);
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Controller.java b/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Controller.java
deleted file mode 100644
index 77ab2a0a..00000000
--- a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Controller.java
+++ /dev/null
@@ -1,218 +0,0 @@
-package com.tictacthor.webserver;
-
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.tictacthor.accountUtilities.CreateNewAccount;
-import com.tictacthor.accountUtilities.ShareAccountTo;
-import com.tictacthor.accountUtilities.myGame;
-import com.tictacthor.flows.EndGameFlow;
-import com.tictacthor.flows.StartGameFlow;
-import com.tictacthor.flows.SubmitTurnFlow;
-import com.tictacthor.states.BoardState;
-import net.corda.client.jackson.JacksonSupport;
-import net.corda.core.contracts.UniqueIdentifier;
-import net.corda.core.identity.CordaX500Name;
-import net.corda.core.identity.Party;
-import net.corda.core.messaging.CordaRPCOps;
-import net.corda.core.node.NodeInfo;
-import java.util.*;
-import org.bouncycastle.asn1.x500.X500Name;
-import org.bouncycastle.asn1.x500.style.BCStyle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.stream.Collectors;
-import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
-
-/**
- * Define your API endpoints here.
- */
-@RestController
-@RequestMapping("/") // The paths for HTTP requests are relative to this base path.
-public class Controller {
- private static final Logger logger = LoggerFactory.getLogger(RestController.class);
- private final CordaRPCOps proxy;
- private final CordaX500Name me;
-
- public Controller(NodeRPCConnection rpc) {
- this.proxy = rpc.proxy;
- this.me = proxy.nodeInfo().getLegalIdentities().get(0).getName();
-
- }
-
- /** Helpers for filtering the network map cache. */
- public String toDisplayString(X500Name name){
- return BCStyle.INSTANCE.toString(name);
- }
-
- private boolean isNotary(NodeInfo nodeInfo) {
- return !proxy.notaryIdentities()
- .stream().filter(el -> nodeInfo.isLegalIdentity(el))
- .collect(Collectors.toList()).isEmpty();
- }
-
- private boolean isMe(NodeInfo nodeInfo){
- return nodeInfo.getLegalIdentities().get(0).getName().equals(me);
- }
-
- private boolean isNetworkMap(NodeInfo nodeInfo){
- return nodeInfo.getLegalIdentities().get(0).getName().getOrganisation().equals("Network Map Service");
- }
-
- @Configuration
- class Plugin {
- @Bean
- public ObjectMapper registerModule() {
- return JacksonSupport.createNonRpcMapper();
- }
- }
-
- @GetMapping(value = "/me",produces = APPLICATION_JSON_VALUE)
- private HashMap whoami(){
- HashMap myMap = new HashMap<>();
- myMap.put("me", me.toString());
- return myMap;
- }
-
- @PostMapping(value = "createAccount/{acctName}")
- private ResponseEntity createAccount(@PathVariable String acctName){
- try{
- String result = proxy.startTrackedFlowDynamic(CreateNewAccount.class,acctName).getReturnValue().get();
- return ResponseEntity.status(HttpStatus.CREATED).body("Account "+acctName+" Created");
-
- }catch (Exception e) {
- return ResponseEntity
- .status(HttpStatus.BAD_REQUEST)
- .body(e.getMessage());
- }
- }
-
- @PostMapping(value = "requestGameWith/{whoAmI}/{team}/{competeWith}")
- private ResponseEntity requestGameWith(@PathVariable String whoAmI,@PathVariable String team, @PathVariable String competeWith){
- Set matchingPasties = proxy.partiesFromName(team,false);
- try{
-
- Iterator iter = matchingPasties.iterator();
- String result = proxy.startTrackedFlowDynamic(ShareAccountTo.class,whoAmI,iter.next()).getReturnValue().get();
- return ResponseEntity.status(HttpStatus.CREATED).body("Game Request has Sent. When "+competeWith+" accepts your challenge, the game will start!");
-
- }catch (Exception e) {
- return ResponseEntity
- .status(HttpStatus.BAD_REQUEST)
- .body(e.getMessage());
- }
- }
-
- @PostMapping(value = "acceptGameInvite/{whoAmI}/{team}/{competeWith}")
- private ResponseEntity acceptGameInvite(@PathVariable String whoAmI,@PathVariable String team, @PathVariable String competeWith){
- Set matchingPasties = proxy.partiesFromName(team,false);
- try{
-
- Iterator iter = matchingPasties.iterator();
- String result = proxy.startTrackedFlowDynamic(ShareAccountTo.class,whoAmI,iter.next()).getReturnValue().get();
- return ResponseEntity.status(HttpStatus.CREATED).body("I, "+whoAmI+" accepts "+competeWith+"'s challenge. Let's play!");
-
- }catch (Exception e) {
- return ResponseEntity
- .status(HttpStatus.BAD_REQUEST)
- .body(e.getMessage());
- }
- }
-
- @PostMapping(value = "startGameAndFirstMove/{whoAmI}/{competeWith}/{position}")
- private ResponseEntity startGameAndFirstMove(@PathVariable String whoAmI,
- @PathVariable String competeWith,
- @PathVariable String position){
- int x = -1;
- int y = -1;
- int pos = Integer.parseInt(position);
- if(pos == 0) {
- x=0;y=0;
- }else if(pos == 1){
- x=0;y=1;
- }else if(pos == 2){
- x=0;y=2;
- }else if(pos == 3){
- x=1;y=0;
- }else if(pos == 4){
- x=1;y=1;
- }else if(pos == 5){
- x=1;y=2;
- }else if(pos == 6){
- x=2;y=0;
- }else if(pos == 7){
- x=2;y=1;
- }else if(pos == 8){
- x=2;y=2;
- }
- try{
- UniqueIdentifier gameId = proxy.startTrackedFlowDynamic(StartGameFlow.class,whoAmI,competeWith).getReturnValue().get();
- String submitTurn = proxy.startTrackedFlowDynamic(SubmitTurnFlow.class, gameId, whoAmI,competeWith,x,y).getReturnValue().get();
- return ResponseEntity.status(HttpStatus.CREATED).body("Game Id Created: "+gameId+", "+whoAmI+" made the first move on position ["+x+","+y+"].");
-
- }catch (Exception e) {
- return ResponseEntity
- .status(HttpStatus.BAD_REQUEST)
- .body(e.getMessage());
- }
- }
-
- @PostMapping(value = "submitMove/{whoAmI}/{competeWith}/{position}")
- private ResponseEntity submitMove(@PathVariable String whoAmI,
- @PathVariable String competeWith,
- @PathVariable String position) {
- int x = -1;
- int y = -1;
- int pos = Integer.parseInt(position);
- if(pos == 0) {
- x=0;y=0;
- }else if(pos == 1){
- x=0;y=1;
- }else if(pos == 2){
- x=0;y=2;
- }else if(pos == 3){
- x=1;y=0;
- }else if(pos == 4){
- x=1;y=1;
- }else if(pos == 5){
- x=1;y=2;
- }else if(pos == 6){
- x=2;y=0;
- }else if(pos == 7){
- x=2;y=1;
- }else if(pos == 8){
- x=2;y=2;
- }
- try{
- UniqueIdentifier gameId = proxy.startTrackedFlowDynamic(myGame.class,whoAmI).getReturnValue().get().getLinearId();
- String submitTurn = proxy.startTrackedFlowDynamic(SubmitTurnFlow.class, gameId, whoAmI,competeWith,x,y).getReturnValue().get();
-
- if(isGameOver(whoAmI)){
- proxy.startTrackedFlowDynamic(EndGameFlow.class, gameId, whoAmI,competeWith).getReturnValue().get();
- return ResponseEntity.status(HttpStatus.CREATED).body(""+whoAmI+" made the move on position ["+x+","+y+"], and Game Over");
- }else{
- return ResponseEntity.status(HttpStatus.CREATED).body(""+whoAmI+"+ made the move on position ["+x+","+y+"]");
- }
- }catch (Exception e) {
- return ResponseEntity
- .status(HttpStatus.BAD_REQUEST)
- .body(e.getMessage());
- }
- }
-
- private Boolean isGameOver(String whoAmI){
- //If the game is over, the Status should be a null variable
- //So if the status returned is GAME_IN_PROGRESS, it means the game is not over.
- try{
- BoardState.Status gameStatus = proxy.startTrackedFlowDynamic(myGame.class,whoAmI).getReturnValue().get().getStatus();
- return gameStatus != BoardState.Status.GAME_IN_PROGRESS;
- }catch (Exception e) {
- throw new IllegalArgumentException("No board");
- }
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/NodeRPCConnection.java b/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/NodeRPCConnection.java
deleted file mode 100644
index bea1e18a..00000000
--- a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/NodeRPCConnection.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.tictacthor.webserver;
-
-import net.corda.client.rpc.CordaRPCClient;
-import net.corda.client.rpc.CordaRPCConnection;
-import net.corda.core.messaging.CordaRPCOps;
-import net.corda.core.utilities.NetworkHostAndPort;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
-/**
- * Wraps an RPC connection to a Corda node.
- *
- * The RPC connection is configured using command line arguments.
- */
-@Component
-public class NodeRPCConnection implements AutoCloseable {
- // The host of the node we are connecting to.
- @Value("${config.rpc.host}")
- private String host;
- // The RPC port of the node we are connecting to.
- @Value("${config.rpc.username}")
- private String username;
- // The username for logging into the RPC client.
- @Value("${config.rpc.password}")
- private String password;
- // The password for logging into the RPC client.
- @Value("${config.rpc.port}")
- private int rpcPort;
-
- private CordaRPCConnection rpcConnection;
- CordaRPCOps proxy;
-
- @PostConstruct
- public void initialiseNodeRPCConnection() {
- NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, rpcPort);
- CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress);
- rpcConnection = rpcClient.start(username, password);
- proxy = rpcConnection.getProxy();
- }
-
- @PreDestroy
- public void close() {
- rpcConnection.notifyServerAndClose();
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Starter.java b/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Starter.java
deleted file mode 100644
index 826b5d06..00000000
--- a/Accounts/tictacthor/clients/src/main/java/com/tictacthor/webserver/Starter.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.tictacthor.webserver;
-
-import org.springframework.boot.Banner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import static org.springframework.boot.WebApplicationType.SERVLET;
-
-/**
- * Our Spring Boot application.
- */
-@SpringBootApplication
-public class Starter {
- /**
- * Starts our Spring Boot application.
- */
- public static void main(String[] args) {
- SpringApplication app = new SpringApplication(Starter.class);
- app.setBannerMode(Banner.Mode.OFF);
- app.setWebApplicationType(SERVLET);
- app.run(args);
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/Client.java b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/Client.java
new file mode 100644
index 00000000..5a74c8cd
--- /dev/null
+++ b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/Client.java
@@ -0,0 +1,36 @@
+package net.corda.samples.tictacthor;
+
+import net.corda.client.rpc.CordaRPCClient;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.node.NodeInfo;
+import net.corda.core.utilities.NetworkHostAndPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+import static net.corda.core.utilities.NetworkHostAndPort.parse;
+
+/**
+ * Connects to a Corda node via RPC and performs RPC operations on the node.
+ *
+ * The RPC connection is configured using command line arguments.
+ */
+public class Client {
+ private static final Logger logger = LoggerFactory.getLogger(Client.class);
+
+ public static void main(String[] args) {
+ // Create an RPC connection to the node.
+ if (args.length != 3) throw new IllegalArgumentException("Usage: Client ");
+ final NetworkHostAndPort nodeAddress = parse(args[0]);
+ final String rpcUsername = args[1];
+ final String rpcPassword = args[2];
+ final CordaRPCClient client = new CordaRPCClient(nodeAddress);
+ final CordaRPCOps proxy = client.start(rpcUsername, rpcPassword).getProxy();
+
+ // Interact with the node.
+ // For example, here we print the nodes on the network.
+ final List nodes = proxy.networkMapSnapshot();
+ logger.info("{}", nodes);
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Controller.java b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Controller.java
new file mode 100644
index 00000000..eaa2c30c
--- /dev/null
+++ b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Controller.java
@@ -0,0 +1,218 @@
+package net.corda.samples.tictacthor.webserver;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import net.corda.samples.tictacthor.accountUtilities.CreateNewAccount;
+import net.corda.samples.tictacthor.accountUtilities.ShareAccountTo;
+import net.corda.samples.tictacthor.accountUtilities.myGame;
+import net.corda.samples.tictacthor.flows.EndGameFlow;
+import net.corda.samples.tictacthor.flows.StartGameFlow;
+import net.corda.samples.tictacthor.flows.SubmitTurnFlow;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.client.jackson.JacksonSupport;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.identity.Party;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.node.NodeInfo;
+import java.util.*;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.BCStyle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.stream.Collectors;
+import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
+
+/**
+ * Define your API endpoints here.
+ */
+@RestController
+@RequestMapping("/") // The paths for HTTP requests are relative to this base path.
+public class Controller {
+ private static final Logger logger = LoggerFactory.getLogger(RestController.class);
+ private final CordaRPCOps proxy;
+ private final CordaX500Name me;
+
+ public Controller(NodeRPCConnection rpc) {
+ this.proxy = rpc.proxy;
+ this.me = proxy.nodeInfo().getLegalIdentities().get(0).getName();
+
+ }
+
+ /** Helpers for filtering the network map cache. */
+ public String toDisplayString(X500Name name){
+ return BCStyle.INSTANCE.toString(name);
+ }
+
+ private boolean isNotary(NodeInfo nodeInfo) {
+ return !proxy.notaryIdentities()
+ .stream().filter(el -> nodeInfo.isLegalIdentity(el))
+ .collect(Collectors.toList()).isEmpty();
+ }
+
+ private boolean isMe(NodeInfo nodeInfo){
+ return nodeInfo.getLegalIdentities().get(0).getName().equals(me);
+ }
+
+ private boolean isNetworkMap(NodeInfo nodeInfo){
+ return nodeInfo.getLegalIdentities().get(0).getName().getOrganisation().equals("Network Map Service");
+ }
+
+ @Configuration
+ class Plugin {
+ @Bean
+ public ObjectMapper registerModule() {
+ return JacksonSupport.createNonRpcMapper();
+ }
+ }
+
+ @GetMapping(value = "/me",produces = APPLICATION_JSON_VALUE)
+ private HashMap whoami(){
+ HashMap myMap = new HashMap<>();
+ myMap.put("me", me.toString());
+ return myMap;
+ }
+
+ @PostMapping(value = "createAccount/{acctName}")
+ private ResponseEntity createAccount(@PathVariable String acctName){
+ try{
+ String result = proxy.startTrackedFlowDynamic(CreateNewAccount.class,acctName).getReturnValue().get();
+ return ResponseEntity.status(HttpStatus.CREATED).body("Account "+acctName+" Created");
+
+ }catch (Exception e) {
+ return ResponseEntity
+ .status(HttpStatus.BAD_REQUEST)
+ .body(e.getMessage());
+ }
+ }
+
+ @PostMapping(value = "requestGameWith/{whoAmI}/{team}/{competeWith}")
+ private ResponseEntity requestGameWith(@PathVariable String whoAmI,@PathVariable String team, @PathVariable String competeWith){
+ Set matchingPasties = proxy.partiesFromName(team,false);
+ try{
+
+ Iterator iter = matchingPasties.iterator();
+ String result = proxy.startTrackedFlowDynamic(ShareAccountTo.class,whoAmI,iter.next()).getReturnValue().get();
+ return ResponseEntity.status(HttpStatus.CREATED).body("Game Request has Sent. When "+competeWith+" accepts your challenge, the game will start!");
+
+ }catch (Exception e) {
+ return ResponseEntity
+ .status(HttpStatus.BAD_REQUEST)
+ .body(e.getMessage());
+ }
+ }
+
+ @PostMapping(value = "acceptGameInvite/{whoAmI}/{team}/{competeWith}")
+ private ResponseEntity acceptGameInvite(@PathVariable String whoAmI,@PathVariable String team, @PathVariable String competeWith){
+ Set matchingPasties = proxy.partiesFromName(team,false);
+ try{
+
+ Iterator iter = matchingPasties.iterator();
+ String result = proxy.startTrackedFlowDynamic(ShareAccountTo.class,whoAmI,iter.next()).getReturnValue().get();
+ return ResponseEntity.status(HttpStatus.CREATED).body("I, "+whoAmI+" accepts "+competeWith+"'s challenge. Let's play!");
+
+ }catch (Exception e) {
+ return ResponseEntity
+ .status(HttpStatus.BAD_REQUEST)
+ .body(e.getMessage());
+ }
+ }
+
+ @PostMapping(value = "startGameAndFirstMove/{whoAmI}/{competeWith}/{position}")
+ private ResponseEntity startGameAndFirstMove(@PathVariable String whoAmI,
+ @PathVariable String competeWith,
+ @PathVariable String position){
+ int x = -1;
+ int y = -1;
+ int pos = Integer.parseInt(position);
+ if(pos == 0) {
+ x=0;y=0;
+ }else if(pos == 1){
+ x=0;y=1;
+ }else if(pos == 2){
+ x=0;y=2;
+ }else if(pos == 3){
+ x=1;y=0;
+ }else if(pos == 4){
+ x=1;y=1;
+ }else if(pos == 5){
+ x=1;y=2;
+ }else if(pos == 6){
+ x=2;y=0;
+ }else if(pos == 7){
+ x=2;y=1;
+ }else if(pos == 8){
+ x=2;y=2;
+ }
+ try{
+ UniqueIdentifier gameId = proxy.startTrackedFlowDynamic(StartGameFlow.class,whoAmI,competeWith).getReturnValue().get();
+ String submitTurn = proxy.startTrackedFlowDynamic(SubmitTurnFlow.class, gameId, whoAmI,competeWith,x,y).getReturnValue().get();
+ return ResponseEntity.status(HttpStatus.CREATED).body("Game Id Created: "+gameId+", "+whoAmI+" made the first move on position ["+x+","+y+"].");
+
+ }catch (Exception e) {
+ return ResponseEntity
+ .status(HttpStatus.BAD_REQUEST)
+ .body(e.getMessage());
+ }
+ }
+
+ @PostMapping(value = "submitMove/{whoAmI}/{competeWith}/{position}")
+ private ResponseEntity submitMove(@PathVariable String whoAmI,
+ @PathVariable String competeWith,
+ @PathVariable String position) {
+ int x = -1;
+ int y = -1;
+ int pos = Integer.parseInt(position);
+ if(pos == 0) {
+ x=0;y=0;
+ }else if(pos == 1){
+ x=0;y=1;
+ }else if(pos == 2){
+ x=0;y=2;
+ }else if(pos == 3){
+ x=1;y=0;
+ }else if(pos == 4){
+ x=1;y=1;
+ }else if(pos == 5){
+ x=1;y=2;
+ }else if(pos == 6){
+ x=2;y=0;
+ }else if(pos == 7){
+ x=2;y=1;
+ }else if(pos == 8){
+ x=2;y=2;
+ }
+ try{
+ UniqueIdentifier gameId = proxy.startTrackedFlowDynamic(myGame.class,whoAmI).getReturnValue().get().getLinearId();
+ String submitTurn = proxy.startTrackedFlowDynamic(SubmitTurnFlow.class, gameId, whoAmI,competeWith,x,y).getReturnValue().get();
+
+ if(isGameOver(whoAmI)){
+ proxy.startTrackedFlowDynamic(EndGameFlow.class, gameId, whoAmI,competeWith).getReturnValue().get();
+ return ResponseEntity.status(HttpStatus.CREATED).body(""+whoAmI+" made the move on position ["+x+","+y+"], and Game Over");
+ }else{
+ return ResponseEntity.status(HttpStatus.CREATED).body(""+whoAmI+"+ made the move on position ["+x+","+y+"]");
+ }
+ }catch (Exception e) {
+ return ResponseEntity
+ .status(HttpStatus.BAD_REQUEST)
+ .body(e.getMessage());
+ }
+ }
+
+ private Boolean isGameOver(String whoAmI){
+ //If the game is over, the Status should be a null variable
+ //So if the status returned is GAME_IN_PROGRESS, it means the game is not over.
+ try{
+ BoardState.Status gameStatus = proxy.startTrackedFlowDynamic(myGame.class,whoAmI).getReturnValue().get().getStatus();
+ return gameStatus != BoardState.Status.GAME_IN_PROGRESS;
+ }catch (Exception e) {
+ throw new IllegalArgumentException("No board");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/NodeRPCConnection.java b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/NodeRPCConnection.java
new file mode 100644
index 00000000..b1c1362e
--- /dev/null
+++ b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/NodeRPCConnection.java
@@ -0,0 +1,48 @@
+package net.corda.samples.tictacthor.webserver;
+
+import net.corda.client.rpc.CordaRPCClient;
+import net.corda.client.rpc.CordaRPCConnection;
+import net.corda.core.messaging.CordaRPCOps;
+import net.corda.core.utilities.NetworkHostAndPort;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+/**
+ * Wraps an RPC connection to a Corda node.
+ *
+ * The RPC connection is configured using command line arguments.
+ */
+@Component
+public class NodeRPCConnection implements AutoCloseable {
+ // The host of the node we are connecting to.
+ @Value("${config.rpc.host}")
+ private String host;
+ // The RPC port of the node we are connecting to.
+ @Value("${config.rpc.username}")
+ private String username;
+ // The username for logging into the RPC client.
+ @Value("${config.rpc.password}")
+ private String password;
+ // The password for logging into the RPC client.
+ @Value("${config.rpc.port}")
+ private int rpcPort;
+
+ private CordaRPCConnection rpcConnection;
+ CordaRPCOps proxy;
+
+ @PostConstruct
+ public void initialiseNodeRPCConnection() {
+ NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, rpcPort);
+ CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress);
+ rpcConnection = rpcClient.start(username, password);
+ proxy = rpcConnection.getProxy();
+ }
+
+ @PreDestroy
+ public void close() {
+ rpcConnection.notifyServerAndClose();
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Starter.java b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Starter.java
new file mode 100644
index 00000000..7b1e329c
--- /dev/null
+++ b/Accounts/tictacthor/clients/src/main/java/net/corda/samples/tictacthor/webserver/Starter.java
@@ -0,0 +1,23 @@
+package net.corda.samples.tictacthor.webserver;
+
+import org.springframework.boot.Banner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import static org.springframework.boot.WebApplicationType.SERVLET;
+
+/**
+ * Our Spring Boot application.
+ */
+@SpringBootApplication
+public class Starter {
+ /**
+ * Starts our Spring Boot application.
+ */
+ public static void main(String[] args) {
+ SpringApplication app = new SpringApplication(Starter.class);
+ app.setBannerMode(Banner.Mode.OFF);
+ app.setWebApplicationType(SERVLET);
+ app.run(args);
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/contracts/build.gradle b/Accounts/tictacthor/contracts/build.gradle
index 818da95d..1ce77e8d 100644
--- a/Accounts/tictacthor/contracts/build.gradle
+++ b/Accounts/tictacthor/contracts/build.gradle
@@ -32,6 +32,6 @@ dependencies {
cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
- // Token Account dependencies.
+ // Account dependencies.
cordaCompile "$accounts_release_group:accounts-contracts:$accounts_release_version"
}
\ No newline at end of file
diff --git a/Accounts/tictacthor/contracts/src/main/java/com/tictacthor/contracts/BoardContract.java b/Accounts/tictacthor/contracts/src/main/java/com/tictacthor/contracts/BoardContract.java
deleted file mode 100644
index a39c46c7..00000000
--- a/Accounts/tictacthor/contracts/src/main/java/com/tictacthor/contracts/BoardContract.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.tictacthor.contracts;
-
-import com.tictacthor.states.BoardState;
-import kotlin.Pair;
-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 static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
-
-// ************
-// * Contract *
-// ************
-public class BoardContract implements Contract {
- // This is used to identify our contract when building a transaction.
- public static final String ID = "com.tictacthor.contracts.BoardContract";
-
- // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
- // does not throw an exception.
- @Override
- public void verify(LedgerTransaction tx) {
-
- /* We can use the requireSingleCommand function to extract command data from transaction.
- * However, it is possible to have multiple commands in a signle transaction.*/
- final CommandWithParties command = requireSingleCommand(tx.getCommands(), Commands.class);
- final Commands commandData = command.getValue();
-
- }
-
- // Used to indicate the transaction's intent.
- public interface Commands extends CommandData {
- //In our hello-world app, We will only have one command.
- class StartGame implements Commands {}
- class SubmitTurn implements Commands {}
- class EndGame implements Commands {}
-
- }
-
-
- public static class BoardUtils{
- public static Boolean isGameOver(char[][] board){
- return (board[0][0] == board [0][1] && board[0][0] == board [0][2] && (board[0][0] == 'X' || board[0][0] == 'O')) ||
- (board[0][0] == board [1][1] && board[0][0] == board [2][2]&& (board[0][0] == 'X' || board[0][0] == 'O')) ||
- (board[0][0] == board [1][0] && board[0][0] == board [2][0]&& (board[0][0] == 'X' || board[0][0] == 'O')) ||
- (board[2][0] == board [2][1] && board[2][0] == board [2][2]&& (board[2][0] == 'X' || board[2][0] == 'O')) ||
- (board[2][0] == board [1][1] && board[0][0] == board [0][2]&& (board[2][0] == 'X' || board[2][0] == 'O')) ||
- (board[0][2] == board [1][2] && board[0][2] == board [2][2]&& (board[0][2] == 'X' || board[0][2] == 'O')) ||
- (board[0][1] == board [1][1] && board[0][1] == board [2][1]&& (board[0][1] == 'X' || board[0][1] == 'O')) ||
- (board[1][0] == board [1][1] && board[1][0] == board [1][2]&& (board[1][0] == 'X' || board[1][0] == 'O'));
- }
-
- }
-}
diff --git a/Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/contracts/BoardContract.java b/Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/contracts/BoardContract.java
new file mode 100644
index 00000000..31afd2d9
--- /dev/null
+++ b/Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/contracts/BoardContract.java
@@ -0,0 +1,74 @@
+package net.corda.samples.tictacthor.contracts;
+
+import net.corda.core.contracts.CommandData;
+import net.corda.core.contracts.CommandWithParties;
+import net.corda.core.contracts.Contract;
+import net.corda.core.contracts.ContractState;
+import net.corda.core.transactions.LedgerTransaction;
+import net.corda.samples.tictacthor.states.BoardState;
+
+import java.util.List;
+
+import static net.corda.core.contracts.ContractsDSL.requireSingleCommand;
+import static net.corda.core.contracts.ContractsDSL.requireThat;
+
+// ************
+// * Contract *
+// ************
+public class BoardContract implements Contract {
+ // This is used to identify our contract when building a transaction.
+ public static final String ID = "net.corda.samples.tictacthor.contracts.BoardContract";
+
+ // A transaction is valid if the verify() function of the contract of all the transaction's input and output states
+ // does not throw an exception.
+ @Override
+ public void verify(LedgerTransaction tx) {
+ final CommandWithParties command = requireSingleCommand(tx.getCommands(), BoardContract.Commands.class);
+
+ List inputs = tx.getInputStates();
+ List outputs = tx.getOutputStates();
+
+ if (command.getValue() instanceof BoardContract.Commands.StartGame) {
+
+ // Using Corda DSL function requireThat to replicate conditions-checks
+ requireThat(require -> {
+ require.using("No inputs should be consumed when creating a new Invoice State.", inputs.isEmpty());
+ require.using("Transaction must have exactly one output.", outputs.size() == 1);
+ BoardState output = (BoardState) outputs.get(0);
+ require.using("Output board must have status GAME_IN_PROGRESS", output.getStatus() == BoardState.Status.GAME_IN_PROGRESS);
+ require.using("You cannot play a game with yourself.", output.getPlayerO() != output.getPlayerX());
+ return null;
+ });
+
+ } else if (command.getValue() instanceof BoardContract.Commands.SubmitTurn){
+
+ }else if (command.getValue() instanceof BoardContract.Commands.EndGame){
+
+ }else{
+ throw new IllegalArgumentException("Command not found!");
+ }
+
+ }
+
+ // Used to indicate the transaction's intent.
+ public interface Commands extends CommandData {
+ //In our hello-world app, We will only have one command.
+ class StartGame implements Commands {}
+ class SubmitTurn implements Commands {}
+ class EndGame implements Commands {}
+ }
+
+ public static class BoardUtils{
+ public static Boolean isGameOver(char[][] board){
+ return (board[0][0] == board [0][1] && board[0][0] == board [0][2] && (board[0][0] == 'X' || board[0][0] == 'O')) ||
+ (board[0][0] == board [1][1] && board[0][0] == board [2][2]&& (board[0][0] == 'X' || board[0][0] == 'O')) ||
+ (board[0][0] == board [1][0] && board[0][0] == board [2][0]&& (board[0][0] == 'X' || board[0][0] == 'O')) ||
+ (board[2][0] == board [2][1] && board[2][0] == board [2][2]&& (board[2][0] == 'X' || board[2][0] == 'O')) ||
+ (board[2][0] == board [1][1] && board[0][0] == board [0][2]&& (board[2][0] == 'X' || board[2][0] == 'O')) ||
+ (board[0][2] == board [1][2] && board[0][2] == board [2][2]&& (board[0][2] == 'X' || board[0][2] == 'O')) ||
+ (board[0][1] == board [1][1] && board[0][1] == board [2][1]&& (board[0][1] == 'X' || board[0][1] == 'O')) ||
+ (board[1][0] == board [1][1] && board[1][0] == board [1][2]&& (board[1][0] == 'X' || board[1][0] == 'O'));
+ }
+
+ }
+}
diff --git a/Accounts/tictacthor/contracts/src/main/java/com/tictacthor/states/BoardState.java b/Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/states/BoardState.java
similarity index 93%
rename from Accounts/tictacthor/contracts/src/main/java/com/tictacthor/states/BoardState.java
rename to Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/states/BoardState.java
index 23c0fc90..51dce4ec 100644
--- a/Accounts/tictacthor/contracts/src/main/java/com/tictacthor/states/BoardState.java
+++ b/Accounts/tictacthor/contracts/src/main/java/net/corda/samples/tictacthor/states/BoardState.java
@@ -1,7 +1,9 @@
-package com.tictacthor.states;
+package net.corda.samples.tictacthor.states;
-import com.tictacthor.contracts.BoardContract;
-import javafx.util.Pair;
+import net.corda.samples.tictacthor.contracts.BoardContract;
+//import javafx.util.Pair;
+
+import kotlin.Pair;
import net.corda.core.contracts.BelongsToContract;
import net.corda.core.contracts.LinearState;
import net.corda.core.contracts.UniqueIdentifier;
@@ -91,14 +93,14 @@ public char[][] deepCopy(){
}
public BoardState returnNewBoardAfterMove(Pair pos, AnonymousParty me, AnonymousParty competitor){
- if((pos.getKey() > 2) ||(pos.getValue()> 2)){
+ if((pos.getFirst() > 2) ||(pos.getSecond()> 2)){
throw new IllegalStateException("Invalid board index.");
}
char[][] newborad = this.deepCopy();
if(isPlayerXTurn){
- newborad[pos.getKey()][pos.getValue()] = 'X';
+ newborad[pos.getFirst()][pos.getSecond()] = 'X';
}else{
- newborad[pos.getKey()][pos.getValue()] = 'O';
+ newborad[pos.getFirst()][pos.getSecond()] = 'O';
}
if(BoardContract.BoardUtils.isGameOver(newborad)){
BoardState b = new BoardState(this.playerO,this.playerX,me,competitor,!this.isPlayerXTurn,this.linearId, newborad,Status.GAME_OVER);
@@ -111,7 +113,6 @@ public BoardState returnNewBoardAfterMove(Pair pos, AnonymousPa
//getter setter
-
public UniqueIdentifier getPlayerO() {
return playerO;
}
diff --git a/Accounts/tictacthor/contracts/src/test/java/com/tictacthor/contracts/ContractTests.java b/Accounts/tictacthor/contracts/src/test/java/com/tictacthor/contracts/ContractTests.java
deleted file mode 100644
index f05ab9c3..00000000
--- a/Accounts/tictacthor/contracts/src/test/java/com/tictacthor/contracts/ContractTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.tictacthor.contracts;
-
-import net.corda.testing.node.MockServices;
-import org.junit.Test;
-
-public class ContractTests {
- private final MockServices ledgerServices = new MockServices();
-
- @Test
- public void dummyTest() {
-
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/ContractTests.java b/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/ContractTests.java
new file mode 100644
index 00000000..94f0d1ae
--- /dev/null
+++ b/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/ContractTests.java
@@ -0,0 +1,41 @@
+package net.corda.samples.tictacthor.contracts;
+
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.testing.core.TestIdentity;
+import net.corda.testing.node.MockServices;
+import org.junit.Test;
+
+import java.util.UUID;
+
+import static net.corda.testing.node.NodeTestUtils.ledger;
+
+public class ContractTests {
+ private final MockServices ledgerServices = new MockServices();
+ TestIdentity Operator = new TestIdentity(new CordaX500Name("Alice", "TestLand", "US"));
+ TestIdentity Operator2 = new TestIdentity(new CordaX500Name("Bob", "TestLand", "US"));
+
+ @Test
+ public void GameCanOnlyCreatedWhenTwoDifferentPlayerPresented() {
+ UniqueIdentifier playerX = new UniqueIdentifier();
+ BoardState tokenPass = new BoardState(new UniqueIdentifier(),new UniqueIdentifier(),
+ new AnonymousParty(Operator.getPublicKey()),new AnonymousParty(Operator2.getPublicKey()));
+ BoardState tokenfail = new BoardState(playerX,playerX,
+ new AnonymousParty(Operator.getPublicKey()),new AnonymousParty(Operator2.getPublicKey()));
+ ledger(ledgerServices, l -> {
+ l.transaction(tx -> {
+ tx.output(BoardContract.ID, tokenfail);
+ tx.command(Operator.getPublicKey(), new BoardContract.Commands.StartGame()); // Wrong type.
+ return tx.fails();
+ });
+ l.transaction(tx -> {
+ tx.output(BoardContract.ID, tokenPass);
+ tx.command(Operator.getPublicKey(), new BoardContract.Commands.StartGame()); // Wrong type.
+ return tx.verifies();
+ });
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/StateTests.java b/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/StateTests.java
new file mode 100644
index 00000000..00602130
--- /dev/null
+++ b/Accounts/tictacthor/contracts/src/test/java/net/corda/samples/tictacthor/contracts/StateTests.java
@@ -0,0 +1,18 @@
+package net.corda.samples.tictacthor.contracts;
+
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.testing.node.MockServices;
+import org.junit.Test;
+
+public class StateTests {
+ private final MockServices ledgerServices = new MockServices();
+
+ @Test
+ public void hasFieldOfCorrectType() throws NoSuchFieldException {
+ // Does the message field exist?
+ BoardState.class.getDeclaredField("playerO");
+ // Is the message field of the correct type?
+ assert(BoardState.class.getDeclaredField("playerO").getType().equals(UniqueIdentifier.class));
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/gradle.properties b/Accounts/tictacthor/gradle.properties
index ec9fcb16..47e31d39 100644
--- a/Accounts/tictacthor/gradle.properties
+++ b/Accounts/tictacthor/gradle.properties
@@ -1,3 +1,3 @@
-name=Test
+name=Tictacthor Cordapp
group=com.tictacthor
-version=0.1
\ No newline at end of file
+version=1.0
\ No newline at end of file
diff --git a/Accounts/tictacthor/gradle/wrapper/gradle-wrapper.properties b/Accounts/tictacthor/gradle/wrapper/gradle-wrapper.properties
index 2a2a3a8e..ae01072d 100644
--- a/Accounts/tictacthor/gradle/wrapper/gradle-wrapper.properties
+++ b/Accounts/tictacthor/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/Accounts/tictacthor/repositories.gradle b/Accounts/tictacthor/repositories.gradle
index 2874c2ab..8be7b630 100644
--- a/Accounts/tictacthor/repositories.gradle
+++ b/Accounts/tictacthor/repositories.gradle
@@ -1,8 +1,8 @@
repositories {
mavenLocal()
mavenCentral()
- jcenter()
+
maven { url 'https://jitpack.io' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
}
diff --git a/Accounts/tictacthor/runServers.sh b/Accounts/tictacthor/runServers.sh
new file mode 100644
index 00000000..0807fb1f
--- /dev/null
+++ b/Accounts/tictacthor/runServers.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+./gradlew bootRunDevRel &
+./gradlew bootRunSOE
diff --git a/Accounts/tictacthor/workflows/build.gradle b/Accounts/tictacthor/workflows/build.gradle
index 5d34b3e5..e6adce24 100644
--- a/Accounts/tictacthor/workflows/build.gradle
+++ b/Accounts/tictacthor/workflows/build.gradle
@@ -57,6 +57,7 @@ dependencies {
// CorDapp dependencies.
cordapp project(":contracts")
+
//Account dependencies
cordaCompile "$confidential_id_release_group:ci-workflows:$confidential_id_release_version"
cordaCompile "$accounts_release_group:accounts-workflows:$accounts_release_version"
diff --git a/Accounts/tictacthor/workflows/src/integrationTest/java/com/tictacthor/DriverBasedTest.java b/Accounts/tictacthor/workflows/src/integrationTest/java/com/tictacthor/DriverBasedTest.java
deleted file mode 100644
index b27be9da..00000000
--- a/Accounts/tictacthor/workflows/src/integrationTest/java/com/tictacthor/DriverBasedTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.tictacthor;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.core.concurrent.CordaFuture;
-import net.corda.core.identity.CordaX500Name;
-import net.corda.testing.core.TestIdentity;
-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.List;
-
-import static net.corda.testing.driver.Driver.driver;
-import static org.junit.Assert.assertEquals;
-
-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(new DriverParameters().withIsDebug(true).withStartNodesInProcess(true), dsl -> {
- // Start a pair of nodes and wait for them both to be ready.
- List> handleFutures = ImmutableList.of(
- dsl.startNode(new NodeParameters().withProvidedName(bankA.getName())),
- dsl.startNode(new NodeParameters().withProvidedName(bankB.getName()))
- );
-
- try {
- NodeHandle partyAHandle = handleFutures.get(0).get();
- NodeHandle partyBHandle = handleFutures.get(1).get();
-
- // 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.
- assertEquals(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName()).getName(), bankB.getName());
- assertEquals(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName()).getName(), bankA.getName());
- } catch (Exception e) {
- throw new RuntimeException("Caught exception during test: ", e);
- }
-
- return null;
- });
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/integrationTest/java/net/corda/samples/tictacthor/DriverBasedTest.java b/Accounts/tictacthor/workflows/src/integrationTest/java/net/corda/samples/tictacthor/DriverBasedTest.java
new file mode 100644
index 00000000..ac0c2c26
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/integrationTest/java/net/corda/samples/tictacthor/DriverBasedTest.java
@@ -0,0 +1,48 @@
+package net.corda.samples.tictacthor;
+
+import com.google.common.collect.ImmutableList;
+import net.corda.core.concurrent.CordaFuture;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.testing.core.TestIdentity;
+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.List;
+
+import static net.corda.testing.driver.Driver.driver;
+import static org.junit.Assert.assertEquals;
+
+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(new DriverParameters().withIsDebug(true).withStartNodesInProcess(true), dsl -> {
+ // Start a pair of nodes and wait for them both to be ready.
+ List> handleFutures = ImmutableList.of(
+ dsl.startNode(new NodeParameters().withProvidedName(bankA.getName())),
+ dsl.startNode(new NodeParameters().withProvidedName(bankB.getName()))
+ );
+
+ try {
+ NodeHandle partyAHandle = handleFutures.get(0).get();
+ NodeHandle partyBHandle = handleFutures.get(1).get();
+
+ // 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.
+ assertEquals(partyAHandle.getRpc().wellKnownPartyFromX500Name(bankB.getName()).getName(), bankB.getName());
+ assertEquals(partyBHandle.getRpc().wellKnownPartyFromX500Name(bankA.getName()).getName(), bankA.getName());
+ } catch (Exception e) {
+ throw new RuntimeException("Caught exception during test: ", e);
+ }
+
+ return null;
+ });
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/CreateNewAccount.java b/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/CreateNewAccount.java
deleted file mode 100644
index 3ea3e355..00000000
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/CreateNewAccount.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.tictacthor.accountUtilities;
-
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.*;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.flows.*;
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.workflows.services.AccountService;
-import net.corda.core.flows.FlowLogic;;
-import net.corda.core.flows.StartableByRPC;
-
-import java.util.UUID;
-
-@StartableByRPC
-@StartableByService
-@InitiatingFlow
-public class CreateNewAccount extends FlowLogic{
-
- private String acctName;
-
- public CreateNewAccount(String acctName) {
- this.acctName = acctName;
- }
-
-
- @Override
- public String call() throws FlowException {
- StateAndRef newAccount = null;
- try {
- newAccount = getServiceHub().cordaService(KeyManagementBackedAccountService.class).createAccount(acctName).get();
- } catch (Exception e) {
- e.printStackTrace();
- }
- AccountInfo acct = newAccount.getState().getData();
- return "" + acct.getName() + " team's account was created. UUID is : " + acct.getIdentifier();
- }
-}
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/NewKeyForAccount.java b/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/NewKeyForAccount.java
deleted file mode 100644
index 8e5f24b2..00000000
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/NewKeyForAccount.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.tictacthor.accountUtilities;
-
-import co.paralleluniverse.fibers.Suspendable;
-import net.corda.core.flows.FlowException;
-import net.corda.core.flows.FlowLogic;
-import net.corda.core.flows.StartableByRPC;
-import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.PartyAndCertificate;
-import java.util.*;
-
-@StartableByRPC
-@StartableByService
-public class NewKeyForAccount extends FlowLogic{
-
- private final UUID accountID;
-
- public NewKeyForAccount(UUID accountID) {
- this.accountID = accountID;
- }
-
- @Override
- @Suspendable
- public PartyAndCertificate call() throws FlowException {
- return getServiceHub().getKeyManagementService().freshKeyAndCert(getOurIdentityAndCert(), false, accountID);
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ShareAccountTo.java b/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ShareAccountTo.java
deleted file mode 100644
index 401bef21..00000000
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ShareAccountTo.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.tictacthor.accountUtilities;
-
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.flows.FlowException;
-import net.corda.core.flows.FlowLogic;
-import net.corda.core.flows.StartableByRPC;
-import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.Party;
-import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
-import java.util.*;
-
-@StartableByRPC
-@StartableByService
-public class ShareAccountTo extends FlowLogic{
-
- private final Party shareTo;
- private final String acctNameShared;
-
- public ShareAccountTo(String acctNameShared, Party shareTo) {
- this.acctNameShared = acctNameShared;
- this.shareTo = shareTo;
- }
-
- @Override
- @Suspendable
- public String call() throws FlowException {
- List> allmyAccounts = getServiceHub().cordaService(KeyManagementBackedAccountService.class).ourAccounts();
- StateAndRef SharedAccount = allmyAccounts.stream()
- .filter(it -> it.getState().getData().getName().equals(acctNameShared))
- .findAny().get();
-
- subFlow(new ShareAccountInfo(SharedAccount, Arrays.asList(shareTo)));
- return "Shared " + acctNameShared + " with " + shareTo.getName().getOrganisation();
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/StartGameFlow.java b/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/StartGameFlow.java
deleted file mode 100644
index 8f0af663..00000000
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/StartGameFlow.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.tictacthor.flows;
-
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.services.AccountService;
-import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import com.sun.istack.NotNull;
-import com.tictacthor.accountUtilities.NewKeyForAccount;
-import com.tictacthor.contracts.BoardContract;
-import com.tictacthor.states.BoardState;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.contracts.UniqueIdentifier;
-import net.corda.core.crypto.TransactionSignature;
-import net.corda.core.flows.*;
-import net.corda.core.identity.AnonymousParty;
-import net.corda.core.node.services.vault.QueryCriteria;
-import net.corda.core.transactions.SignedTransaction;
-import net.corda.core.transactions.TransactionBuilder;
-import net.corda.core.utilities.ProgressTracker;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-// ******************
-// * Initiator flow *
-// ******************
-@InitiatingFlow
-@StartableByRPC
-public class StartGameFlow extends FlowLogic {
-
- private final ProgressTracker progressTracker = tracker();
-
- private static final ProgressTracker.Step GENERATING_TRANSACTION = new ProgressTracker.Step("Generating a HeartState transaction");
- private static final ProgressTracker.Step SIGNING_TRANSACTION = new ProgressTracker.Step("Signing transaction with our private key.");
- private static final ProgressTracker.Step FINALISING_TRANSACTION = new ProgressTracker.Step("Recording transaction") {
- @Override
- public ProgressTracker childProgressTracker() {
- return FinalityFlow.tracker();
- }
- };
-
- private static ProgressTracker tracker() {
- return new ProgressTracker(
- GENERATING_TRANSACTION,
- SIGNING_TRANSACTION,
- FINALISING_TRANSACTION
- );
- }
-
- @Override
- public ProgressTracker getProgressTracker() {
- return progressTracker;
- }
-
- //private variables
- private String whoAmI ;
- private String whereTo;
-
- //public constructor
- public StartGameFlow(String whoAmI, String whereTo){
- this.whoAmI = whoAmI;
- this.whereTo = whereTo;
- }
-
- @Suspendable
- @Override
- public UniqueIdentifier call() throws FlowException {
- //grab account service
- AccountService accountService = getServiceHub().cordaService(KeyManagementBackedAccountService.class);
- //grab the account information
- AccountInfo myAccount = accountService.accountInfo(whoAmI).get(0).getState().getData();
- PublicKey myKey = subFlow(new NewKeyForAccount(myAccount.getIdentifier().getId())).getOwningKey();
-
- AccountInfo targetAccount = accountService.accountInfo(whereTo).get(0).getState().getData();
- AnonymousParty targetAcctAnonymousParty = subFlow(new RequestKeyForAccount(targetAccount));
-
- //check if this account is in another game
- QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria().withExternalIds(Arrays.asList(myAccount.getIdentifier().getId()));
- List> results = getServiceHub().getVaultService().queryBy(BoardState.class,criteria).getStates();
- if(results.size() != 0){
- throw new IllegalArgumentException("You are in another game");
- }
-
- progressTracker.setCurrentStep(GENERATING_TRANSACTION);
- //generating State for transfer
- BoardState initialBoardState = new BoardState(myAccount.getIdentifier(),
- targetAccount.getIdentifier(),
- new AnonymousParty(myKey),
- targetAcctAnonymousParty);
-
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
- .addOutputState(initialBoardState)
- .addCommand(new BoardContract.Commands.StartGame(),Arrays.asList(myKey,targetAcctAnonymousParty.getOwningKey()));
-
-
- progressTracker.setCurrentStep(SIGNING_TRANSACTION);
- //self verify and sign Transaction
- txbuilder.verify(getServiceHub());
- SignedTransaction locallySignedTx = getServiceHub().signInitialTransaction(txbuilder,Arrays.asList(getOurIdentity().getOwningKey(),myKey));
-
- //Collect sigs
- FlowSession sessionForAccountToSendTo = initiateFlow(targetAccount.getHost());
- List accountToMoveToSignature = (List) subFlow(new CollectSignatureFlow(locallySignedTx,
- sessionForAccountToSendTo,targetAcctAnonymousParty.getOwningKey()));
- SignedTransaction signedByCounterParty = locallySignedTx.withAdditionalSignatures(accountToMoveToSignature);
- progressTracker.setCurrentStep(FINALISING_TRANSACTION);
- //Finalize
- subFlow(new FinalityFlow(signedByCounterParty,
- Arrays.asList(sessionForAccountToSendTo).stream().filter(it -> it.getCounterparty() != getOurIdentity()).collect(Collectors.toList())));
- return initialBoardState.getLinearId();
- }
-}
-
-
-@InitiatedBy(StartGameFlow.class)
-class StartGameFlowResponder extends FlowLogic {
- //private variable
- private FlowSession counterpartySession;
-
- //Constructor
- public StartGameFlowResponder(FlowSession counterpartySession) {
- this.counterpartySession = counterpartySession;
- }
-
- @Override
- @Suspendable
- public Void call() throws FlowException {
- subFlow(new SignTransactionFlow(counterpartySession) {
- @Override
- protected void checkTransaction(@NotNull SignedTransaction stx) throws FlowException {
- // Custom Logic to validate transaction.
- }
- });
- subFlow(new ReceiveFinalityFlow(counterpartySession));
- return null;
- }
-}
-
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SyncGame.java b/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SyncGame.java
deleted file mode 100644
index cd0c7f7a..00000000
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SyncGame.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.tictacthor.flows;
-
-import co.paralleluniverse.fibers.Suspendable;
-import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
-import com.r3.corda.lib.accounts.workflows.services.AccountService;
-import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import com.tictacthor.states.BoardState;
-import net.corda.core.contracts.StateAndRef;
-import net.corda.core.contracts.UniqueIdentifier;
-import net.corda.core.flows.FlowException;
-import net.corda.core.flows.FlowLogic;
-import net.corda.core.flows.StartableByRPC;
-import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.Party;
-import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
-import net.corda.core.node.services.Vault;
-import net.corda.core.node.services.vault.QueryCriteria;
-import com.r3.corda.lib.accounts.workflows.flows.ShareStateAndSyncAccounts;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-@StartableByRPC
-@StartableByService
-public class SyncGame extends FlowLogic{
- private String gameId;
- private Party party;
-
- public SyncGame(String gameId, Party party) {
- this.gameId = gameId;
- this.party = party;
- }
-
- @Override
- @Suspendable
- public String call() throws FlowException {
-
- UUID id = UUID.fromString(gameId);
- QueryCriteria.LinearStateQueryCriteria queryCriteria = new QueryCriteria.LinearStateQueryCriteria()
- .withUuid(Arrays.asList(id)).withStatus(Vault.StateStatus.UNCONSUMED);
- try {
- StateAndRef inputBoardStateAndRef = getServiceHub().getVaultService().queryBy(BoardState.class,queryCriteria).getStates().get(0);
- subFlow(new ShareStateAndSyncAccounts(inputBoardStateAndRef,party));
-
- }catch (Exception e){
- throw new FlowException("GameState with id "+gameId+" not found.");
- }
- return "Game synced";
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/CreateNewAccount.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/CreateNewAccount.java
new file mode 100644
index 00000000..e4a2c7c2
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/CreateNewAccount.java
@@ -0,0 +1,38 @@
+package net.corda.samples.tictacthor.accountUtilities;
+
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.*;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.flows.*;
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.accounts.workflows.services.AccountService;
+import net.corda.core.flows.FlowLogic;;
+import net.corda.core.flows.StartableByRPC;
+
+import java.util.UUID;
+
+@StartableByRPC
+@StartableByService
+@InitiatingFlow
+public class CreateNewAccount extends FlowLogic{
+
+ private String acctName;
+
+ public CreateNewAccount(String acctName) {
+ this.acctName = acctName;
+ }
+
+
+ @Override
+ public String call() throws FlowException {
+ StateAndRef newAccount = null;
+ try {
+ newAccount = getServiceHub().cordaService(KeyManagementBackedAccountService.class).createAccount(acctName).get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ AccountInfo acct = newAccount.getState().getData();
+ return "" + acct.getName() + " team's account was created. UUID is : " + acct.getIdentifier();
+ }
+}
diff --git a/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/NewKeyForAccount.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/NewKeyForAccount.java
new file mode 100644
index 00000000..d94f3bf2
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/NewKeyForAccount.java
@@ -0,0 +1,26 @@
+package net.corda.samples.tictacthor.accountUtilities;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.flows.StartableByService;
+import net.corda.core.identity.PartyAndCertificate;
+import java.util.*;
+
+@StartableByRPC
+@StartableByService
+public class NewKeyForAccount extends FlowLogic{
+
+ private final UUID accountID;
+
+ public NewKeyForAccount(UUID accountID) {
+ this.accountID = accountID;
+ }
+
+ @Override
+ @Suspendable
+ public PartyAndCertificate call() throws FlowException {
+ return getServiceHub().getKeyManagementService().freshKeyAndCert(getOurIdentityAndCert(), false, accountID);
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ShareAccountTo.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ShareAccountTo.java
new file mode 100644
index 00000000..0132589b
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ShareAccountTo.java
@@ -0,0 +1,39 @@
+package net.corda.samples.tictacthor.accountUtilities;
+
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.flows.StartableByService;
+import net.corda.core.identity.Party;
+import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
+import java.util.*;
+
+@StartableByRPC
+@StartableByService
+public class ShareAccountTo extends FlowLogic{
+
+ private final Party shareTo;
+ private final String acctNameShared;
+
+ public ShareAccountTo(String acctNameShared, Party shareTo) {
+ this.acctNameShared = acctNameShared;
+ this.shareTo = shareTo;
+ }
+
+ @Override
+ @Suspendable
+ public String call() throws FlowException {
+ List> allmyAccounts = getServiceHub().cordaService(KeyManagementBackedAccountService.class).ourAccounts();
+ StateAndRef SharedAccount = allmyAccounts.stream()
+ .filter(it -> it.getState().getData().getName().equals(acctNameShared))
+ .findAny().get();
+
+ subFlow(new ShareAccountInfo(SharedAccount, Arrays.asList(shareTo)));
+ return "Shared " + acctNameShared + " with " + shareTo.getName().getOrganisation();
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ViewMyAccounts.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ViewMyAccounts.java
similarity index 95%
rename from Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ViewMyAccounts.java
rename to Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ViewMyAccounts.java
index aba3cfe4..fc48ac7d 100644
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/ViewMyAccounts.java
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/ViewMyAccounts.java
@@ -1,4 +1,4 @@
-package com.tictacthor.accountUtilities;
+package net.corda.samples.tictacthor.accountUtilities;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/myGame.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/myGame.java
similarity index 79%
rename from Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/myGame.java
rename to Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/myGame.java
index b8f6cc6e..046751c5 100644
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/accountUtilities/myGame.java
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/accountUtilities/myGame.java
@@ -1,22 +1,17 @@
-package com.tictacthor.accountUtilities;
+package net.corda.samples.tictacthor.accountUtilities;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
-import com.r3.corda.lib.accounts.workflows.flows.AccountInfoByName;
import com.r3.corda.lib.accounts.workflows.services.AccountService;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
-import com.tictacthor.states.BoardState;
-import net.corda.core.contracts.StateAndRef;
+import net.corda.samples.tictacthor.states.BoardState;
import net.corda.core.flows.FlowException;
import net.corda.core.flows.FlowLogic;
import net.corda.core.flows.StartableByRPC;
import net.corda.core.flows.StartableByService;
-import net.corda.core.identity.Party;
-import com.r3.corda.lib.accounts.workflows.flows.ShareAccountInfo;
import net.corda.core.node.services.vault.QueryCriteria;
import java.util.*;
-import java.util.stream.Collectors;
@StartableByRPC
@StartableByService
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/EndGameFlow.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/EndGameFlow.java
similarity index 89%
rename from Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/EndGameFlow.java
rename to Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/EndGameFlow.java
index 4cbac2ba..3f9d6ab6 100644
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/EndGameFlow.java
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/EndGameFlow.java
@@ -1,4 +1,4 @@
-package com.tictacthor.flows;
+package net.corda.samples.tictacthor.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,19 +6,22 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.tictacthor.accountUtilities.NewKeyForAccount;
-import com.tictacthor.contracts.BoardContract;
-import com.tictacthor.states.BoardState;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.tictacthor.accountUtilities.NewKeyForAccount;
+import net.corda.samples.tictacthor.contracts.BoardContract;
+import net.corda.samples.tictacthor.states.BoardState;
import net.corda.core.contracts.StateAndRef;
import net.corda.core.contracts.UniqueIdentifier;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.Party;
import net.corda.core.node.services.Vault;
import net.corda.core.node.services.vault.QueryCriteria;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
+
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
@@ -90,7 +93,12 @@ public String call() throws FlowException {
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
//generating State for transfer
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ Party notary = inputBoardStateAndRef.getState().getNotary();
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addInputState(inputBoardStateAndRef)
.addCommand(new BoardContract.Commands.EndGame(),Arrays.asList(myKey,targetAcctAnonymousParty.getOwningKey()));
diff --git a/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/StartGameFlow.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/StartGameFlow.java
new file mode 100644
index 00000000..76ba4367
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/StartGameFlow.java
@@ -0,0 +1,147 @@
+package net.corda.samples.tictacthor.flows;
+
+import co.paralleluniverse.fibers.Suspendable;
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.services.AccountService;
+import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import com.sun.istack.NotNull;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.samples.tictacthor.accountUtilities.NewKeyForAccount;
+import net.corda.samples.tictacthor.contracts.BoardContract;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.crypto.TransactionSignature;
+import net.corda.core.flows.*;
+import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.Party;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.core.transactions.SignedTransaction;
+import net.corda.core.transactions.TransactionBuilder;
+import net.corda.core.utilities.ProgressTracker;
+
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+// ******************
+// * Initiator flow *
+// ******************
+@InitiatingFlow
+@StartableByRPC
+public class StartGameFlow extends FlowLogic {
+
+ private final ProgressTracker progressTracker = tracker();
+
+ private static final ProgressTracker.Step GENERATING_TRANSACTION = new ProgressTracker.Step("Generating a HeartState transaction");
+ private static final ProgressTracker.Step SIGNING_TRANSACTION = new ProgressTracker.Step("Signing transaction with our private key.");
+ private static final ProgressTracker.Step FINALISING_TRANSACTION = new ProgressTracker.Step("Recording transaction") {
+ @Override
+ public ProgressTracker childProgressTracker() {
+ return FinalityFlow.tracker();
+ }
+ };
+
+ private static ProgressTracker tracker() {
+ return new ProgressTracker(
+ GENERATING_TRANSACTION,
+ SIGNING_TRANSACTION,
+ FINALISING_TRANSACTION
+ );
+ }
+
+ @Override
+ public ProgressTracker getProgressTracker() {
+ return progressTracker;
+ }
+
+ //private variables
+ private String whoAmI ;
+ private String whereTo;
+
+ //public constructor
+ public StartGameFlow(String whoAmI, String whereTo){
+ this.whoAmI = whoAmI;
+ this.whereTo = whereTo;
+ }
+
+ @Suspendable
+ @Override
+ public UniqueIdentifier call() throws FlowException {
+ //grab account service
+ AccountService accountService = getServiceHub().cordaService(KeyManagementBackedAccountService.class);
+ //grab the account information
+ AccountInfo myAccount = accountService.accountInfo(whoAmI).get(0).getState().getData();
+ PublicKey myKey = subFlow(new NewKeyForAccount(myAccount.getIdentifier().getId())).getOwningKey();
+
+ AccountInfo targetAccount = accountService.accountInfo(whereTo).get(0).getState().getData();
+ AnonymousParty targetAcctAnonymousParty = subFlow(new RequestKeyForAccount(targetAccount));
+
+ //check if this account is in another game
+ QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria().withExternalIds(Arrays.asList(myAccount.getIdentifier().getId()));
+ List> results = getServiceHub().getVaultService().queryBy(BoardState.class,criteria).getStates();
+ if(results.size() != 0){
+ throw new IllegalArgumentException("You are in another game");
+ }
+
+ progressTracker.setCurrentStep(GENERATING_TRANSACTION);
+ //generating State for transfer
+ BoardState initialBoardState = new BoardState(myAccount.getIdentifier(),
+ targetAccount.getIdentifier(),
+ new AnonymousParty(myKey),
+ targetAcctAnonymousParty);
+
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
+ .addOutputState(initialBoardState)
+ .addCommand(new BoardContract.Commands.StartGame(),Arrays.asList(myKey,targetAcctAnonymousParty.getOwningKey()));
+
+
+ progressTracker.setCurrentStep(SIGNING_TRANSACTION);
+ //self verify and sign Transaction
+ txbuilder.verify(getServiceHub());
+ SignedTransaction locallySignedTx = getServiceHub().signInitialTransaction(txbuilder,Arrays.asList(getOurIdentity().getOwningKey(),myKey));
+
+ //Collect sigs
+ FlowSession sessionForAccountToSendTo = initiateFlow(targetAccount.getHost());
+ List accountToMoveToSignature = (List) subFlow(new CollectSignatureFlow(locallySignedTx,
+ sessionForAccountToSendTo,targetAcctAnonymousParty.getOwningKey()));
+ SignedTransaction signedByCounterParty = locallySignedTx.withAdditionalSignatures(accountToMoveToSignature);
+ progressTracker.setCurrentStep(FINALISING_TRANSACTION);
+ //Finalize
+ subFlow(new FinalityFlow(signedByCounterParty,
+ Arrays.asList(sessionForAccountToSendTo).stream().filter(it -> it.getCounterparty() != getOurIdentity()).collect(Collectors.toList())));
+ return initialBoardState.getLinearId();
+ }
+}
+
+
+@InitiatedBy(StartGameFlow.class)
+class StartGameFlowResponder extends FlowLogic {
+ //private variable
+ private FlowSession counterpartySession;
+
+ //Constructor
+ public StartGameFlowResponder(FlowSession counterpartySession) {
+ this.counterpartySession = counterpartySession;
+ }
+
+ @Override
+ @Suspendable
+ public Void call() throws FlowException {
+ subFlow(new SignTransactionFlow(counterpartySession) {
+ @Override
+ protected void checkTransaction(@NotNull SignedTransaction stx) throws FlowException {
+ // Custom Logic to validate transaction.
+ }
+ });
+ subFlow(new ReceiveFinalityFlow(counterpartySession));
+ return null;
+ }
+}
+
diff --git a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SubmitTurnFlow.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SubmitTurnFlow.java
similarity index 92%
rename from Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SubmitTurnFlow.java
rename to Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SubmitTurnFlow.java
index 4bd5b464..477f3a6a 100644
--- a/Accounts/tictacthor/workflows/src/main/java/com/tictacthor/flows/SubmitTurnFlow.java
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SubmitTurnFlow.java
@@ -1,4 +1,4 @@
-package com.tictacthor.flows;
+package net.corda.samples.tictacthor.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
@@ -6,24 +6,26 @@
import com.r3.corda.lib.accounts.workflows.flows.RequestKeyForAccount;
import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
import com.sun.istack.NotNull;
-import com.tictacthor.accountUtilities.NewKeyForAccount;
-import com.tictacthor.contracts.BoardContract;
-import com.tictacthor.states.BoardState;
-import javafx.util.Pair;
+import net.corda.samples.tictacthor.accountUtilities.NewKeyForAccount;
+import net.corda.samples.tictacthor.contracts.BoardContract;
+import net.corda.samples.tictacthor.states.BoardState;
+//import javafx.util.Pair;
+import kotlin.Pair;
import net.corda.core.contracts.StateAndRef;
import net.corda.core.contracts.UniqueIdentifier;
import net.corda.core.crypto.TransactionSignature;
import net.corda.core.flows.*;
import net.corda.core.identity.AnonymousParty;
+import net.corda.core.identity.Party;
import net.corda.core.node.services.Vault;
import net.corda.core.node.services.vault.QueryCriteria;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
+
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
-import java.util.UUID;
import java.util.stream.Collectors;
// ******************
@@ -102,7 +104,11 @@ public String call() throws FlowException {
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
//generating State for transfer
BoardState outputBoardState = inputBoardState.returnNewBoardAfterMove(new Pair<>(x,y),new AnonymousParty(myKey), targetAcctAnonymousParty);
- TransactionBuilder txbuilder = new TransactionBuilder(getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0))
+
+ // Obtain a reference to a notary we wish to use.
+ Party notary = inputBoardStateAndRef.getState().getNotary();
+
+ TransactionBuilder txbuilder = new TransactionBuilder(notary)
.addInputState(inputBoardStateAndRef)
.addOutputState(outputBoardState)
.addCommand(new BoardContract.Commands.SubmitTurn(),Arrays.asList(myKey,targetAcctAnonymousParty.getOwningKey()));
diff --git a/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SyncGame.java b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SyncGame.java
new file mode 100644
index 00000000..2703fc3a
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/main/java/net/corda/samples/tictacthor/flows/SyncGame.java
@@ -0,0 +1,44 @@
+package net.corda.samples.tictacthor.flows;
+
+import co.paralleluniverse.fibers.Suspendable;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.flows.FlowException;
+import net.corda.core.flows.FlowLogic;
+import net.corda.core.flows.StartableByRPC;
+import net.corda.core.flows.StartableByService;
+import net.corda.core.identity.Party;
+import net.corda.core.node.services.Vault;
+import net.corda.core.node.services.vault.QueryCriteria;
+import com.r3.corda.lib.accounts.workflows.flows.ShareStateAndSyncAccounts;
+
+import java.util.*;
+
+@StartableByRPC
+@StartableByService
+public class SyncGame extends FlowLogic{
+ private String gameId;
+ private Party party;
+
+ public SyncGame(String gameId, Party party) {
+ this.gameId = gameId;
+ this.party = party;
+ }
+
+ @Override
+ @Suspendable
+ public String call() throws FlowException {
+
+ UUID id = UUID.fromString(gameId);
+ QueryCriteria.LinearStateQueryCriteria queryCriteria = new QueryCriteria.LinearStateQueryCriteria()
+ .withUuid(Arrays.asList(id)).withStatus(Vault.StateStatus.UNCONSUMED);
+ try {
+ StateAndRef inputBoardStateAndRef = getServiceHub().getVaultService().queryBy(BoardState.class,queryCriteria).getStates().get(0);
+ subFlow(new ShareStateAndSyncAccounts(inputBoardStateAndRef,party));
+
+ }catch (Exception e){
+ throw new FlowException("GameState with id "+gameId+" not found.");
+ }
+ return "Game synced";
+ }
+}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/ContractTests.java b/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/ContractTests.java
deleted file mode 100644
index 8f97c2d1..00000000
--- a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/ContractTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.tictacthor;
-
-import net.corda.testing.node.MockServices;
-import org.junit.Test;
-
-public class ContractTests {
- private final MockServices ledgerServices = new MockServices();
-
- @Test
- public void dummyTest() {
-
- }
-}
\ No newline at end of file
diff --git a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/FlowTests.java b/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/FlowTests.java
deleted file mode 100644
index 4590d2db..00000000
--- a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/FlowTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.tictacthor;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.testing.node.MockNetwork;
-import net.corda.testing.node.MockNetworkParameters;
-import net.corda.testing.node.StartedMockNode;
-import net.corda.testing.node.TestCordapp;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlowTests {
- private final MockNetwork network = new MockNetwork(new MockNetworkParameters(ImmutableList.of(
- TestCordapp.findCordapp("com.tictacthor.contracts"),
- TestCordapp.findCordapp("com.tictacthor.flows")
- )));
- private final StartedMockNode a = network.createNode();
- private final StartedMockNode b = network.createNode();
-
- public FlowTests() {
- }
-
- @Before
- public void setup() {
- network.runNetwork();
- }
-
- @After
- public void tearDown() {
- network.stopNodes();
- }
-
- @Test
- public void dummyTest() {
-
- }
-}
diff --git a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/NodeDriver.java b/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/NodeDriver.java
deleted file mode 100644
index 3a4a2613..00000000
--- a/Accounts/tictacthor/workflows/src/test/java/com/tictacthor/NodeDriver.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.tictacthor;
-
-import com.google.common.collect.ImmutableList;
-import net.corda.core.identity.CordaX500Name;
-import net.corda.testing.driver.DriverParameters;
-import net.corda.testing.driver.NodeParameters;
-import net.corda.testing.node.User;
-import com.google.common.collect.ImmutableSet;
-
-import java.util.List;
-import static net.corda.testing.driver.Driver.driver;
-
-/**
- * Allows you to run your nodes through an IDE (as opposed to using deployNodes). Do not use in a production
- * environment.
- */
-public class NodeDriver {
- public static void main(String[] args) {
- final List rpcUsers =
- ImmutableList.of(new User("user1", "test", ImmutableSet.of("ALL")));
-
- driver(new DriverParameters().withStartNodesInProcess(true).withWaitForAllNodesToFinish(true), dsl -> {
- try {
- dsl.startNode(new NodeParameters()
- .withProvidedName(new CordaX500Name("PartyA", "London", "GB"))
- .withRpcUsers(rpcUsers)).get();
- dsl.startNode(new NodeParameters()
- .withProvidedName(new CordaX500Name("PartyB", "New York", "US"))
- .withRpcUsers(rpcUsers)).get();
- } catch (Throwable e) {
- System.err.println("Encountered exception in node startup: " + e.getMessage());
- e.printStackTrace();
- }
-
- return null;
- }
- );
- }
-}
diff --git a/Accounts/tictacthor/workflows/src/test/java/net/corda/samples/tictacthor/FlowTests.java b/Accounts/tictacthor/workflows/src/test/java/net/corda/samples/tictacthor/FlowTests.java
new file mode 100644
index 00000000..71f10d38
--- /dev/null
+++ b/Accounts/tictacthor/workflows/src/test/java/net/corda/samples/tictacthor/FlowTests.java
@@ -0,0 +1,95 @@
+package net.corda.samples.tictacthor;
+
+import com.google.common.collect.ImmutableList;
+import com.r3.corda.lib.accounts.contracts.states.AccountInfo;
+import com.r3.corda.lib.accounts.workflows.services.AccountService;
+import com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService;
+import net.corda.core.contracts.StateAndRef;
+import net.corda.core.contracts.UniqueIdentifier;
+import net.corda.core.identity.CordaX500Name;
+import net.corda.core.node.NetworkParameters;
+import net.corda.core.node.services.vault.QueryCriteria;
+import net.corda.samples.tictacthor.accountUtilities.CreateNewAccount;
+import net.corda.samples.tictacthor.accountUtilities.ShareAccountTo;
+import net.corda.samples.tictacthor.flows.StartGameFlow;
+import net.corda.samples.tictacthor.states.BoardState;
+import net.corda.testing.node.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.time.Instant;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class FlowTests {
+ private MockNetwork network;
+ private StartedMockNode a;
+ private StartedMockNode b;
+
+
+ private NetworkParameters testNetworkParameters =
+ new NetworkParameters(4, Arrays.asList(), 10485760, (10485760 * 5), Instant.now(),1, new LinkedHashMap<>());
+
+ @Before
+ public void setup() {
+
+ network = new MockNetwork(new MockNetworkParameters().withCordappsForAllNodes(ImmutableList.of(
+ TestCordapp.findCordapp("net.corda.samples.tictacthor.contracts"),
+ TestCordapp.findCordapp("net.corda.samples.tictacthor.flows"),
+ TestCordapp.findCordapp("com.r3.corda.lib.accounts.contracts"),
+ TestCordapp.findCordapp("com.r3.corda.lib.accounts.workflows"))).withNetworkParameters(testNetworkParameters)
+ .withNotarySpecs(ImmutableList.of(new MockNetworkNotarySpec(CordaX500Name.parse("O=Notary,L=London,C=GB"))))
+ );
+ a = network.createPartyNode(null);
+ b = network.createPartyNode(null);
+ network.runNetwork();
+ }
+
+ @After
+ public void tearDown() {
+ network.stopNodes();
+ }
+
+ @Test
+ public void AccountCreation() throws ExecutionException, InterruptedException {
+ CreateNewAccount createAcct = new CreateNewAccount("TestAccountA");
+ Future future = a.startFlow(createAcct);
+ network.runNetwork();
+ AccountService accountService = a.getServices().cordaService(KeyManagementBackedAccountService.class);
+ List> myAccount = accountService.accountInfo("TestAccountA");
+ assert (myAccount.size() != 0);
+ }
+
+ @Test
+ public void CreateGameTest() throws ExecutionException, InterruptedException {
+ CreateNewAccount createAcct = new CreateNewAccount("TestAccountA");
+ Future future = a.startFlow(createAcct);
+ network.runNetwork();
+ ShareAccountTo shareAToB = new ShareAccountTo("TestAccountA",b.getInfo().getLegalIdentities().get(0));
+ Future future2 = a.startFlow(shareAToB);
+ network.runNetwork();
+
+ CreateNewAccount createAcct2 = new CreateNewAccount("TestAccountB");
+ Future future3 = b.startFlow(createAcct2);
+ network.runNetwork();
+
+ ShareAccountTo shareBToA = new ShareAccountTo("TestAccountB",a.getInfo().getLegalIdentities().get(0));
+ Future future4 = b.startFlow(shareBToA);
+ network.runNetwork();
+
+ StartGameFlow startGame = new StartGameFlow("TestAccountA","TestAccountB");
+ Future future5 = a.startFlow(startGame);
+ network.runNetwork();
+
+ AccountService accountService = b.getServices().cordaService(KeyManagementBackedAccountService.class);
+ AccountInfo myAccount = accountService.accountInfo("TestAccountB").get(0).getState().getData();
+ QueryCriteria.VaultQueryCriteria criteria = new QueryCriteria.VaultQueryCriteria().withExternalIds(Arrays.asList(myAccount.getIdentifier().getId()));
+ List> storedGame = b.getServices().getVaultService().queryBy(BoardState.class,criteria).getStates();
+ assert (storedGame.size() != 0);
+
+ }
+
+
+}
diff --git a/Accounts/worldcupticketbooking/README.md b/Accounts/worldcupticketbooking/README.md
index e74cf618..324533db 100644
--- a/Accounts/worldcupticketbooking/README.md
+++ b/Accounts/worldcupticketbooking/README.md
@@ -1,9 +1,9 @@
-# T20 Cricket World Cup Ticket Booking Cordapp
+# T20 Cricket World Cup Ticket Booking CorDapp
## Introduction
This sample shows you how to integrate accounts and tokens. This sample talks about a scenario where typically when the Cricket season starts, BCCI (Board of Control for Cricket) starts selling tickets.
-As of now there are multiple dealers whom the BCCI issues tickets and further these dealers sell tickets to their client. We are trying to simulate similar functionality maintaining the entore issuance and selling
+As of now there are multiple dealers whom the BCCI issues tickets and further these dealers sell tickets to their client. We are trying to simulate similar functionality maintaining the entire issuance and selling
of the tickets on Corda Platform.
## Flow logic of the sample application
@@ -11,10 +11,10 @@ of the tickets on Corda Platform.
Nodes:
* BCCI node: source of ticket creation. All the tickets in the market are created by this node.
-* Bank Node: souce of money. All the money that is transacted between each individual is issued by this node.
+* Bank Node: source of money. All the money that is transacted between each individual is issued by this node.
* Dealer1 Node: Dealer Agency 1 and it includes
- * agent1 account: who will get ticket from the BCCI and sell to others. (To demostrate same node account token transaction.)
- * buyer1 account: who will get the ticket from agent1 and later sell to buyer3 (To demostrate cross node account token transaction)
+ * agent1 account: who will get ticket from the BCCI and sell to others. (To demonstrate same node account token transaction.)
+ * buyer1 account: who will get the ticket from agent1 and later sell to buyer3 (To demonstrate cross node account token transaction)
* buyer2 account: who will buy the ticket from buyer3.
* Dealer2 Node: Dealer Agency 2 and it includes
* buyer3 account: who will get the ticket from buyer1 and sell to buyer2
@@ -23,41 +23,49 @@ Nodes:
+## Pre-Requisites
+
+For development environment setup, please refer to: [Setup Guide](https://docs.r3.com/en/platform/corda/4.9/community/getting-set-up.html).
+
+## Running the sample
+Deploy and run the nodes by:
+```
+./gradlew clean build deployNodes
+./build/nodes/runnodes
+```
### Step 1
+Run the below flow in Dealer1's interactive node shell. This will create the agent1, buyer1 and buyer2 accounts on the Dealer1 node and share this account info with BCCI, Bank, and Dealer2 node respectively.
```
flow start CreateAndShareAccountFlow accountName: agent1, partyToShareAccountInfoToList: [BCCI, Dealer2]
flow start CreateAndShareAccountFlow accountName: buyer1, partyToShareAccountInfoToList: [Bank, Dealer2]
flow start CreateAndShareAccountFlow accountName: buyer2, partyToShareAccountInfoToList: [Bank, Dealer2]
```
-Run the above flow on the Dealer1 node. This will create the agent1, buyer1 and buyer2 accounts on the Dealer1 node and share this account info with BCCI, Bank, and Dealer2 node respecticely.
-Then let's go to the Dealer2 node and create buyer3 account:
+Then let's go to the Dealer2 interactive node shell and create buyer3 account:
```
flow start CreateAndShareAccountFlow accountName: buyer3, partyToShareAccountInfoToList: [Bank, Dealer1]
```
-Run the below query to confirm if accounts are created on Dealer1 node. Also run the above query on Bank and BCCI node to confirm if account info is shared with these nodes.
+Run the below query to confirm if accounts are created on Dealer1 node. Also run the below query on Bank and BCCI's interactive node shell to confirm if account info is shared with these nodes.
run vaultQuery contractStateType : com.r3.corda.lib.accounts.contracts.states.AccountInfo
-
-
### Step 2
+Run the below command on the Bank's interactive node shell, which will issue 20 USD to buyer1 account.
```
start IssueCashFlow accountName : buyer1 , currency : USD , amount : 10
start IssueCashFlow accountName : buyer3 , currency : USD , amount : 20
start IssueCashFlow accountName : buyer2 , currency : USD , amount : 50
```
-Run the above command on the Bank node, which will issue 20 USD to buyer1 account.
### Step 3
```
flow start QuerybyAccount whoAmI: buyer1
```
-You can check balance of buyer1 account at Dealer1's node
-[Option] You can also run the below command to confirm if 20 USD fungible tokens are stored at Dealer1's node. The current holder field in the output will be an AnonymousParty which specifies an account.
+You can check balance of buyer1 account at Dealer1's interactive node shell.
+[Option] You can also run the below command to confirm if 20 USD fungible tokens are stored at Dealer1's node. The current holder field in the output will be an [AnonymousParty](https://docs.r3.com/en/platform/corda/4.9/community/api-identity.html) which specifies an account.
```
run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.FungibleToken
```
@@ -65,25 +73,27 @@ run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.Fung
### Step 4
+Run the below flow on BCCI's node. BCCI node will create base token type for the T20 Ticket for the match MumbaiIndians Vs RajasthanRoyals. The ticket ID returned from this flow will be needed in the next steps.
+
start CreateT20CricketTicketTokenFlow ticketTeam : MumbaiIndiansVsRajasthanRoyals
-Run the above flow on BCCI's node. BCCI node will create base token type for the T20 Ticket for the match MumbaiIndians Vs RajasthanRoyals. The ticket ID returned from this flow will be needed in the next steps.
-You can see your ticket state generated via vault query at the BCCI'd node:
+You can see your ticket state generated via vault query at the BCCI's node:
run vaultQuery contractStateType : com.t20worldcup.states.T20CricketTicket
### Step 5
+Run the below flow on BCCI's node to issue a non-fungible token based off the token type which we created in Step5. You will need to replace the `` with the uuid returned from step 6. This token will be issued by the BCCI node to agent1 account on Dealer1 node.
+
start IssueNonFungibleTicketFlow tokenId : , dealerAccountName : agent1
-Run the above flow on BCCI's node to issue a non fungible token based off the token type which we created in Step5. You will need to replace the `` with the uuid returned from step 6. This token will be issued by the BCCI node to dealer1 account on Dealer1 node.
Switching to the Dealer1's node, you can run the following code to confirm if the token has been issued to the dealer1 account.
```
flow start QuerybyAccount whoAmI: agent1
```
-You can also look for the acutal state that is recoreded by:
+You can also look for the actual state that is recorded by:
run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.NonFungibleToken
Note that, the current holder it will be a key representing the account.
@@ -94,10 +104,10 @@ Note that, the current holder it will be a key representing the account.
flow start DVPAccountsOnSameNode tokenId: , buyerAccountName: buyer1, sellerAccountName: agent1, costOfTicket: 5, currency: USD
```
-This is the DVP flow where the buyer(buyer1 account on Dealer1 node) account will pay cash to seller account(agent1 account on Dealer1 node), and the seller accountwill transfer the ticket token to the buyer. Again, replace the `` with the uuid generated in step 6.
+This is the DVP flow where the buyer(buyer1 account on Dealer1 node) account will pay cash to seller account(agent1 account on Dealer1 node), and the seller account will transfer the ticket token to the buyer. Again, replace the `` with the uuid generated in step 6.
### Step 7
-Now lets continue the flow logic to intiate an ticket sale between buyer1 and buyer3. Go to Dealer2 node and run the following code:
+Now let's continue the flow logic to initiate a ticket sale between buyer1 and buyer3. Go to Dealer2 node and run the following code:
```
flow start DVPAccountsHostedOnDifferentNodes tokenId: , buyerAccountName: buyer3, sellerAccountName: buyer1, costOfTicket: 10, currency: USD
@@ -121,9 +131,77 @@ At Dealer2 node
flow start QuerybyAccount whoAmI: buyer3
```
-Confirm who owns the FungibleToken (cash) and NonFungibleToken (ticket) again by running this on Dealer1's node.
+Confirm who owns the [FungibleToken](https://training.corda.net/libraries/tokens-sdk/#fungibletoken) (cash) and [NonFungibleToken](https://training.corda.net/libraries/tokens-sdk/#nonfungibletoken) (ticket) again by running this on Dealer1's node.
+
+
+## Transfer tokens from one account to other
+
+For someone who is looking into how to only transfer tokens from one account to other use below steps.
+
+### Step 1
+Run the below flow on the Dealer1 node. This will create the agent1, buyer1 and buyer2 accounts on the Dealer1 node and share this account info with BCCI, Bank, and Dealer2 node respectively.
+
+```
+flow start CreateAndShareAccountFlow accountName: agent1, partyToShareAccountInfoToList: [BCCI, Dealer2]
+flow start CreateAndShareAccountFlow accountName: buyer1, partyToShareAccountInfoToList: [Bank, Dealer2]
+flow start CreateAndShareAccountFlow accountName: buyer2, partyToShareAccountInfoToList: [Bank, Dealer2]
+```
+
+Then let's go to the Dealer2 node and create buyer3 account:
+```
+flow start CreateAndShareAccountFlow accountName: buyer3, partyToShareAccountInfoToList: [Bank, Dealer1]
+```
+
+Run the below query to confirm if accounts are created on Dealer1 node. Also run the below query on Bank and BCCI node to confirm if account info is shared with these nodes.
+
+ run vaultQuery contractStateType : com.r3.corda.lib.accounts.contracts.states.AccountInfo
+
+
+### Step 2
+
+Run the below command on the Bank node, which will issue 77 USD to buyer1 account.
+
+```
+start IssueCashFlow accountName : buyer1 , currency : USD , amount : 77
+```
+
+### Step 3
+```
+flow start QuerybyAccount whoAmI: buyer1
+```
+You can check balance of buyer1 account at Dealer1's node
+[Option] You can also run the below command to confirm if 20 USD fungible tokens are stored at Dealer1's node. The current holder field in the output will be an AnonymousParty which specifies an account.
+```
+run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.FungibleToken
+```
+
+### Step 4
+
+ start MoveTokensBetweenAccounts buyerAccountName : buyer1, sellerAccountName : buyer3 , currency : USD , costOfTicket : 10
+
+This will move tokens from account buyer1 to account buyer3
+
+
+
+### Step 5
+```
+flow start QuerybyAccount whoAmI: buyer1
+```
+You can check balance of buyer1 account at Dealer1's node
+```
+run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.FungibleToken
+```
+
+### Step 6
+```
+flow start QuerybyAccount whoAmI: buyer3
+```
+You can check balance of buyer3 account at Dealer2's node
+```
+run vaultQuery contractStateType : com.r3.corda.lib.tokens.contracts.states.FungibleToken
+```
## Further Reading
For accounts visit https://github.com/corda/accounts.
diff --git a/Accounts/worldcupticketbooking/build.gradle b/Accounts/worldcupticketbooking/build.gradle
index fa9a0277..e567053f 100644
--- a/Accounts/worldcupticketbooking/build.gradle
+++ b/Accounts/worldcupticketbooking/build.gradle
@@ -36,10 +36,10 @@ buildscript {
repositories {
mavenLocal()
mavenCentral()
- jcenter()
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
- // maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
- maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
+
+ maven { url 'https://download.corda.net/maven/corda-releases' }
+ // maven { url 'http://software.r3.com/artifactory/corda-lib-dev' }
+ maven { url 'http://software.r3.com/artifactory/corda-lib' }
}
dependencies {
@@ -57,12 +57,12 @@ allprojects {
repositories {
mavenLocal()
- jcenter()
+
mavenCentral()
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
// Can be removed post-release - used to get nightly snapshot build.
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
+ maven { url 'https://download.corda.net/maven/corda-lib' }
+ maven { url 'https://download.corda.net/maven/corda-lib-dev' }
// maven { url 'https://jitpack.io' }
maven { url "https://repo.gradle.org/gradle/libs-releases-local" }
}
@@ -107,6 +107,7 @@ dependencies {
cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}"
cordaCompile "org.slf4j:jul-to-slf4j:$slf4j_version"
+ cordaDriver "net.corda:corda-shell:4.10"
//accounts
cordapp "$accounts_release_group:accounts-contracts:$accounts_release_version"
@@ -163,6 +164,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
cordapp("$tokens_release_group:tokens-workflows:$tokens_release_version")
cordapp("$tokens_release_group:tokens-money:$tokens_release_version")
cordapp("$tokens_release_group:tokens-selection:$tokens_release_version")
+ runSchemaMigration = true
}
node {
name "O=Notary,L=London,C=GB"
diff --git a/Accounts/worldcupticketbooking/clients/build.gradle b/Accounts/worldcupticketbooking/clients/build.gradle
index bfed0e1f..c6be5398 100644
--- a/Accounts/worldcupticketbooking/clients/build.gradle
+++ b/Accounts/worldcupticketbooking/clients/build.gradle
@@ -8,6 +8,12 @@ sourceSets {
}
}
+configurations {
+ all {
+ exclude group: 'ch.qos.logback', module: 'logback-classic'
+ }
+}
+
dependencies {
// Corda dependencies.
compile "$corda_release_group:corda-rpc:$corda_release_version"
diff --git a/Accounts/worldcupticketbooking/repositories.gradle b/Accounts/worldcupticketbooking/repositories.gradle
index 64f5d567..072b616b 100644
--- a/Accounts/worldcupticketbooking/repositories.gradle
+++ b/Accounts/worldcupticketbooking/repositories.gradle
@@ -1,10 +1,10 @@
repositories {
mavenLocal()
mavenCentral()
- jcenter()
+
maven { url 'https://jitpack.io' }
- maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
+ maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
- maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib-dev' }
- maven { url 'http://ci-artifactory.corda.r3cev.com/artifactory/corda-lib' }
+ maven { url 'http://software.r3.com/artifactory/corda-lib-dev' }
+ maven { url 'http://software.r3.com/artifactory/corda-lib' }
}
diff --git a/Accounts/worldcupticketbooking/workflows/build.gradle b/Accounts/worldcupticketbooking/workflows/build.gradle
index 15f078d8..b2f724d5 100644
--- a/Accounts/worldcupticketbooking/workflows/build.gradle
+++ b/Accounts/worldcupticketbooking/workflows/build.gradle
@@ -65,9 +65,9 @@ dependencies {
// Token SDK dependencies.
- cordaCompile "$tokens_release_group:tokens-money:$tokens_release_version"
cordaCompile "$tokens_release_group:tokens-workflows:$tokens_release_version"
cordaCompile "$tokens_release_group:tokens-contracts:$tokens_release_version"
+ cordaCompile "$tokens_release_group:tokens-money:$tokens_release_version"
cordapp "$tokens_release_group:tokens-selection:$tokens_release_version"
}
diff --git a/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/CreateT20CricketTicketTokenFlow.java b/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/CreateT20CricketTicketTokenFlow.java
index e6acc18d..f75f0d25 100644
--- a/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/CreateT20CricketTicketTokenFlow.java
+++ b/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/CreateT20CricketTicketTokenFlow.java
@@ -11,6 +11,7 @@
import net.corda.core.flows.StartableByRPC;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
+import net.corda.core.identity.CordaX500Name;
/**
* This flow should be run by BCCI node. BCCI node will take care of issuing the base token type for the Ipl ticket. The token type will be craeted on the BCCI node
@@ -30,8 +31,9 @@ public CreateT20CricketTicketTokenFlow(String ticketTeam) {
@Override
@Suspendable
public String call() throws FlowException {
- //get the notary
- Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
+ // Obtain a reference to a notary we wish to use.
+ /** Explicit selection of notary by CordaX500Name - argument can by coded in flows or parsed from config (Preferred)*/
+ final Party notary = getServiceHub().getNetworkMapCache().getNotary(CordaX500Name.parse("O=Notary,L=London,C=GB"));
//create token type by passing in the name of the ipl match. specify the maintainer as BCCI
UniqueIdentifier id = new UniqueIdentifier();
diff --git a/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/DVPAccountsHostedOnDifferentNodes.java b/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/DVPAccountsHostedOnDifferentNodes.java
index 86238873..39243ab4 100644
--- a/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/DVPAccountsHostedOnDifferentNodes.java
+++ b/Accounts/worldcupticketbooking/workflows/src/main/java/com/t20worldcup/flows/DVPAccountsHostedOnDifferentNodes.java
@@ -93,7 +93,7 @@ public String call() throws FlowException {
//buyer will create generate a move tokens state and send this state with new holder(seller) to seller
Amount amount = new Amount(costOfTicket, FiatCurrency.Companion.getInstance(currency));
- //Buyer Query for token balance.
+ //Buyer Query for token balance.
QueryCriteria queryCriteria = QueryUtilitiesKt.heldTokenAmountCriteria(this.getInstance(currency), buyerAccount).and(QueryUtilitiesKt.sumTokenCriteria());
List