Hyperledger Fabric v1.1链码单事务无法设置多事件,仅获最后事件
在Hyperledger Fabric v1.1链码单个函数中添加多个事件仅能获取最后一个的问题
我在Hyperledger Fabric v1.1的链码函数里添加了多个事件,代码如下:
func (t *SimpleChaincode) initUsers(stub shim.ChaincodeStubInterface, args []string) pb.Response { ... //Event supplier_bare err = stub.SetEvent("supplier_bare", userAsbytes) if err != nil { return shim.Error(err.Error()) } //Event supplier_bare_1 err = stub.SetEvent("supplier_bare_1", userAsbytes) if err != nil { return shim.Error(err.Error()) } ... return shim.Success(nil) }
调用这个函数时,每个事务只能获取到最后一个事件(supplier_bare_1),事务事件信息如下:
... "events": { "chaincode_id": "mycc10", "tx_id":"5421ae37d6e1947b7121f411d64dc215ccacbe45b2d0a9c796cc4a3715c922d6", "event_name": "supplier_bare_1", "payload": { "type": "Buffer", "data": [ ... ] } }, ...
想请教:这是链码本身的限制吗?有没有办法在单个函数里实现多事件触发?
回答
没错,你碰到的是Hyperledger Fabric v1.1的一个固有限制——单个链码事务只能触发一个事件。每次调用stub.SetEvent()都会覆盖之前设置的事件数据,所以最终只有最后一次调用的事件会被附加到事务上,这就是你只能拿到supplier_bare_1的原因。
不过有个可行的替代方案来实现类似“多事件”的效果:把多个事件的内容打包成一个复合结构,作为单个事件的payload发送,在客户端监听时再解析拆分出多个事件条目。具体实现步骤如下:
1. 定义复合事件结构
在链码里定义一个包含多个事件的结构体,用来打包所有需要发送的事件数据:
import "encoding/json" // 单个事件条目 type EventEntry struct { EventName string `json:"event_name"` Payload []byte `json:"payload"` } // 复合事件,包含多个事件条目 type CompositeEvent struct { Events []EventEntry `json:"events"` }
2. 在链码函数中构建并发送复合事件
把你需要的多个事件都塞进复合结构体,序列化后作为单个事件的payload发送:
func (t *SimpleChaincode) initUsers(stub shim.ChaincodeStubInterface, args []string) pb.Response { ... // 构建复合事件,包含两个需要的事件 compositeEvent := CompositeEvent{ Events: []EventEntry{ {EventName: "supplier_bare", Payload: userAsbytes}, {EventName: "supplier_bare_1", Payload: userAsbytes}, }, } // 将复合事件序列化为JSON字节 eventBytes, err := json.Marshal(compositeEvent) if err != nil { return shim.Error(err.Error()) } // 设置单个复合事件 err = stub.SetEvent("composite_supplier_events", eventBytes) if err != nil { return shim.Error(err.Error()) } ... return shim.Success(nil) }
3. 客户端解析复合事件
当客户端监听到composite_supplier_events事件后,把payload反序列化为你定义的CompositeEvent结构,就能从中拿到所有的事件条目了。
另外还有一个备选方案:如果业务场景允许,可以把不同的事件拆分到不同的链码事务中调用,但这会破坏事务的原子性,所以只适合不需要原子性保证的场景。
内容的提问来源于stack exchange,提问作者Jasti Sri Radhe Shyam
相关产品推荐
相关产品推荐

