Corda

Kick-start your application development on Corda.

Get started with Corda in 3 easy steps

CorDapps (applications built on Corda) define the flows, agreements, and updates that Corda node owners can use. Think of them as the lines which connect all the dots on Corda. Run your CorDapp in Java or Kotlin in minutes, learn best practices, and find samples ranging from simple transactions to advanced enterprise-level auction markets powered by blockchain.

Install the required software for CorDapp development: Java 8 JDK, IntelliJ IDEA, Git, and Gradle.

We have a repository that contains multiple sample apps to help you get started. Run the following command to clone the CorDapp Samples repository:


git clone http://github.com/corda/samples-java

git clone http://github.com/corda/samples-kotlin

Read through the Corda Key Concepts to understand how Corda works.

Corda SDKs
Corda SDKs

Create your CorDapp easily with SDKs for all operating systems.

Explore SDKs

Plugins

Plugins

Editor plugins to expertise developer’s experience working with Corda.

Get plugins

CorDapp template

Get your projects started fast – choose and edit customizable CorDapp templates.

View available templates

CorDapps
Open source CorDapps

Use existing CorDapps for key functions such as settling payments and exploring nodes.

Access CorDapps

Explore Corda

R3 offers developers the infrastructure and ease to implement custom and secure blockchain applications.

Get Corda

Represent your assets with Corda states

States let you transact digitally with nearly any asset by transforming it into an object on the ledger.

Here is an example of how you would represent a CarState in Corda:

        
@BelongsToContract(CarContract.class)
public class CarState implements ContractState {
    private Party owningBank;
    private Party holdingDealer;
    private Party manufacturer;
    private String vin;
    private String licensePlateNumber;
    private String make;
    private String model;
    private String dealershipLocation;
    private final List participants = new ArrayList();

    // our state takes all these parameters as input to the constructor
    public CarState(Party owningBank, Party holdingDealer, Party manufacturer . . .) {
        this.owningBank = owningBank;
        this.holdingDealer = holdingDealer;
        this.manufacturer = manufacturer;
        // etc.

        this.participants.add(owningBank);
        this.participants.add(holdingDealer);
        this.participants.add(manufacturer);
    }
}
        
    
        
@BelongsToContract(CarContract::class)
class CarState(private val owningBank: Party,
               private val holdingDealer: Party,
               private val manufacturer: Party,
               private val vin: String,
               private val licensePlateNumber: String,
               private val make: String,
               private val model: String,
               private val dealershipLocation: String) : ContractState {
    
    private override val participants: MutableList = ArrayList()

    // our state takes all these parameters as input to the constructor
    init {
        participants.add(owningBank)
        participants.add(holdingDealer)
        participants.add(manufacturer)
    }
}
        
    
        
public class CarContract implements Contract {
    public static String ID = "Sample.CarContract";

    @Override
    public void verify(LedgerTransaction tx) throws IllegalArgumentException {

        CommandWithParties command = requireSingleCommand(tx.getCommands(), CarContract.Commands.class);

        List inputs = tx.getInputStates();
        List outputs = tx.getOutputStates();

        if (command.getValue() instanceof CarContract.Commands.Issue) {
            requireThat(req -> {
                req.using("Transaction must have no input states.", inputs.isEmpty());
                req.using("Transaction must have exactly one output.", outputs.size() == 1);
                req.using("Output must be a CarState.", outputs.get(0) instanceof CarState);
                
                // retrieve the CarState for the transaction 
                CarState output = (CarState) outputs.get(0);

                req.using("The license plate number must be seven characters long.", outputState.getLicensePlateNumber().length() == 7);
                req.using("Manufacturer must be required singer.", command.getSigners().contains(output.getManufacturer().getOwningKey()));
                return null;
            });
        } else {
            throw new IllegalArgumentException("Unrecognized command");
        }
    }
        
    
        
class CarContract : Contract {
    @Throws(IllegalArgumentException::class)
    override fun verify(tx: LedgerTransaction) {
        val (signers, _, value) = tx.commands.requireSingleCommand(Commands::class.java)
        val inputs = tx.inputStates
        val outputs = tx.outputStates
        if (value is Commands.Issue) {
            requireThat { 
                "Transaction must have no input states.".using(inputs.isEmpty())
                "Transaction must have exactly one output.".using(outputs.size == 1)
                "Output must be a CarState.".using(outputs[0] is CarState)

                // retrieve the CarState for the transaction
                val outputState = outputs[0] as CarState
                "The license plate number must be seven characters long.".using(outputState.getLicensePlateNumber().length() === 7)
                "Manufacturer must be required singer.".using(signers.contains(outputState.getManufacturer().getOwningKey()))
            }
        } else {
            throw IllegalArgumentException("Unrecognized command")
        }
    }

    interface Commands : CommandData {
        class Issue : Commands
    }

    companion object {
        var ID = "Sample.CarContract"
    }
}
        
    

Verify transactions with Corda Contracts

Contracts let you determine the validity of any transaction. They represent agreements between parties about what transactions the parties can perform with a given asset. You can attach real legal documents to transactions on Corda.

Example of a CarStateContract to the left.

Get it done with Corda flows

Flows are what make CorDapps work. When a Flow is triggered, it enables parties to coordinate actions without a centralized controller. This means CorDapps built for issuing loans, reserving concert tickets, or checking for newsletter subscriptions can do so reliably. Flows let Corda nodes interact with any external application via RPC call.

Here’s an example of how you can code CreateCarStateFlow:

        
// constructor for providing the information to the corda flow to then create the car 
public CarIssueFlowInitiator(Party owningBank, Party holdingDealer, Party manufacturer, . . .) {
  this.owningBank = owningBank; 
  this.holdingDealer = holdingDealer;
  this.manufacturer = manufacturer;
  // etc.   
}

// . . . 

@Suspendable
@Override
public SignedTransaction call() throws FlowException {
    // find a notary for the transaction
    Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
    // get a reference to the manufacturer node, the only node that can issue new cars
    Party manufacturer = getOurIdentity();
    // create our car state
    CarState carState = new CarState(owningBank, holdingDealer, manufacturer);
    // build the transaction
    TransactionBuilder transactionBuilder = new TransactionBuilder(notary);
    // we're manufacturing a new car
    CommandData commandData = new CarContract.Commands.Issue();
    // add the command and add the expected output of the transaction
    transactionBuilder.addCommand(commandData, manufacturer.getOwningKey(), holdingDealer.getOwningKey());
    transactionBuilder.addOutputState(carState, CarContract.ID);
    // verify the transaction
    transactionBuilder.verify(getServiceHub());
    // initiate the flow and transaction
    FlowSession session = initiateFlow(holdingDealer);
    // use corda to collect signatures from all the required signers
    SignedTransaction signedTransaction = getServiceHub().signInitialTransaction(transactionBuilder);
    SignedTransaction fullySignedTransaction = subFlow(new CollectSignaturesFlow(signedTransaction, singletonList(session)));
    return subFlow(new FinalityFlow(fullySignedTransaction, singletonList(session)));
}
        
    
        
class CarIssueFlow {
    @InitiatingFlow
    @StartableByRPC
    class Initiator(var owningBank: Party, var holdingDealer: Party) : FlowLogic() {
        @Suspendable
        @Throws(FlowException::class)
        override fun call(): SignedTransaction {
            // find a notary for the transaction
            val notary = serviceHub.networkMapCache.notaryIdentities[0]
            // get a reference to the manufacturer node, the only node that can issue new cars
            val manufacturer = ourIdentity
            // create our car state
            val carState = CarState(owningBank, holdingDealer, manufacturer)
            // build the transaction
            val transactionBuilder = TransactionBuilder(notary)
            // we're manufacturing a new car
            val commandData: CommandData = CarContract.Commands.Issue()
            // add the command and add the expected output of the transaction
            transactionBuilder.addCommand(commandData, manufacturer.owningKey, holdingDealer.owningKey)
            transactionBuilder.addOutputState(carState, CarContract.ID)
            // verify the transaction
            transactionBuilder.verify(serviceHub)
            // initiate the flow and transaction
            val session = initiateFlow(holdingDealer)
            // use corda to collect signatures from all the required signers
            val signedTransaction = serviceHub.signInitialTransaction(transactionBuilder)
            val fullySignedTransaction = subFlow(CollectSignaturesFlow(signedTransaction, listOf(session)))
            return subFlow(FinalityFlow(fullySignedTransaction, listOf(session)))
        }
    }
}
        
    

Feature comparison

Corda and Corda Enterprise have the same core elements. Corda Enterprise optimizes for business with additional connectivity features.
Here’s how they compare:

Corda functionality
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

Corda ledger

done done

Flow framework

done done

Immutable states

done done

Vault

done done

Smart contracts

done done

Atormic transactions

(with input, output, and reference states)
done done

Multiple accounts

done done

Supported development languages

Java, Kotlin

Java, Kotlin

Standard Corda APIs

done done

Compatible with any Corda network

(including the Corda Network)
done done
Node
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

Single node

done done

Multiple nodes for high availability/disaster recovery

close done
Connectivity
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

In-process Artemis MQ

done done

External Artemis MQ

close done

Corda firewall

close done

Multi-node use of a shared external Artemis MQ and a shared Corda firewall

close done
Key storage
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

Java keystore file

done done

HSM support

close done
Vault databases
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

H2 (development use only)

done done

Postgres

done done

SQL server

Experimental only

done

Oracle

close done
Support
Feature Community Edition
(open source)
Enterprise Edition
(licensed)

Support

Eligible for additional Support Services

24/7 Support included in license

Corda developer highlights

Latest Blog Posts

Corda • June 27, 2023 • By: Divya Taori

Why Kafka Was Selected for Next-Gen Corda

Read blog post

Corda • June 14, 2023 • By: Divya Taori

Corda 5 Beta 4 is here!

Read blog post

Upcoming event

There are no upcoming events at this time. Check back soon.

Featured video