blacklist (Kotlin)
This CorDapp allows nodes to reach agreement over arbitrary strings of text, but only with parties that are not included in the blacklist uploaded to the nodes.
The blacklist takes the form of a jar including a single file, blacklist.txt
. blacklist.txt
lists the following
parties as being banned from entering into agreements:
- Crossland Savings
- TCF National Bank Wisconsin
- George State Bank
- The James Polk Stone Community Bank
- Tifton Banking Company
The blacklist jar is uploaded as an attachment when building a transaction, and used in the AgreementContract
to
check that the parties to the AgreementState
are not blacklisted.
- Learn how to handle and parse transaction attachments
- Working with X500 identities
- Hash verification
Although this example CorDapp restricts agreement over arbitrary strings of text (contained in AgreementState
) to parties not included
in the blacklist of organisations, this same blacklist functionality can be used to potentially limit:
a) agreements consisting of many other types of states.
- the blacklist is enforced in the
AgreementContract
where an overlap of the participant's organisation against the blacklist will throw a 'IllegalArgumentException - Failed Requirement'. If you have a custom state, you can use the same code in the overloaded verify function of your associated contract.Â
b) participants based on features OTHER than their organisation.
- The
AgreementContract
uses the CordaX500Name to identify the participant organisations and compare it to the attached blacklist. It's important to note that additional properties are available through the same participant identity including:   - commonName,   - organisationUnit,   - organisation,   - locality,   - state,   - and country.
Whitelisting
Another useful application of this sample is to flip the requirement condition to turn the attachment
into a whitelist. In AgreementContract
, using a statement such as
 blacklistedCompanies.toSet().containsAll(participantsOrgs)
with the infix function using
would throw an exception if any participant
 is NOT on the attachment of approved organisations.
With very little modification to the sample code you can create blacklists on these other predicates.
- Issuing tokens (see new tokenSDK) to holders based on their region (state or country). I.E. A special token that represents value only relevant to a specific area. Possibly a state tax rebate where some states do not have the program so you want to exclude them. Or a real-estate property where ownership excludes certain entities.
- Restricting agreements with participants based on some off-ledger criteria in your organization. For example, a Multi-Level-Marketing firm that does drop-shipping agreements with member-distributors. In the case that it is the requirement for a member-distributor to maintain a monthly purchase amount, members who fail to meet a quota can be placed on the blacklist.
An important thing to consider with a blacklist in attachment form is that it has the advantage of allowing you to maintain the list with off-ledger facts. There are other ways enforce a blacklist in Corda as well. For instance, you could maintain a blacklist state and use this as an input to transactions, or you could also build (blacklist-like) conditions into your contracts.Â
A use case where a blacklist attachment might NOT be suitable is saying "a party can only hold X tokens". It's possible to hold a blacklist, but it is much better off to query the vault for the current number of tokens issued to the party.
corda-nodeinfo (Kotlin)
Allows one to get some rudimentary information about a running Corda node via RPC
Useful for debugging network issues, ensuring flows have loaded etc.
After cloning, use the getInfo gradle task to retrieve node information.
./gradlew getInfo -Phost="localhost:10006" -Pusername="user1" -Ppassword="test"
> Task :getInfo
Logging into localhost:10006 as user1
Node connected: O=PartyA, L=London, C=GB
Time: 2018-02-27T11:30:37.729Z.
Flows: [com.example.flow.ExampleFlow$Initiator, net.corda.core.flows.ContractUpgradeFlow$Authorise, net.corda.core.flows.ContractUpgradeFlow$Deauthorise, net.corda.core.flows.ContractUpgradeFlow$Initiate, net.corda.finance.flows.CashConfigDataFlow, net.corda.finance.flows.CashExitFlow, net.corda.finance.flows.CashIssueAndPaymentFlow, net.corda.finance.flows.CashIssueFlow, net.corda.finance.flows.CashPaymentFlow]
Platform version: 2
Current Network Map Status -->
-- O=PartyA, L=London, C=GB @ localhost
-- O=Controller, L=London, C=GB @ localhost
-- O=PartyB, L=New York, C=US @ localhost
-- O=PartyC, L=Paris, C=FR @ localhost
-- O=Notary, L=London, C=GB @ localhost
Registered Notaries -->
-- O=Notary, L=London, C=GB
-- O=Controller, L=London, C=GB
- connecting to nodes using
CordaRPCClient
- creating queries with
CordaRPCOps
link - connecting directly to queues with AMQP
- This sample is useful when you want to retrieve a topology of the network map
- an app that is triggered by changes in node participation
- tracking node behaviors over time
- Flow availability
- putting controls on available flows on the network
- monitoring
- Reference the CordaRPCOps docs and issue additional commands or queries to the connected node
- Export info to local logs for analysis or tracking
- Build a front-end to interact with your app through CordaRPCOps
See Docs related to the CordaRPCClient
cordapp-example (Kotlin, Java)
This CorDapp allows nodes to agree IOUs with each other, as long as they obey the following contract rules:
- The IOU’s value is strictly positive
- A node is not trying to issue an IOU to itself
There is more extensive documentation in a tutorial format available [here](This CorDapp is documented here)
- Contract, State, and Flow structures
- Providence and evolving facts through the use of LinearState interface
- mapping Schemas and use of QueryableState
- using ProgressTracker and steps
Any case where you need to agree that a certain party/parties are indebted or required to execute performance of some criteria to satisfy the counter-party.
The paradigm of an IOU contract can apply to many real world uses which extend on the same code-base and structure of this example.
Escrows - You can take the IOU agreement and modify the contract to verify a certain condition creating a conditional escrow (either on-ledger or off, see Oracles)
Tokens/States - The IOU example uses a simple Integer value to represent the amount owed. This is the most basic realization of the IOU and misses possibly important data such as currency, non-monetary assets, fractional stakes. You can create an IOU using Corda Token SDK to generate IOUs on many types of defined assets including; DigitalCurrency, Fiat, Fungible Tokens, Non-Fungible Tokens, Evolving Tokens, and more!
Time-Windows - Extend your IOU to include a Time Window in order to add characteristics such as: interest accrual, deadlines, depreciation/appreciation etc.
Split and Merge - IOU can be extended to handle further complexity than just a single lender / borrower. With the basic IOU state, you can consume an existing IOU and split the value across multiple output IOUs. Likewise, you can take multiple IOUs as input states and then combine them into a single IOU.
None.
explicit-cordapp-upgrades (Kotlin)
This CorDapp shows the end-to-end process of upgrading contracts in Corda, using the explicit Contract Upgrade Flow. A demonstration of implicit upgrades using Signature Constraints can be found in the Implicit Cordapp Upgrades app (https://github.com/corda/samples/tree/release-V4/implicit-cordapp-upgrades)
The upgrade takes place in four stages:
- Create a replacement contract implementing the UpgradedContract interface and the accompanying state
- Bundle the replacement contract and state into a CorDapp and install it on each node
- For each state you wish to upgrade the contract of, authorise the contract upgrade for that state on each node
- On a single node, run the contract upgrade for each state you wish to upgrade the contract of
- Establishing a connection to nodes via CordaRPCClient
- Running flows on states filtered by associated contract ID
- Using Corda's
ContractUpgradeFlow
to Authrise and then Upgrade state instances - Implementing
UpgradedContract
interface.
General reason you would want to execute an Explicit Contract Upgrade could be:
- Changing the verification of transactions based on some new requirement agreed by all parties. (Note: if new verify logic is not required by all participants you can bypass potential contract upgrades by using Clauses)
See the following links for more in-depth description of scenarios suited to Explicit Contract Upgrades
Contract Upgrades and Constraints in V3
-
The implementation of the UpgradedContract interface function
upgrade
contained incom.upgrade.new.NewContract
 defines the upgrade path in regards to transitioning to new states linked to the new contract. In this example we can see that the states are not modified but you may wish to transition to new state definitions during the contract upgrade. You can modify this upgrade logic. -
You may also find this code useful in an automation of updating off-ledger agreements which have a corresponding ledger representation. For example,
UpgradeContractClient
in Client.kt makes calls to Corda'sContractUpgradeFlow
with theNewContract
class as a parameter. By pushing changes in contract properties into a template engine, or by creating a transaction with the new contract properties stored in an attachment; you can dynamically generate theNewContract
and execute an automated explicit update on new contract requirements.
Also see Implicit Cordapp Upgrades
flow-db (Kotlin)
This CorDapp provides a simple example of how the node database can be accessed in flows. In this case, the flows maintain a table of cryptocurrency values in the node's database. There are three flows:
The CorDapp defines three flows:
AddTokenValueFlow, which adds a new token to the database table with an initial value UpdateTokenValueFlow, which updates the value of an existing token in the database table QueryTokenValueFlow, which reads the value of an existing token from the database table Under the hood, the database accesses are managed by the CryptoValuesDatabaseService CordaService.
Be aware that support of database accesses in flows is currently limited:
The operation must be executed in a BLOCKING way. Flows don't currently support suspending to await an operation's response The operation must be idempotent. If the flow fails and has to restart from a checkpoint, the operation will also be replayed
- Testing with MockNetworks and Unit-tests
- Initiating a jdbcSession through a node's ServiceHub
- Creating a custom cordaService to handle serialization/deserialization of tokens
- Defining custom SQL queries and mapping parameters to the queries
- Accessing Legacy databases / integration with existing systems
- Storing reference data uncoupled from a state
- table of crypto-token values (this sample)
- addresses/information of entities who do not have an on-ledger representation
- URLs or mirror links
- GDPR compliance (some customer data may not be suitable on an immutable ledger)
- Interact with a different database (see Node Configuration)
- Implement more complex SQL queries in
CryptoValuesDatabaseService
- Execute custom sub-flows based on SQL return values
By default nodes are configured to use an H2 database but PostgreSQL and SQLserver can easily by used instead.
flow-http (Kotlin)
This CorDapp provides a simple example of how HTTP requests can be made in flows. In this case, the flow makes an HTTP request to retrieve the original BitCoin readme from GitHub.
Be aware that support of HTTP requests in flows is currently limited:
The request must be executed in a BLOCKING way. Flows don't currently support suspending to await an HTTP call's response The request must be idempotent. If the flow fails and has to restart from a checkpoint, the request will also be replayed
- Http request from within a flow
- Using libraries within your flows
- You want to interact through flows with API endpoints
- Have transaction details forwarded to an analytics service etc.
- Do a GET request to retrieve details
- Retrieve (non-critical) data from the web to modify states or execute conditional behavior
- Parse a web-page
- Try interacting with a 3rd party API service
- Build in error handling for failed responses
- Take transaction details and issue http receipts with details.
Important! This simple request must be executed in a BLOCKING manner. If you are wishing to use HTTP request responses in state verification, or take advantage of Corda's state machine serialization behavior please look at implementing Oracles - to ensure multiple nodes are presented with the same response.
heartbeat (Kotlin)
This CorDapp is a simple showcase of scheduled activities (i.e. activities started by a node at a specific time without direct input from the node owner).
A node starts its heartbeat by calling the StartHeartbeatFlow. This creates a HeartState on the ledger. This HeartState has a scheduled activity to start the HeatbeatFlow one second later.
When the HeartbeatFlow runs one second later, it consumes the existing HeartState and creates a new HeartState. The new HeartState also has a scheduled activity to start the HeatbeatFlow in one second.
In this way, calling the StartHeartbeatFlow creates an endless chain of HeartbeatFlows one second apart.
- initializing Java
Instant
object to represent time from Epoch - implementation of
ScheduledState
interface on the state object so defined flow will execute at the passed Instant. - user of
ProgressTracker
to track stages of Flow and subFlow
- Issue monthly statements on a schedule
- generate a balance report
- create an Obligation or IOU for a recurring time-frame or point in the future
- Have your CorDapp delay a Flow in anticipation of a future event
- wait for an on-ledger independent transaction
- wait for an off-ledger condition through the use of an Oracle
- Creating a continuous "clock-cycle" like execution (as this sample does)
- execute batch transactions through regular cycles
- Override the
Instant
parameter of the HeartState primary constructor to set different delays - Add conditions to create dynamic schedules based on some state of the world
- For example, query the network map for number of Notaries and vary delay a flow based on network resources.
- Use extended recurring subFlows (similar to the sample) with varying delays to compose a song or return an artistic output.
yo-cordapp (Kotlin)
This CorDapp showcases the basic features of a state, contract, and flow.
In this CorDapp you can send Yo's! to all your friends running Corda nodes!
- Create simple states
- Create simple contracts
- Create simple flows
- Create simple validation of flows (e.g prevent transactions being sent to certain parties)
- Learn how to interact with the shell
- Any CorDapp requires these basic components to communicate between nodes.
- If you want to record information on-ledger (sharing it with other nodes), you'll need to create these basic components.
- Extend the state to hold more information than just a string.
- Create more complex flows (maybe recieving a 'yo!' triggers an automatic response of a
HelloState
) - Try querying information from the vault in a flow.
whistleblower (Kotlin)
This CorDapp is a simple showcase of confidential identities (i.e. anonymous public keys).
A node (the whistle-blower) can whistle-blow on a company to another node (the investigator). Both the whistle-blower and the investigator generate anonymous public keys for this transaction, meaning that any third-parties who manage to get ahold of the state cannot identity the whistle-blower or investigator.
-
Generate anonymous identities (using
SwapIdentitiesFlow
) -
Sign a transaction using anonymous keys
- Have a three way communication where the two noninitiating participants don't know eachothers identities
- A central orangiser wants to exchange the same information to two potential investors, but the two potential investors shouldn't know eachothers legal identities.
- Two parties are in a competition organised by a third party. The third party wishes to give the same information to the two parties but doesn't want them to know eachothers legal identities.
- Several parties have placed anonymous bids. The third party needs to send information to the parties who have successfully placed the bid but doesn't want to leak who has/hasn't placed a bid.
- Use a state for reference but keep the parties involved in that state anonymous
- Hide the purchase trail of private buyers but allow for the validation of the issuer
- In persisted data, obfuscate the originator of a transaction
- purchasing multiple train tickets: keep the journeys from being related if the database leaks
- In the
BlowWhistleFlowResponder
class, thecheckTransaction
function is incomplete. Add some validation for the transaction. - Once a complaint has been lodged, a party may want to take action. Create a state for these actions and a flow that references the original complaint.
timesheet-example (Kotlin)
This CordApp demonstrates the use of schemas in a transaction.
In this CorDapp, two nodes can exchange an IOU that encapsulates a QueryableState
which returns an instance of a schema object. This schema object is the invoice and holds all of the information related to the IOU.
- Write a
MappedSchema
- Write a
QueryableState
- Use a
MappedSchema
in a flow - Create an Oracle to retrieve external information
- Use data classes to transfer information between Oracles and nodes
- Export the information in a state into a database compatable schema.
- You may have previously existing databases that you want to store state information in, off-ledger. You can write a schema that corresponds to the required fields and use this to hold your state information.
- You might want to create a custom table with your own defined attributes in your node's database. You can the query the vault according to these attributes.
- One of your flows may use states that hold evolving information about the amount of money left in an IOU agreement. Maybe you want to send out a notice to all nodes that owe you more than a threshold (maybe those who owe you more than ÂŁ100). You could use this newly defined table to query the vault specifically on the 'amountOwed' attribute.
- Create relational joins between the node's tables and your organisation's tables
- You may use Corda to keep track of purchases. Perhaps you have to insist that the productIDs of those items sold corresponds to some productId you use internally to keep track of your stock.
- Add code in
SalaryRateOracle
to handle the case where a pay rate is missing. - In
InvoiceContract
write a clause that supports a partial payment. - Create code that registers a new job when it commences and links the invoice to that job.
See the API for QueryableState
spring-webserver (Kotlin)
This project defines a simple Spring webserver that connects to a Corda node via RPC.
- Create a Spring Boot server
- Create a RESTful API for Corda
- Present information from the Corda nodes over HTTP
- Maybe you are a museum that is leasing out art works. These lease agreements are kept track of using a Corda APP, but the museums' curators aren't familiar with Corda and don't want to have to worry about using the shell to retrieve this information. You could create a web interface that retrieves data from the vault and presents it in an HTML file.
- Trigger flows from a node over HTTP
- Perhaps you're running a public node that allows users of your website to cast a ballot in some vote. You can do all of the login functionality from a standard web front end and create a REST API that triggers Corda functionality. You can guard end points the same way you would with a normal API.
- Display flow progress
- Perhaps you are managing an extensive registration process that requires a lot of back and forth between two parties. For example, student finance. It may be useful for the counterParty (in this instance, a student) to see where the application presently is (and what are the next steps). This could be done as a series of subflows (in which case, there could be a state keeping track of the students application), or a database update could occur during the flow and this is queried via an HTTP call to display progress in situ.
- This sample hasn't created any flows that the API end points are connected to. Using an application you've already developed, connect the API to your flows.
reference-states (Kotlin)
This CorDapp demonstrates the use of reference states in a transaction and in the verification method of a contract.
This CorDapp allows two nodes to enter into an IOU agreement, but enforces that both parties belong to a list of sanctioned entities.
This list of sanctioned entities is taken from a referenced SanctionedEntities
state.
- Append a reference state to a transaction
- When you want need the information from an updating state but you don't want to consume it in a transaction
- You are a company that maintains a number of projects and you work with a number of different partners on these projects. You have one state that maintains the list of active partners currently working with you.
This state periodically is updated when new partners are added or old ones are removed. When a new project is commenced, a new state is created for that project. That project assigns partners to work on it and this list is maintained in its state.
Perodically, this project state is updated to track the progress of that project and to add or remove partners who are actively working on it. Whenever this state is updated, you want to be sure that all the partners that you have working on that
project are actively partnered with you. To make sure this is the case, you want to include a reference to your active partners state. NOTE: It may be the case that the
activePartners
state used by the initiating party is outdated. In order to circumvent this issue, you'd want to include a referencing state that holds a StatePointer (of typeLinearID
) that points to the activePartners state.
- You are a company that maintains a number of projects and you work with a number of different partners on these projects. You have one state that maintains the list of active partners currently working with you.
This state periodically is updated when new partners are added or old ones are removed. When a new project is commenced, a new state is created for that project. That project assigns partners to work on it and this list is maintained in its state.
Perodically, this project state is updated to track the progress of that project and to add or remove partners who are actively working on it. Whenever this state is updated, you want to be sure that all the partners that you have working on that
project are actively partnered with you. To make sure this is the case, you want to include a reference to your active partners state. NOTE: It may be the case that the
- Add a command for transferring an IOU to a new beneficiary and require that this beneficiary is a sanctioned entity.
- Add a StatePointer to the referenced state and use that to point to the SanctionedEntity to ensure that the SanctionedEntity list is the most up to date.
When you use a reference state in a transaction, the contract for that state is also not executed.
pigtail (Kotlin)
This CorDapp sample demonstrates how to setup a Braid service and JS client to interact with a Corda backend.
- Bootstrap a braid server through a CordaService
- Add flows and services to braid server
- Setup config for the braid server including port number and HTTPS vs HTTP
- Expose HTTP endpoints using a Braid Service that can be consumed by a Javascript client
- See spring-webserver example
- Take an application you've already built (or one of the other samples) and expose it's flows using the Braid service.
oracle-example (Kotlin)
This CorDapp is a simple example of how to structure an oracle service that provides querying and signing abilities
This CorDapp implements an oracle service that allows nodes to:
- Request the Nth prime number
- Request the oracle's signature to prove that the number included in their transaction is actually the Nth prime number
- How to write an oracle
- How to write flows for an oracle
- How to request information from an oracle
- How to get an oracle to sign some information
- How to add an oracle as a required signer for a transaction
- Request information from a trusted third party
- All corDapps HAVE to be deterministic so that they can be verified. As a result, you can't use external information straight in your contracts. However, there may be occasions when you require a piece of third party information. One way of obtaining that information is to request it from an oracle class. For instance, suppose you have an agreement established in a state on the ledger that states, if it rains on wednesday, partyB will owe partyA ÂŁ100. You could retrieve the weather report on any given day by requesting it from an oralce (including a time-window in your transaction could guarantee that the informaton was obtained on a wednesday)
- Have information signed for by a trusted third party
- There is some infromation already available to you, but in order for your counterparty to accept it, they want some assurance that it is legitimate. For example, in order to transact with you the counterparty wants to guarantee that your company has registered with a certain organisation. Now, we could provide a certification that claims this to be true but perhaps the counterparty wants that information to be signed off on by a trusted third party before it will accept the transaction. We could send this certification to the trusted third party (the oracle) and have them sign off on the information.
- Create an oracle for information that can't be deterministically generated by the nodes (E.G access a weather report API or pull ina file stored by the oracle)
observable-states (Kotlin)
This CorDapp shows how Corda's observable states feature works. Observable states is the ability for nodes who are not participants in a transaction to still store them if the transactions are sent to them.
In this CorDapp, we assume that when a seller creates some kind of HighlyRegulatedState
, they must notify the state
and national regulators. There are two ways to use observable states:
- Manually send a non-signing party a copy of a signed transaction
- Have a party store a state in their vault without having to be a required signer on it
- In a transaction you have a third party that you don't want to give the opportunity to block your transactions but has to be made aware of a transaction that has taken place. Perhaps you are maintaining a closed auction and, upon the auction closing, you are required by a regulator to announce the winner of the bid to all involved parties and the regulator. You don't want the losing parties to be able to block the closing of the auction (for self interest, they may decide to not sign), but they do need to see the finished state.
- Automate the sending of a signed transaction to a non-signing party via the
FinalityFlow
obligation-cordapp (Kotlin, Java)
This CorDapp comprises a demo of an IOU-like agreement that can be issued, transfered and settled confidentially.
The CorDapp allows you to issue, transfer (from old lender to new lender) and settle (with cash) obligations. It also comes with an API and website that allows you to do all of the aforementioned things.
- Use anonymous identities in transactions
- Create an obligation
- Transfer ownership of an obligation between parties
- Connect AngularJS to a Corda backend in java and kotlin
- Compare token types
- Create financial instruments that can change ownership
- You may have lent money to another party and created an obligation on Corda to record this transaction. You may want to be able to sell this obligation to another party in the future (so that, now, the borrower owes the new lender the money)
- Create obligations with anonymised participants
- If you're creating a state that may frequently change hands (e.g an obligation that's intended to be used as a financial instrument) you may not want the history of the lender parties to be kept on ledger. By anonymising the parties involved during the transaction, you can keep this information hidden.
- In the
ObligationBaseFlow
, in the internal classSignxFlowNoChecking
, add verification for the signed transaction. - Add a time-window for the period of time that an obligation can be traded
- Add a sanction list for the entites that can be transferred the obligation(see reference-states)
negotiation-cordapp (Kotlin)
This CorDapp shows how multi-party negotiation is handled on the Corda ledger, in the absence of an API for user interaction.
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 aTradeState
with identical attributes - Modifying the proposal, consuming the existing
ProposalState
and replacing it with a newProposalState
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.
- Accessing
FlowSession.counterParty
to control who initiates a flow. - Separating a business use case into multiple flow.
- Throwing FlowExceptions to manually abort flows.
- Performing business logic on a received state before finalising
- It's not always going to be the case that a state received from a flow can be immediately approved. For example, with a real estate registration, there may be a verification process that cant be automated and has to occur off ledger first (e.g a certificate of ownership in an attachment may need to be checked by a human entity). You can use this demostrated technique to divide this flow up where necessary to allow for the off-ledger components.
- Negotiating terms of a contract
- It may be the case that two interacting bodies have two different expectations of the information given in a state. The process of modifying the state and proposing alternatives may be automated (e.g the alternate flows are automtically triggered).
- Create a negotiation bot (a buyer and a seller) that are negotiating an art sale. The buyer has an upper limit on the money they will accept for the trade and the seller has a lower limit on the money they will accept. They are trying to minimise/maximise the agreed upon price respectively. Create a modifyable state that alters these proposals until an agreement is reached.
implicit-cordapp-upgrades (Kotlin)
This CorDapp shows how to carry out implicit upgrades of a CorDapp, by writing flows and contracts in a backwards compatible manner and taking advantage of Signature Constraints.
Implicit upgrades to the contract involve adding the new versions of a CorDapp to the whitelist (list of accepted CordApps on a network) and then using the version numbers to delegate to the correct flow handler for that version of an app. This allows a node to 'lazy upgrade' (upgrade only when they want to interact with a node that requires them to) and to continue interacting with other nodes running older versions of that app.
- Versioning flows via annotations
- Use versioning to delegate flow handlers
- Issue upgraded contracts to your test nodes via a .sh script
- When you don't need an atomic upgrade, but you want to change features of a contract
- You've issued an IOU that has an inefficient verification process that's slowing down the speed of transactions. Nodes are free to use the older version because the integrity of the agreement isn't compromised, but some nodes may choose to use the new version to speed up the operation of the dAPP.
See the following links for more in-depth description of scenarios suited to Implicit Contract Upgrades
Contract Upgrades and Constraints in V3
- Take an old application that you've built (or take the cordapp-example code) and create a second version of the contract with a new verification method. Create a flow delegation to handle the multiple versions.
Also see Explicit Cordapp Upgrades
attachment-demo (Kotlin)
This demo brings up three nodes, and sends a transaction containing an attachment from one to the other.
- Establishing rpc connection through CordaRPCClient and interacting with nodes through CordaRPCOps
- Hashing a file to SecureHash.SHA256
- Uploading attachment and verifying storage on node through hash
- Downloading attachments from a node's corresponding Web endpoint.
Attachments are useful for:
- Inclusion of legal prose or metadata
- you have a corresponding invoice with a transaction
- you have a legal off-ledger contract backing the on-ledger representation
- you want to store additional data such as URLs, files, etc.; related to the transaction
- One method of implementing oracles (suitable for large, static, and low value data)
- try adding multiple attachments
- use
AttachmentQueryCriteria
to filter attachments and run complex queries with boolean operators - go beyond a "two party trade flow" to send attachments to multiple nodes
See the official docs from more information about attachments
This demo brings up three nodes: a notary, a node acting as the Bank of Corda that accepts requests for issuance of some asset and a node acting as Big Corporation which requests issuance of an asset (cash in this example).
Upon receipt of a request the Bank of Corda node self-issues the asset and then transfers ownership to the requester after successful notarisation and recording of the issue transaction on the ledger.
.. note:: The Bank of Corda is somewhat like a "Bitcoin faucet" that dispenses free bitcoins to developers for testing and experimentation purposes.
- Using
WebServerPluginRegistry
to create API endpoints for interacting with Corda nodes via RPC - Interaction with nodes via
CordaRPCOps
- Blocking to wait for future from client-side flow response
- Handling errors such as node disconnect through exceptions
The concept of a 'token faucet' is useful for any on-demand issuance:
- You want to issue some none limited asset to users while tracking consumption
- NGO could issue food rations to track demand overtime and facilitate supply and logistics
- A Sports team could issue consumable supplies such as hockey tape, sports drinks, or pain relief cream.
- You want to create flexible value issuance based on user requests
- Marketplace that wants to control liquidity by opening temporary faucets for users to request tokens
- Adding a time-window to requests in order to control issuance
- Create a user-request cap so that users are cut-off after a certain value of issuance
- Switch the
Currency
being distributed in the sample with Corda's new TokenSDK
For more information and additional overview about establishing RPCConnections see Interacting with a Node
trader-demo (Kotlin)
This CorDapp demonstrates the manners by which you can configure a responder flow.
The CorDapp has five nodes; Bank A, Bank B, Bank of Corda, a NonLogging Bank, and a notary bank. Four of the five banks will print transaction information because that is what is defined in the LoggingBuyerFlow
(which subclasses, and therefore takes priority over, BuyerFlow
).
The NonLogging Bank however will not print out this transaction information because it has been configured in the deployNodes
task to explicitly user BuyerFlow
.
- Use of subclassing to override a flow responder
- Use of explicit configuration to override a flow responder.
- Subclassing a flow
- Extending a third party application
- You may be using a CorDapp that's been created by another party that you wish to add features to. Instead of recreating the app from scratch, you could extend the features of the app by subclassing the flows that need to change and adding new functionality.
- Modifying a generic flow to suit a specific business case
- You can add features necessary for a specific business case to a pre-existing flow.
- Borrowing features from a flow
- If you are creating a new flow that is very similar to one already in use in your app, it might be worth considering simply extending the behaviour.
- Extending a third party application
- Explicitly configuring a different responder
- Modifying a third party application
- A third party may have provided a CorDapp but you need to completely override some of its elements to suit your business needs
- Redefining a generic flow to suit a specific business case
- It may be the case that a parent flow shares very few, or no, features with the flow necessary for a particular business case. In this instance, you don't want to subclass the original flow but instead create an entirely new one.
- Modifying a third party application
- Manage many nodes running the sample application with different responses.
- Overriding flows instead of creating separate CorDapps can be a simple way of handling the business case where nodes need to run variants on the parent flow.
- Use different means (subclassing and explicit configuration) to override the
SellerFlow
and change the behaviour of the initiating flow for different nodes.
- To read more about ovveriding flows, click here.
- WARNING: Pay careful attention to the annotations of the subclassing flows. The responders require
@InitatedBy
but initiators that subclasss should not have the@Initiating
annotation. - WARNING: The more overriding flows you have, the more complex it will be to ensure that the sequence of steps in the initiators and the responders is compatible. If your CorDapp is growing complex, consider whether you should be using a new CorDapp with different functionality.
simm-valuation-demo (Kotlin, Java)
This CorDapp gives a demonstration of how third party libraries can be used by a Corda node.
The CorDapp uses OpenGamma's proprietary model to showcase the SIMM process and integrate it within the app.
NOTE Due to the proprietary nature of this service, the actual sample is taking stub data (faked data) and using that instead of the opengamma analytics engine. The format of the data is identical.
- How to integrate a third party library with a Corda node
- Use of stub data for testing
- If you need to use processes external to your Corda node
- Not all use cases require simple processing. It may be necessary to encapsulate some processing into a library and then to integrate this library with your Corda node.
- Accessing third party libraries
- Most business logic is spread across a number of providers. Using this as an example, you can integrate these services with your Corda node.
- If you have a license from OpenGamma, you can swap out the stub data for the analytics engine (which we will be happy to demonstrate)
WARNING The analytics engine has been replaced with stub data in this demo. Results obtained by this sample should not be used as a source of information.
notary-demo (Kotlin)
This CorDapp demonstrates how to use a single-node notary vs a distributed notary, and also gives examples of the potential pluggable consensus algorithms you can use for that distributed notary.
The CorDapp shows a party getting transactions notarised by either a single-node or a distributed notary service (using either the RAFT consensus algorithm or the BFT-smart consensus algorithm).
- Create a custom notary in
MyCustomNotaryService
- How to edit the configuration files to test with different notaries
- A notary is required for uniqueness consensus
- If you were using tokens to represent an asset like a house in a CorDapp that allows you to trade real estate, without a notary guaranteeing the uniqeness of spend, a house owner would be able to sell their house many times over (double spending).
- A multi-node notary can be used to provide a highly available notary
- In a critical business case where the network needs to provide assurance of availability, a multi-node notary can be used to provide fault-tolerance. NOTE: Multi-node notaries are
- Implement an alternative notary service in one of your CorDapps (or in one of the other sample apps)
- Extend the custom notary to include more features.
- Presently, you can only create custom notaries that are single-node.
- Read more about notaries here
- WARNING: Customising a notary service is still an experimental feature and not recommended for most use-cases. The APIs for writing a custom notary may change in the future.
network-verifier (Kotlin)
This CorDapp shows a method of whitelisting participants to add to a flow
- Filtering through a list of all nodes registered to the network
- Filtering using the X500 certificate
- Adding users required as participants to a flow
- There may be situations whereby an entity on the network needs to sign on a transaction. You can use this sample as a way of automatically adding that entity as a required participant using their X500 name.
- Adding users required as observers to a flow
- Similarly to above, you may not need an entity on the network to act as a required signer, but you may require they be made aware of a transaction. You can use this sample but alter it so that the entity is added as an observer rather than a participant.
- Deploy four nodes on the network and create a transaction that requires a third node to act as a participant, and then as an observer. You can query what transactions were made visible to what nodes through the shell
- INCOMPLETE SAMPLE
This CorDapp demonstrates a sophisticated and real-world use-case of Corda involving components like an Oracle and a web API.
The app launches three nodes; Bank A, Bank B and a node that simultaneously runs a notary, a network map and an interest rates oracle. The two banks agree on an interest rate swap, and then do regular fixings of the deal as the time on a simulated clock passes.
- An Oracle for supplying a consistent time across nodes
- A web API for interfacing with the information
- RPC communication between nodes
- The use of utils for sophisticated processing
- If you need time based execution between nodes
- In networking there is no such thing as a 'true' time. Time differences, hardware differences, communication delays, and malicious manipulation means that every node in a communication could be running according to a different time. If consistency is required, time keeping can be delegated to a trusted time keeping authority (an oracle). An example use case would be in the management of a blind auction. Sealed envelopes should not be opened before the end of the auction, and this requires specifying when that 'time' has been reached and that it being reached is indisputable.
- The oracle currently broadcasts the time according to its own time zone. Add functionality that allows the oracle to convert the clock to the same time zone as the index/source.
- This sample is still under development and isn't without bugs (these are described in the comments of the code).
- A more straight forward example of an oracle is available here
This sample shows a simple example of how to use per-corDapp configuration.
- A configuration file
- Gradle build file to show how to install your CorDapp configuration
- A flow that prints the current CorDapp configuration
- Maintaining different configurations for separate environments
- Often nodes will require different configurations when they are deployed versus when the CordApp is in development. Maintaining the configuration files separately from the build file makes it easier to interchange these configurations as necessary.
- Maintain the same configuration across developers
- You may be working on a number of CorDapps at any given time, all installed on the same node. It may be that these corDapps require different configurations for testing purposes. Maintaining these configurations across the various CordApps makes it easier to work on multiple projects.
- Maintain separate configurations between developers
- If you have multiple developers working on the same project, it may be that a configuration for one developer wont work for another (for example, there could be clashes in port usage). Allowing each developer to share the buid file for necessary dependencies, but allowing them to set the node configurations separetely, takes care of this issue.
- A list of the fields you can configure is given here - experiment with the changes you can make.
- Take an existing application you've worked on and extract out the node configuration into a config.conf file.
- Add error handling (throw exception when key not available) to the
GetStringConfigFlow
.
- See more about per-cordapp configuration in the docs