You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Corda合约代码(verify方法)中获取交易发起方信息?

How to Get the Transaction Initiator in Corda Contract's verify Method

Great question! In Corda, since contract verification runs on every participating node, you can't directly retrieve the "transaction initiator" implicitly—but you can explicitly pass this information via the transaction's commands, which is the standard pattern for implementing permission checks like "only the input state owner can perform this action" directly in the contract.

Here's a step-by-step implementation:

1. Define a Command that Carries the Initiator's Identity

First, create a command class within your contract that includes the initiator's AbstractParty as part of its data. This lets you explicitly pass who's initiating the transaction from the flow to the contract.

class MyContract : Contract {
    companion object {
        @JvmStatic
        val ID = "com.example.MyContract"
    }

    // Define contract commands with embedded initiator info
    interface Commands : CommandData {
        // This command includes the initiator's identity
        class Transfer(val initiator: AbstractParty) : Commands
    }

    override fun verify(tx: LedgerTransaction) {
        // Extract the single Transfer command from the transaction
        val transferCommand = tx.commands.requireSingleCommand<Commands.Transfer>()
        
        // Get the initiator from the command's data
        val transactionInitiator = transferCommand.value.initiator
        
        // Retrieve the input state we're checking permissions for
        val inputState = tx.inputsOfType<MyState>().single()
        
        // Perform the permission check using requireThat for clear error messages
        requireThat {
            "Only the owner of the input state can initiate this transfer" using 
                (inputState.owner == transactionInitiator)
            // Add any other contract validation rules here...
        }
    }
}

2. Pass the Initiator from the Flow to the Contract

In your flow, when building the transaction, you'll create the Transfer command with the initiator's identity (typically ourIdentity for the node running the flow) and ensure the initiator signs the command.

// Example flow code to build the transaction
val inputStateRef = // Reference to your input MyState
val outputState = // Your output MyState
val notary = serviceHub.networkMapCache.notaryIdentities.first()

// The initiator is the current node's identity
val initiator = ourIdentity

// Create the command with the initiator's info, and require their signature
val transferCommand = Command(
    MyContract.Commands.Transfer(initiator),
    listOf(initiator.owningKey)
)

// Build the transaction
val txBuilder = TransactionBuilder(notary)
    .addInputState(inputStateRef)
    .addOutputState(outputState, MyContract.ID)
    .addCommand(transferCommand)

// Proceed with signing, collecting other signatures, and finalizing the transaction...

Key Notes

  • Why use commands for this? Corda contracts don't have access to flow context or implicit "initiator" metadata—all data used in verification must be explicitly included in the transaction. Commands are the designed way to pass operational context (like who's initiating an action) to the contract.
  • Signer validation: You can also cross-check that the initiator is actually one of the command's signers (to prevent tampering). For example, add a rule like:
    "The initiator must sign the transaction" using 
        (transferCommand.signers.contains(initiator.owningKey))
    

内容的提问来源于stack exchange,提问作者ivolchenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:09:36