Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Advanced/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ An capital market themed app that depicts an ideal shareable due diligence proce
An application that depicts the businsess negotiation and communication process over a distributed ledger system.
It consists of the proposing, negotiating, and settling a corda transaction.

### [Negotiation Cordapp (Key Rotation Proof-Free)](./negotiation-cordapp-key-rotation-proof-free):
An application that depicts the business negotiation and communication process over a distributed ledger system.
It consists of the proposing, negotiating, and settling a corda transaction.
This is a modified version of the Negotiation CorDapp that demonstrates how to update a CorDapp to support proof-free
key rotation.

### [Obligation Cordapp](./obligation-cordapp):
A simple i-owe-you application illustrates all of the steps of creating an obligation for a resource to change owners.

Expand Down
1 change: 1 addition & 0 deletions Advanced/constants.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
cordaReleaseGroup=net.corda
cordaCoreReleaseGroup=net.corda
cordaEnterpriseReleaseGroup=com.r3.corda
cordaVersion=4.15-SNAPSHOT
cordaCoreVersion=4.15-SNAPSHOT
cordaShellVersion=4.15-SNAPSHOT
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
13 changes: 13 additions & 0 deletions Advanced/negotiation-cordapp-key-rotation-proof-free/LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2016, R3 Limited.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
69 changes: 69 additions & 0 deletions Advanced/negotiation-cordapp-key-rotation-proof-free/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Negotiation Cordapp Proof-Free Transactions

This CorDapp shows how multi-party negotiation is handled on the Corda ledger, in the absence of an API for user
interaction. This version of the CorDapp demonstrates how to implement a negotiation flow with key rotation support
that only requires the key rotation proof to be provided when consuming a state signed by the old key.

## Concepts

A flow is provided that allows a node to propose a trade to a counterparty. The counterparty has two options:

* Accepting the proposal, converting the `ProposalState` into a `TradeState` with identical attributes
* Modifying the proposal, consuming the existing `ProposalState` and replacing it with a new `ProposalState` for a new
amount

Only the recipient of the proposal has the ability to accept it or modify it. If the sender of the proposal tries to
accept or modify the proposal, this attempt will be rejected automatically at the flow level.

### Flows

We start with the proposal flow implemented in `ProposalFlow.java`.


The modification of the proposal is implemented in `ModificationFlow.java`.


In the `AcceptanceFlow.java`, we receive the modified ProposalState and it's converted into a TradeState.



## Usage

### Pre-Requisites
For development environment setup, please refer to: [Setup Guide](https://docs.corda.net/getting-set-up.html).



### Running the nodes:

Open a terminal and go to the project root directory and type: (to deploy the nodes using bootstrapper)
```
./gradlew clean deployNodes
```
Then type: (to run the nodes)
```
./build/nodes/runnodes
```

We will interact with this CorDapp via the nodes' [CRaSH](https://docs.corda.net/docs/corda-os/shell.html) shells.

First, go the the shell of PartyA, and propose a deal with yourself as buyer and a value of 10 to PartyB:

flow start ProposalFlow$Initiator isBuyer: true, amount: 10, counterparty: PartyB

We can now look at the proposals in the PartyA's vault:

run vaultQuery contractStateType: ProposalState

If we note down the state's `linearId.id`, we can now modify the proposal from the shell of PartyB by running:

flow start ModificationFlow$Initiator proposalId: <YOUR-NEWLY-GENERATED-PROPOSAL-ID>, newAmount: 8

Finally, let's have PartyA accept the proposal:

flow start AcceptanceFlow$Initiator proposalId: <YOUR-NEWLY-GENERATED-PROPOSAL-ID>

We can now see the accepted trade in our vault with the new value by running the command (note we are now querying for
`TradeState`s, not `ProposalState`s):

run vaultQuery contractStateType: TradeState
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved.

For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at
https://www.r3.com/trademark-policy/.
192 changes: 192 additions & 0 deletions Advanced/negotiation-cordapp-key-rotation-proof-free/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import static org.gradle.api.JavaVersion.VERSION_17

buildscript {
Properties constants = new Properties()
file("$projectDir/../constants.properties").withInputStream { constants.load(it) }

ext {
corda_release_group = constants.getProperty("cordaReleaseGroup")
corda_core_release_group = constants.getProperty("cordaCoreReleaseGroup")
// This sample runs on Corda ENTERPRISE: its node, driver, shell and test artifacts come from cordaEnterpriseReleaseGroup
// (com.r3.corda). Enterprise builds on Corda OS's corda-core, which stays under cordaCoreReleaseGroup.
corda_enterprise_release_group = constants.getProperty("cordaEnterpriseReleaseGroup")
corda_release_version = constants.getProperty("cordaVersion")
corda_core_release_version = constants.getProperty("cordaCoreVersion")
corda_gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
kotlin_version = constants.getProperty("kotlinVersion")
junit_version = constants.getProperty("junitVersion")
quasar_version = constants.getProperty("quasarVersion")
quasar_exclusions = [
'co.paralleluniverse**',
'groovy**',
'com.esotericsoftware.**',
'jdk**',
'junit**',
'kotlin**',
'net.rubygrapefruit.**',
'org.gradle.**',
'org.apache.**',
'org.jacoco.**',
'org.junit**',
'org.slf4j**',
'worker.org.gradle.**',
'org.mockito.kotlin**',
'org.assertj**',
'org.hamcrest**',
'org.mockito**',
'org.opentest4j**',
'org.springframework**'
]
log4j_version = constants.getProperty("log4jVersion")
slf4j_version = constants.getProperty("slf4jVersion")
corda_platform_version = constants.getProperty("platformVersion").toInteger()
//springboot
spring_boot_version = '3.2.5'
spring_boot_gradle_plugin_version = '3.2.5'

testJvmArgs = ['--add-opens', 'java.base/java.time=ALL-UNNAMED', '--add-opens', 'java.base/java.io=ALL-UNNAMED',
'--add-opens', 'java.base/java.util=ALL-UNNAMED', '--add-opens', 'java.base/java.net=ALL-UNNAMED',
'--add-opens', 'java.base/java.nio=ALL-UNNAMED', '--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED',
'--add-opens', 'java.base/java.security.cert=ALL-UNNAMED', '--add-opens', 'java.base/java.security=ALL-UNNAMED',
'--add-opens', 'java.base/javax.net.ssl=ALL-UNNAMED', '--add-opens', 'java.base/java.lang=ALL-UNNAMED',
'--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED', '--add-opens', 'java.sql/java.sql=ALL-UNNAMED',]
}

repositories {
mavenLocal()
mavenCentral()

maven { url 'https://download.corda.net/maven/corda-dependencies' }
maven { url 'https://download.corda.net/maven/corda-releases' }
}

dependencies {
classpath "net.corda.plugins:cordapp:$corda_gradle_plugins_version"
classpath "net.corda.plugins:cordformation:$corda_gradle_plugins_version"
classpath "net.corda.plugins:quasar-utils:$corda_gradle_plugins_version"
classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_gradle_plugin_version"
}
}

allprojects {
apply from: "${rootProject.projectDir}/repositories.gradle"
apply plugin: 'java'

tasks.withType(Test) {
jvmArgs = rootProject.ext.testJvmArgs
}

repositories {
mavenLocal()

mavenCentral()
maven { url 'https://download.corda.net/maven/corda-dependencies' }
// Can be removed post-release - used to get nightly snapshot build.
maven { url 'https://download.corda.net/maven/corda-releases' }
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" }
}

java {
sourceCompatibility = VERSION_17
targetCompatibility = VERSION_17
}

compileJava {
options.compilerArgs << '-parameters'
}

jar {
// This makes the JAR's SHA-256 hash repeatable.
preserveFileTimestamps = false
reproducibleFileOrder = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}

apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'

sourceSets {
main {
resources {
srcDir rootProject.file("config/dev")
}
}
}

dependencies {
// Corda dependencies.
cordaProvided "$corda_core_release_group:corda-core:$corda_core_release_version"
cordaBootstrapper ("$corda_enterprise_release_group:corda-node-api:$corda_release_version") {
exclude group: "ch.qos.logback", module: "logback-classic"
}
corda "$corda_enterprise_release_group:corda:$corda_release_version"

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

cordaProvided "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
cordaProvided "org.apache.logging.log4j:log4j-web:${log4j_version}"
cordaProvided "org.slf4j:jul-to-slf4j:$slf4j_version"
cordaDriver "$corda_enterprise_release_group:corda-shell:$corda_release_version"
}

cordapp {
targetPlatformVersion corda_platform_version.toInteger()
minimumPlatformVersion corda_platform_version.toInteger()
workflow {
name "Negotiation CorDapp"
vendor "Corda Open Source"
licence "Apache License, Version 2.0"
versionId 1
}
}

task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {

nodeDefaults {
cordapp project(':contracts')
cordapp project(':workflows')
runSchemaMigration = true
}

node {
name "O=Notary,L=London,C=GB"
notary = [validating: false]
p2pPort 10002
rpcSettings {
address("localhost:10003")
adminAddress("localhost:10043")
}
}
node {
name "O=PartyA,L=London,C=GB"
p2pPort 10005
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10046")
}
rpcUsers = [[user: "user1", "password": "test", "permissions": ["ALL"]]]
}
node {
name "O=PartyB,L=New York,C=US"
p2pPort 10008
rpcSettings {
address("localhost:10009")
adminAddress("localhost:10049")
}
rpcUsers = [[user: "user1", "password": "test", "permissions": ["ALL"]]]
}
}

task installQuasar(type: Copy) {
destinationDir rootProject.file("lib")
from(configurations.quasar) {
rename 'quasar-core(.*).jar', 'quasar.jar'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">

<Properties>
<Property name="log-path">logs</Property>
<Property name="log-name">node-${hostName}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>

<ThresholdFilter level="trace"/>

<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}
</pattern>>
</PatternLayout>
</Console>

<!-- Will generate up to 10 log files for a given day. During every rollover it will delete
those that are older than 60 days, but keep the most recent 10 GB -->
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/${log-name}.log"
filePattern="${archive}/${log-name}.%d{yyyy-MM-dd}-%i.log.gz">

<PatternLayout pattern="[%-5level] %d{ISO8601}{GMT+0} [%t] %c{1} - %msg%n"/>

<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>

<DefaultRolloverStrategy min="1" max="10">
<Delete basePath="${archive}" maxDepth="1">
<IfFileName glob="${log-name}*.log.gz"/>
<IfLastModified age="60d">
<IfAny>
<IfAccumulatedFileSize exceeds="10 GB"/>
</IfAny>
</IfLastModified>
</Delete>
</DefaultRolloverStrategy>

</RollingFile>
</Appenders>

<Loggers>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Root>
<Logger name="net.corda" level="info" additivity="false">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="RollingFile-Appender"/>
</Logger>
</Loggers>

</Configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Properties>
<Property name="log-path">build/logs</Property>
<Property name="log-name">node-${hostName}</Property>
</Properties>

<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
[%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n
</pattern>>
</PatternLayout>
</Console>
<File name="File-Appender"
fileName="${log-path}/${log-name}.log" immediateFlush="false" append="true">
<PatternLayout pattern="[%-5level] %d{ISO8601}{GMT+0} [%t] %c{1} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="File-Appender"/>
</Root>
<Logger name="net.corda" level="info" additivity="false">
<AppenderRef ref="Console-Appender"/>
<AppenderRef ref="File-Appender"/>
</Logger>
</Loggers>
</Configuration>
Loading