我如何限制一组节点发起流
How can i restrict a set of nodes from initiating a flow
如果我有两种参与方,例如:BankA、BankB、InsuranceA、InsuranceB。我可以限制交易仅由保险方发起吗?
所以我不希望 BankA 能够启动特定流程。
一种方法是为具有适当权限的银行和保险公司设置不同的 RPC 客户端。在权限中,您可以定义哪个用户可以启动什么流程。可以在 build.gradle 文件的节点配置中设置权限。
有几种方法可以让您阻止节点启动某些流程:
您只能在保险公司节点上安装定义保险公司特定流程的 CorDapp,而不能在银行节点上安装
- 您甚至可以只提供包含保险公司流向保险公司节点的 CorDapp JAR
正如 Kid101 所说,您可以将节点的 RPC 权限限制为仅允许保险公司节点的 RPC 用户启动相关流程。例如:
rpcUsers=[
{
username=exampleUser
password=examplePass
permissions=[
"StartFlow.net.corda.flows.ExampleFlow1",
"StartFlow.net.corda.flows.ExampleFlow2"
]
}
...
]
这两种方法依赖于节点之间的信任。没有什么可以阻止其中一个银行节点获取包含保险公司流程的 CorDapp 并授予自己启动它的 RPC 权限。
如果节点不信任(您应该假设它们在 DLT 世界中),您应该改为采用以下方法之一:
您可以在响应程序流程中执行检查。例如,如果您有流对 IssueInsurancePolicyFlow
/ IssueInsurancePolicyFlowResponder
,您可以在 IssueInsurancePolicyFlowResponder
中添加检查以确保 IssueInsurancePolicyFlow
的发起者是保险公司节点。
在伪代码中:
if (counterpartySession.counterparty !in insurerNodeList) {
throw IllegalStateException("Flow must be run by an insurer node.")
}
在这里,由您决定如何检索有效保险公司节点列表。例如,它可以从响应节点的数据库中读取。
请注意,此方法仅在发起人(除了公证人)之外还有所需的签名人时才有效。否则,无法强制不诚实的银行节点向诚实的交易对手发送消息以调用响应程序流程(以及包含的支票)。
另请注意,此检查应放在响应程序流程中,因为发起程序无法修改响应程序端的代码运行。如果支票放在发起者流程中,银行节点可以创建自己的发起流程并离开这个支票
您可以在合同本身内进行检查。例如:
override fun verify(tx: LedgerTransaction) {
...
val dealStateOutput = tx.outputsOfType<DealState>().single()
if (dealStateOutput.insurer !in approvedInsurers)
throw IllegalArgumentException("Unapproved insurer.")
...
}
这种方法的难点在于将批准的保险公司名单纳入合同。您可以对其进行硬编码,但它可能会随着时间的推移而发生变化,从而迫使您升级合约。一种替代方法是包含一个 oracle 签名的命令,指示给定的保险公司已获批准,并检查该保险公司是否与输出状态上的保险公司相匹配。
如果我有两种参与方,例如:BankA、BankB、InsuranceA、InsuranceB。我可以限制交易仅由保险方发起吗?
所以我不希望 BankA 能够启动特定流程。
一种方法是为具有适当权限的银行和保险公司设置不同的 RPC 客户端。在权限中,您可以定义哪个用户可以启动什么流程。可以在 build.gradle 文件的节点配置中设置权限。
有几种方法可以让您阻止节点启动某些流程:
您只能在保险公司节点上安装定义保险公司特定流程的 CorDapp,而不能在银行节点上安装
- 您甚至可以只提供包含保险公司流向保险公司节点的 CorDapp JAR
正如 Kid101 所说,您可以将节点的 RPC 权限限制为仅允许保险公司节点的 RPC 用户启动相关流程。例如:
rpcUsers=[ { username=exampleUser password=examplePass permissions=[ "StartFlow.net.corda.flows.ExampleFlow1", "StartFlow.net.corda.flows.ExampleFlow2" ] } ... ]
这两种方法依赖于节点之间的信任。没有什么可以阻止其中一个银行节点获取包含保险公司流程的 CorDapp 并授予自己启动它的 RPC 权限。
如果节点不信任(您应该假设它们在 DLT 世界中),您应该改为采用以下方法之一:
您可以在响应程序流程中执行检查。例如,如果您有流对
IssueInsurancePolicyFlow
/IssueInsurancePolicyFlowResponder
,您可以在IssueInsurancePolicyFlowResponder
中添加检查以确保IssueInsurancePolicyFlow
的发起者是保险公司节点。在伪代码中:
if (counterpartySession.counterparty !in insurerNodeList) { throw IllegalStateException("Flow must be run by an insurer node.") }
在这里,由您决定如何检索有效保险公司节点列表。例如,它可以从响应节点的数据库中读取。
请注意,此方法仅在发起人(除了公证人)之外还有所需的签名人时才有效。否则,无法强制不诚实的银行节点向诚实的交易对手发送消息以调用响应程序流程(以及包含的支票)。
另请注意,此检查应放在响应程序流程中,因为发起程序无法修改响应程序端的代码运行。如果支票放在发起者流程中,银行节点可以创建自己的发起流程并离开这个支票
您可以在合同本身内进行检查。例如:
override fun verify(tx: LedgerTransaction) { ... val dealStateOutput = tx.outputsOfType<DealState>().single() if (dealStateOutput.insurer !in approvedInsurers) throw IllegalArgumentException("Unapproved insurer.") ... }
这种方法的难点在于将批准的保险公司名单纳入合同。您可以对其进行硬编码,但它可能会随着时间的推移而发生变化,从而迫使您升级合约。一种替代方法是包含一个 oracle 签名的命令,指示给定的保险公司已获批准,并检查该保险公司是否与输出状态上的保险公司相匹配。