首页 > 解决方案 > 什么决定了登录 Corda 所需的密钥?

问题描述

我最近在我的流量测试中遇到了一个错误,上面写着:

java.lang.IllegalArgumentException: A signature was requested for a key that isn't part of the required signing keys for transaction 

当我查看我的代码时,我无法确定是哪个键导致了问题。

输出状态上有一个participants列表。

该命令采用键列表。

创建了一个带有密钥的本地事务:

val locallySignedTx = serviceHub.signInitialTransaction(txBuilder, keysToSignWith)

我还使用在每个帐户上都有密钥的帐户 SDK。

还需要对方的CollectSignatureFlow密钥。

其中哪一部分决定了签名所需的密钥?

标签: corda

解决方案


在下面的代码块中,第一个参数new Command()是命令的类型,Create()第二个参数是所需签名者的列表(在本例中为贷方和借方)。
所以回答你的问题:Command构造函数中的第二个参数定义了所需签名者的列表。

final Command<IOUContract.Commands.Create> txCommand = 
new Command<>(new IOUContract.Commands.Create(), 
ImmutableList.of(iouState.getLender().getOwningKey(), iouState.getBorrower().getOwningKey()));

请注意,您所在州的合同可能有一个验证规则,该规则确定谁应该是所需的签名者,所以当您定义上面的命令时;如果您请求不应该存在的签名者,您的合同将无法通过验证:

require.using("All of the participants must be signers.", command.getSigners()
.containsAll(out.getParticipants().stream()
.map(AbstractParty::getOwningKey).collect(Collectors.toList())));

现在让我们回到你的问题,我认为发生的事情是你从一个不属于你的命令所需签名者的一方收集了一个签名,我搜索了 Corda 的代码,发现你的错误消息来自CollectSignaturesFlow.checkMySignaturesRequired()函数:

private fun checkMySignaturesRequired(stx: SignedTransaction, signingKeys: Iterable<PublicKey>) {
    require(signingKeys.all { it in stx.tx.requiredSigningKeys }) {
        "A signature was requested for a key that isn't part of 
the required signing keys for transaction ${stx.id}"
    }
}

您提到您正在使用 Accounts 库,所以我的猜测是在您的流程中,主机节点(即托管您的帐户的节点)必须代表他们签名,所以当它签名时应该使用这些帐户的密钥,像这样:

getServiceHub().signInitialTransaction(txBuilder, Arrays.asList(pkOfAcc1, pkOfAcc2, pkOfAcc3);

由于看不到您的完整代码,因此我试图尽我所能回答。


推荐阅读