Corda RPC
Purpose¶
A helper layer over the R3 Corda RPC Blockchain API: Corda
Platform 6 supports Corda 4. It comes bundled with the latest java archives required to integrate and interact with Corda.
The latest developer guide can be found here: https://docs.corda.net/docs/corda-os/4.4.html
The Corda RCP API is provided as a native java API and as such is available for use directly from any Platform 6 script.
Note
Using the Corda RPC API will require your scripts import all the net.corda packages used. A great way to hide this and de-clutter your scripts is to use the @import to insert a commonly used set of imports into each of your scripts.
Current API documentation can be found here: https://docs.corda.net/docs/corda-os/4.4/tutorial-clientrpc-api.html
Methods¶
Binding name: p6.cordarpc
Method: CordaContext build(final String hostPort, final String username, final String password)
Build an instance of a CordaContext object using the supplied node connection parameters.
A CordaContext has the following fields for your convenience:
CordaRPCClient client
CordaRPCConnection connection
CordaRPCOps proxy
The CordaContext implements Closeable so making the closure of the connection more manageable.
The supplied hostPort
parameter is parsed by the net.corda.core.utilities.NetworkHostAndPort
class to build a usable node address.
Warning
For simplicity I have shown username and password values in the following example scripts. It is not advisable to hard code user credentials in scripts. A better way would be to use values from our configuration service or other external injection mechanism.
Examples¶
Example One¶
A simple one line script that will connect to a node, retrieve and log the node diagnostic information and close the connection cleanly
p6.cordarpc.build('localhost:10005', 'user1', 'test').withCloseable { ctx -> p6.log.info(ctx.proxy.nodeDiagnosticInfo().toString()) }
Example Two¶
A more basic use of the CordaContext to list the nodes registered flows and finally close the context
def cordaCtx = p6.cordarpc.build('localhost:10005', 'user1', 'test')
def lstFlows = cordaCtx.proxy.registeredFlows()
p6.log.info('Registered Flows: ' + lstFlows)
cordaCtx.close()
Example Three¶
This example uses the nodes and cordapps deployed using the Corda Samples project: https://github.com/corda/samples
After building https://github.com/corda/samples/tree/release-V4/cordapp-example I started four nodes using the runnodes
script.
Note
In order to reference the com.example.flow package in your scripts it is essential that a copy of the Example cordapp
JAR files are copied into the folder ${P6_DATA}/lib so they are added to the Platform 6 classpath
cordapp-example-workflows-0.1.jar
and cordapp-example-contracts-0.1.jar
in this tutorial.
Please refer to the Bundled Resources Service This is the recommended way to distribute JAR files with your applications.
This example will connect to node PartyA
and initiate an example flow establishing a IOUState with value 99
with PartyB
When the flow is complete the script logs the transaction id associated with this flow initiation:
INFO [GROOVYSCRIPT: io.platform6.scripts.p6core.corda.Main] ExampleFlow initiation complete: SignedTransaction(id=F6F990A117DFAA07D5EDAD22F78AE527888BC31A4D638C293E91EAEA083E7507)
import com.example.flow.ExampleFlow
import net.corda.core.identity.Party
import net.corda.core.identity.CordaX500Name
p6.cordarpc.build('localhost:10005', 'user1', 'test').withCloseable { ctx ->
def partyBName = new CordaX500Name('PartyB', 'New York', 'US')
def partyB = ctx.proxy.wellKnownPartyFromX500Name(partyBName)
def flowHandle = ctx.proxy.startFlowDynamic(ExampleFlow.Initiator.class, 99, partyB)
p6.log.info('ExampleFlow initiation complete: ' + flowHandle.getReturnValue().get())
}
Warning
The following text is taken from the Corda API documentation but is worth repeating here:
“With regards to the start flow RPCs, there is an extra layer of security whereby the flow to be executed has to be annotated with @StartableByRPC. Flows without this annotation cannot execute using RPC.”
Without the annotation the startFlowDynamic() call will fail!