答案 0 :(得分:0)
从Corda 3开始,实现自定义公证服务仍是一项实验功能。用于实现自定义公证服务的API将来可能会更改。此外,尚不完全支持自定义Raft或BFT公证人。如果要编写自己的Raft公证人,则必须实现自定义数据库连接器(或为公证人使用单独的数据库),并使用自定义配置文件。
实现自定义公证人的第一步是在CorDapp中创建一个公证人服务类(即一个用@CordaService
注释的公证服务类)。 Corda节点扫描这些服务类,并在启动时将其初始化。定制公证服务类应提供采用AppServiceHub
和PublicKey
的构造函数:
@CordaService
class MyCustomValidatingNotaryService(override val services: AppServiceHub, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() {
override val uniquenessProvider = PersistentUniquenessProvider()
override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic<Void?> = MyValidatingNotaryFlow(otherPartySession, this)
override fun start() {}
override fun stop() {}
}
下一步是编写公证服务流程。您可以自由地复制和修改现有的内置流程,例如ValidatingNotaryFlow
,NonValidatingNotaryFlow
,也可以从头开始实现自己的流程(遵循NotaryFlow.Service
模板)。以下是验证公证服务的自定义流程示例:
class MyValidatingNotaryFlow(otherSide: FlowSession, service: MyCustomValidatingNotaryService) : NotaryFlow.Service(otherSide, service) {
/**
* The received transaction is checked for contract-validity, for which the caller also has to to reveal the whole
* transaction dependency chain.
*/
@Suspendable
override fun receiveAndVerifyTx(): TransactionParts {
try {
val stx = receiveTransaction()
val notary = stx.notary
checkNotary(notary)
verifySignatures(stx)
resolveAndContractVerify(stx)
val timeWindow: TimeWindow? = if (stx.coreTransaction is WireTransaction) stx.tx.timeWindow else null
return TransactionParts(stx.id, stx.inputs, timeWindow, notary!!)
} catch (e: Exception) {
throw when (e) {
is TransactionVerificationException,
is SignatureException -> NotaryInternalException(NotaryError.TransactionInvalid(e))
else -> e
}
}
}
@Suspendable
private fun receiveTransaction(): SignedTransaction {
return otherSideSession.receive<NotarisationPayload>().unwrap {
val stx = it.signedTransaction
validateRequest(NotarisationRequest(stx.inputs, stx.id), it.requestSignature)
stx
}
}
@Suspendable
private fun resolveAndContractVerify(stx: SignedTransaction) {
subFlow(ResolveTransactionsFlow(stx, otherSideSession))
stx.verify(serviceHub, false)
customVerify(stx)
}
private fun verifySignatures(stx: SignedTransaction) {
val transactionWithSignatures = stx.resolveTransactionWithSignatures(serviceHub)
checkSignatures(transactionWithSignatures)
}
private fun checkSignatures(tx: TransactionWithSignatures) {
try {
tx.verifySignaturesExcept(service.notaryIdentityKey)
} catch (e: SignatureException) {
throw NotaryInternalException(NotaryError.TransactionInvalid(e))
}
}
private fun customVerify(stx: SignedTransaction) {
// Add custom verification logic
}
}
要启用该服务,请将以下内容添加到节点的配置中:
notary : {
validating : true # Set to false if your service is non-validating
custom : true
}