Skip to content

Commit

Permalink
Encumbrance Pawn Shop Sample (#12)
Browse files Browse the repository at this point in the history
* Encumbrance Sample
  • Loading branch information
ashutoshmeher-r3 authored Aug 4, 2023
1 parent e7cfbd5 commit d09aaa0
Show file tree
Hide file tree
Showing 33 changed files with 2,021 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
**/out/
**/logs/
**/node_modules/
*~*
**/workspace/
**/CordaPIDCache.dat
*~*
118 changes: 118 additions & 0 deletions java-samples/encumbrance-pawn-shop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Corda encumbrance sample

Corda supports the idea of "Linked States", using the TransactionState.encumbrance property. When building a transaction, a state x can
point to other state y by specifying the index of y's state in the transaction output index.
In this situation x is linked to y, i.e. x is dependent on y. x cannot be consumed unless you consume y.
Hence if you want to consume x, y should also be present in the input of this transaction.
Hence y's contract is also always run, when x is about to be consumed.
In this situation, x is the encumbered state, and y is the encumbrance.
At present, if you do not specify any encumbrance, it defaults to NULL.

There are many use cases which can use encumbrance like -
1. Cross chain Atomic Swaps
2. Layer 2 games like https://github.com/akichidis/lightning-chess etc.

## About this sample

This is a basic sample which shows how you can use encumbrance in Corda. For this sample, we will have an Asset
created on Corda. We will request for a loan using the asset as a collateral. The Asset will would thus be locked
and cannot be transferred to another party till the loan has been repaid.

## Usage


### Setting up

1. We will begin our test deployment with clicking the `startCorda`. This task will load up the combined Corda workers in docker.
A successful deployment will allow you to open the REST APIs at: https://localhost:8888/api/v1/swagger#. You can test out some
functions to check connectivity. (GET /cpi function call should return an empty list as for now.)
2. We will now deploy the cordapp with a click of `5-vNodeSetup` task. Upon successful deployment of the CPI, the GET /cpi function call should now return the meta data of the cpi you just upload

## Running the app

In Corda 5, flows will be triggered via `POST /flow/{holdingidentityshorthash}` and flow result will need to be view at `GET /flow/{holdingidentityshorthash}/{clientrequestid}`
* holdingidentityshorthash: the id of the network participants, ie Alice, Bob and Charlie. You can view all the short hashes of the network member with another gradle task called `ListVNodes`
* clientrequestid: the id you specify in the flow requestBody when you trigger a flow.


### Crete The Asset

Pick the Alice VNode's identity to create the Asset. Go to POST /flow/{holdingidentityshorthash}, enter the identity short hash(Alice's hash) and request body:

{
"clientRequestId": "create-asset",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.CreateAssetFlow",
"requestBody": {
"assetName": "My Asset"
}
}

### Request Loan

Now request for a Loan from Bob, pick Alice VNode's identity again. Go to POST /flow/{holdingidentityshorthash}, enter the identity short hash(Alice's hash) and request body:

{
"clientRequestId": "request-loan",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.RequestLoanFlow",
"requestBody": {
"lender": "CN=Bob, OU=Test Dept, O=R3, L=London, C=GB",
"loanAmount": 1000,
"collateral": "<asset-id>" // Check Viewing Data in the Vault Section on get this
}
}

### Viewing Data in the Vault

You could view the Loan and the Asset using the GetLoanFlow and GetAssetFlow respectively. The request body are as below:

{
"clientRequestId": "get-asset",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.GetAssetFlow",
"requestBody": {
}
}
Replace the ```flowClassName``` with ```com.r3.developers.samples.encumbrance.workflows.GetLoanFlow``` to view the available Loans in the vault. Don't forget to change the client-id as well.

Note that the Asset is encumbered. But Encumbrances should form a complete directed cycle,
otherwise one can spend the "encumbrance" (Loan) state, which would freeze the "encumbered" (Asset) state forever.
That's why Loan should also be dependent on Asset.

### Transfer Encumbered Asset (Should Fail)

Now try to transfer the Asset to Charlie, pick Alice VNode's identity. Go to POST /flow/{holdingidentityshorthash}, enter the identity short hash(Alice's hash) and request body:

{
"clientRequestId": "transfer-asset",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.TransferAssetFlow",
"requestBody": {
"assetId": "<asset-id>", // Check Viewing Data in the Vault Section on get this
"buyer": "CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB"
}
}
This would result in an error, since the Asset is encumbered with the Loan and hence locked until the loan is repaid.


### Settle The Loan

Now to settle the Loan, pick Alice's VNode's identity. Go to POST /flow/{holdingidentityshorthash}, enter the identity short hash(Alice's hash) and request body:

{
"clientRequestId": "settle-loan",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.SettleLoanFlow",
"requestBody": {
"loanId": "<loan-id>"
}
}

### Transfer Asset
Once the Loan is settled, the asset is unlocked and can be transferred. To transfer the asset to Charlie, pick Alice's VNode's identity. Go to POST /flow/{holdingidentityshorthash}, enter the identity short hash(Alice's hash) and request body:

{
"clientRequestId": "transfer-asset-second-try",
"flowClassName": "com.r3.developers.samples.encumbrance.workflows.TransferAssetFlow",
"requestBody": {
"assetId": "<asset-id>",
"buyer": "CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB"
}
}
The transfer should not complete successfully.
67 changes: 67 additions & 0 deletions java-samples/encumbrance-pawn-shop/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import static org.gradle.api.JavaVersion.VERSION_11

plugins {
id 'org.jetbrains.kotlin.jvm'
id 'net.corda.cordapp.cordapp-configuration'
id 'org.jetbrains.kotlin.plugin.jpa'
id 'java'
id 'maven-publish'
id 'net.corda.plugins.csde'
}

allprojects {
group 'com.r3.developers.csdetemplate'
version '1.0-SNAPSHOT'

def javaVersion = VERSION_11

// Configure the CSDE
csde {
cordaClusterURL = "https://localhost:8888"
networkConfigFile = "config/static-network-config.json"
r3RootCertFile = "config/r3-ca-key.pem"
corDappCpiName = "MyCorDapp"
notaryCpiName = "NotaryServer"
cordaRpcUser = "admin"
cordaRpcPasswd ="admin"
workflowsModuleName = workflowsModule
csdeWorkspaceDir = "workspace"
notaryVersion = cordaNotaryPluginsVersion
combinedWorkerVersion = combinedWorkerJarVersion
postgresJdbcVersion = "42.4.3"
cordaDbContainerName = "CSDEpostgresql"
cordaBinDir = "${System.getProperty("user.home")}/.corda/corda5"
cordaCliBinDir = "${System.getProperty("user.home")}/.corda/cli"
}

// Declare the set of Java compiler options we need to build a CorDapp.
tasks.withType(JavaCompile) {
// -parameters - Needed for reflection and serialization to work correctly.
options.compilerArgs += [
"-parameters"
]
}

repositories {
// All dependencies are held in Maven Central
mavenLocal()
mavenCentral()
}

tasks.withType(Test).configureEach {
useJUnitPlatform()
}

}

publishing {
publications {
maven(MavenPublication) {
artifactId "corda-CSDE-java-sample"
groupId project.group
artifact jar
}

}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB7zCCAZOgAwIBAgIEFyV7dzAMBggqhkjOPQQDAgUAMFsxCzAJBgNVBAYTAkdC
MQ8wDQYDVQQHDAZMb25kb24xDjAMBgNVBAoMBUNvcmRhMQswCQYDVQQLDAJSMzEe
MBwGA1UEAwwVQ29yZGEgRGV2IENvZGUgU2lnbmVyMB4XDTIwMDYyNTE4NTI1NFoX
DTMwMDYyMzE4NTI1NFowWzELMAkGA1UEBhMCR0IxDzANBgNVBAcTBkxvbmRvbjEO
MAwGA1UEChMFQ29yZGExCzAJBgNVBAsTAlIzMR4wHAYDVQQDExVDb3JkYSBEZXYg
Q29kZSBTaWduZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQDjSJtzQ+ldDFt
pHiqdSJebOGPZcvZbmC/PIJRsZZUF1bl3PfMqyG3EmAe0CeFAfLzPQtf2qTAnmJj
lGTkkQhxo0MwQTATBgNVHSUEDDAKBggrBgEFBQcDAzALBgNVHQ8EBAMCB4AwHQYD
VR0OBBYEFLMkL2nlYRLvgZZq7GIIqbe4df4pMAwGCCqGSM49BAMCBQADSAAwRQIh
ALB0ipx6EplT1fbUKqgc7rjH+pV1RQ4oKF+TkfjPdxnAAiArBdAI15uI70wf+xlL
zU+Rc5yMtcOY4/moZUq36r0Ilg==
-----END CERTIFICATE-----
51 changes: 51 additions & 0 deletions java-samples/encumbrance-pawn-shop/config/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} %X - %msg%n"/>
</Console>

<RollingFile name="App"
fileName="logs/corda.log"
filePattern="logs/corda.%d{MM-dd-yyyy}.%i.log"
ignoreExceptions="false">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} %X - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="logs/">
<IfFileName glob="logs/corda.*.log">
<IfAny>
<IfAccumulatedFileSize exceeds="500 MB" />
<IfAccumulatedFileCount exceeds="10" />
</IfAny>
</IfFileName>
<IfLastModified age="7d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<logger name="Console">
<AppenderRef ref="Console" level="info"/>
</logger>

<!-- log warn only for these 3rd party libs -->
<Logger name="com.zaxxer.hikari" level="warn" />
<Logger name="io.javalin.Javalin" level="warn" />
<Logger name="org.apache.aries.spifly" level="warn" />
<Logger name="org.apache.kafka" level="warn" />
<Logger name="org.eclipse.jetty" level="warn" />
<Logger name="org.hibernate" level="warn" />

<!-- default to warn only for OSGi logging -->
<Logger name="net.corda.osgi.framework.OSGiFrameworkWrap" level="warn" />

<root level="debug">
<AppenderRef ref="App" level="info"/>
</root>
</Loggers>
</Configuration>
32 changes: 32 additions & 0 deletions java-samples/encumbrance-pawn-shop/config/r3-ca-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"x500Name" : "CN=Alice, OU=Test Dept, O=R3, L=London, C=GB",
"cpi" : "MyCorDapp"
},
{
"x500Name" : "CN=Bob, OU=Test Dept, O=R3, L=London, C=GB",
"cpi" : "MyCorDapp"
},
{
"x500Name" : "CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB",
"cpi" : "MyCorDapp"
},
{
"x500Name" : "CN=NotaryRep1, OU=Test Dept, O=R3, L=London, C=GB",
"cpi" : "NotaryServer",
"serviceX500Name": "CN=NotaryService, OU=Test Dept, O=R3, L=London, C=GB"
}
]
Loading

0 comments on commit d09aaa0

Please sign in to comment.