Writing a custom notary service (experimental)
This tutorial covers how to write a custom notary service.
Defining a class for the custom notary service
The first step in creating a custom notary service is to create a service class in your CorDapp that extends the NotaryService
abstract class.
This will ensure that it is recognised as a notary service.
The custom notary service class should provide a constructor with two parameters of types ServiceHubInternal
and PublicKey
.
Note that ServiceHubInternal
does not provide any API stability guarantees.
class MyCustomValidatingNotaryService(
override val services: ServiceHubInternal,
override val notaryIdentityKey: PublicKey)
: SinglePartyNotaryService() {
override val uniquenessProvider = PersistentUniquenessProvider(
services.clock,
services.database,
services.cacheFactory,
::signTransaction)
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> = MyValidatingNotaryFlow(otherPartySession, this)
override fun start() {}
override fun stop() {}
}
Writing a flow for the custom notary service
The next step is to write a flow for the custom notary service. You are free to copy and modify the existing built-in flows such
as ValidatingNotaryFlow
, NonValidatingNotaryFlow
, or implement your own from scratch (following the
NotaryFlow.Service
template). Below is an example of a custom flow for a validating notary service:
class MyValidatingNotaryFlow(otherSide: FlowSession, service: MyCustomValidatingNotaryService) : ValidatingNotaryFlow(otherSide, service) {
override fun verifyTransaction(requestPayload: NotarisationPayload) {
try {
val stx = requestPayload.signedTransaction
resolveAndContractVerify(stx)
verifySignatures(stx)
customVerify(stx)
} catch (e: Exception) {
throw NotaryInternalException(NotaryError.TransactionInvalid(e))
}
}
@Suspendable
private fun resolveAndContractVerify(stx: SignedTransaction) {
subFlow(ResolveTransactionsFlow(stx, otherSideSession))
stx.verify(serviceHub, false)
}
private fun verifySignatures(stx: SignedTransaction) {
val transactionWithSignatures = stx.resolveTransactionWithSignatures(serviceHub)
checkSignatures(transactionWithSignatures)
}
private fun checkSignatures(tx: TransactionWithSignatures) {
tx.verifySignaturesExcept(service.notaryIdentityKey)
}
private fun customVerify(stx: SignedTransaction) {
// Add custom verification logic
}
}
Updating the node configuration
To enable the custom notary service, add the following to the node configuration:
notary : {
validating : true # Set to false if your service is non-validating
className : "net.corda.notarydemo.MyCustomValidatingNotaryService" # The fully qualified name of your service class
}
Testing your custom notary service
To create a flow test that uses your custom notary service, you can set the class name of the custom notary service as follows in your flow test:
mockNet = MockNetwork(MockNetworkParameters(
cordappsForAllNodes = listOf(DUMMY_CONTRACTS_CORDAPP, enclosedCordapp()),
notarySpecs = listOf(MockNetworkNotarySpec(
name = CordaX500Name("Custom Notary", "Amsterdam", "NL"),
className = "net.corda.testing.node.CustomNotaryTest\$CustomNotaryService",
validating = false // Can also be validating if preferred.
))
))
After this, your custom notary will be the default notary on the mock network, and can be used in the same way as described in Write integration tests.
Was this page helpful?
Thanks for your feedback!
Chat with us
Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.
Propose documentation improvements directly
Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.
We're sorry this page wasn't helpful. Let us know how we can make it better!
Chat with us
Chat with us on our #docs channel on slack. You can also join a lot of other slack channels there and have access to 1-on-1 communication with members of the R3 team and the online community.
Create an issue
Create a new GitHub issue in this repository - submit technical feedback, draw attention to a potential documentation bug, or share ideas for improvement and general feedback.
Propose documentation improvements directly
Help us to improve the docs by contributing directly. It's simple - just fork this repository and raise a PR of your own - R3's Technical Writers will review it and apply the relevant suggestions.