You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Corda中编写自定义事件?以token转账通知为例

Alright, let's walk through exactly how to implement custom events in Corda for sending token transfer notifications. I'll break this down into actionable steps with code snippets you can adapt for your use case.

1. Define Your Custom Event Class

First, you need a serializable event class to carry the notification details. Corda requires event objects to be serializable so they can be passed between nodes or persisted if needed.

import net.corda.core.serialization.CordaSerializable

@CordaSerializable
data class TokenTransferEvent(
    val accountId: String,
    val notificationMessage: String
)

This class holds the target account ID and the specific message ("Token is transferred" or "Token is received") we want to send.

2. Emit Events During Token Transfer Flow

Next, you'll trigger these events in your token transfer flow. Whether you're using the Corda Token SDK's built-in flows or a custom transfer flow, you'll emit events after the transfer is confirmed.

Local Account Transfer (Same Node)

If both accounts exist on the same node, you can emit events directly via the node's event service:

import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.services.eventEvents

@StartableByRPC
class LocalTokenTransferFlow(
    private val fromAccountId: String,
    private val toAccountId: String,
    private val tokenAmount: Long
) : FlowLogic<Unit>() {
    override fun call() {
        // Execute core token transfer logic (e.g., using Token SDK's MoveTokensFlow)
        // ... your transfer implementation here ...

        // Emit event for the sending account
        serviceHub.eventService.emit(
            TokenTransferEvent(fromAccountId, "Token is transferred")
        )

        // Emit event for the receiving account
        serviceHub.eventService.emit(
            TokenTransferEvent(toAccountId, "Token is received")
        )
    }
}

Cross-Node Account Transfer

If accounts are on different nodes, you need to pass the event to the receiving node via a flow session. Update your initiator flow to send the event details, then have the responder flow emit the event locally:

Initiator Flow

import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party

@StartableByRPC
class CrossNodeTokenTransferFlow(
    private val fromAccountId: String,
    private val toAccountId: String,
    private val tokenAmount: Long,
    private val receivingNode: Party
) : FlowLogic<Unit>() {
    override fun call() {
        // Initiate session with the receiving node
        val session = initiateFlow(receivingNode)

        // Execute core token transfer logic
        // ... your cross-node transfer implementation here ...

        // Emit local event for sending account
        serviceHub.eventService.emit(
            TokenTransferEvent(fromAccountId, "Token is transferred")
        )

        // Send event details to receiving node
        session.send(TokenTransferEvent(toAccountId, "Token is received"))
    }
}

Responder Flow

import net.corda.core.flows.InitiatedBy
import net.corda.core.flows.FlowSession
import net.corda.core.flows.FlowLogic

@InitiatedBy(CrossNodeTokenTransferFlow::class)
class CrossNodeTransferResponder(private val otherSession: FlowSession) : FlowLogic<Unit>() {
    override fun call() {
        // Receive event from initiator node
        val transferEvent = otherSession.receive<TokenTransferEvent>().unwrap { it }
        
        // Emit event locally for receiving account
        serviceHub.eventService.emit(transferEvent)
    }
}
3. Register an Event Listener to Handle Notifications

Now you need a listener that reacts to the emitted events and sends the actual notifications (e.g., logs, external API calls, emails). Create a class that implements Corda's EventListener:

import net.corda.core.node.services.EventListener
import net.corda.core.node.ServiceHub
import org.slf4j.LoggerFactory

class TokenNotificationListener : EventListener {
    private val logger = LoggerFactory.getLogger(javaClass)

    override fun onEvent(event: Any, serviceHub: ServiceHub) {
        if (event is TokenTransferEvent) {
            // Implement your notification logic here
            logger.info("Notification for account ${event.accountId}: ${event.notificationMessage}")
            
            // Example: Call an external notification service
            // externalNotificationService.send(event.accountId, event.notificationMessage)
        }
    }
}

To activate this listener, register it in your node configuration. Add this to your node.conf file:

eventListeners:
  - className: com.yourpackage.TokenNotificationListener
4. Test the Implementation

You can test this by triggering the transfer flow via RPC and verifying the notifications:

import net.corda.client.rpc.CordaRPCClient
import net.corda.core.utilities.NetworkHostAndPort

fun main() {
    val rpcClient = CordaRPCClient(NetworkHostAndPort("localhost", 10006))
    val rpcConnection = rpcClient.start("user1", "test")
    val proxy = rpcConnection.proxy

    // Trigger cross-node transfer flow
    proxy.startFlowDynamic(
        CrossNodeTokenTransferFlow::class.java,
        "account1",
        "account2",
        500L,
        proxy.partiesFromName("PartyB", false).single()
    ).returnValue.get()

    rpcConnection.close()
}

Check your node logs—you should see the notification messages logged for both accounts.

Key Notes
  • Always mark event classes with @CordaSerializable to ensure they work across nodes.
  • Keep listener logic lightweight to avoid blocking flow execution; use async processing for heavy tasks like external API calls.
  • If using the Corda Token SDK, wrap the SDK's MoveTokensFlow in your custom flow to add event emission logic.

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

火山引擎 最新活动