实施自定义 VSCC 以基于 ChaincodeProposalPayload 进行验证

Implement custom VSCC to validate on basis of ChaincodeProposalPayload

我正在尝试实现自定义 VSCC(验证系统链码)以在 FunctionName 和负载数据 (ChaincodeProposalPayload) 的基础上添加一些额外的逻辑。目前我能够从 ChaincodeActionPayload 获取 ChaincodeProposalPayload,但数据似乎已编码。 以下是我正在使用的代码。

    // args[0] - function name (not used now)
// args[1] - serialized Envelope
// args[2] - serialized policy

args := stub.GetArgs()
// get the envelope...
env, err := utils.GetEnvelopeFromBlock(args[1])
if err != nil {
    logger.Errorf("VSCC error: GetEnvelope failed, err %s", err)
    return shim.Error(err.Error())
}

// ...and the payload...
payl, err := utils.GetPayload(env)
if err != nil {
    logger.Errorf("VSCC error: GetPayload failed, err %s", err)
    return shim.Error(err.Error())
}

// ...and the transaction...
tx, err := utils.GetTransaction(payl.Data)
if err != nil {
    logger.Errorf("VSCC error: GetTransaction failed, err %s", err)
    return shim.Error(err.Error())
}

// loop through each of the actions within

fmt.Println(len(tx.Actions))
for _, act := range tx.Actions {
    cap, err := utils.GetChaincodeActionPayload(act.Payload)
    if err != nil {
        logger.Errorf("VSCC error: GetChaincodeActionPayload failed, err %s", err)
        return shim.Error(err.Error())
    }

    fmt.Println("payload " + string(cap.ChaincodeProposalPayload))
}

在控制台中,Payload 打印为编码字符串,如

mycc 调用 一种 b 10

我如何正确地将有效载荷解码为 json?

像这样的东西应该可以工作:

    // ChaincodeProposalPayload
    cpp, err := utils.GetChaincodeProposalPayload(cap.ChaincodeProposalPayload)
    if err != nil {
        logger.Errorf("GetChaincodeProposalPayload failed: %s", err)
        return shim.Error(err.Error())
    }

    // ChaincodeInvocationSpec
    cis := &peer.ChaincodeInvocationSpec{}
    err = proto.Unmarshal(cpp.Input, cis)
    if err != nil {
        logger.Errorf("GetChaincodeInvokeSpec failed: %s", err)
        return shim.Error(err.Error())
    }

    spec := &peer.ChaincodeSpec
    err = proto.Unmarshal(cis.GetChaincodeSpec(),spec)
    if err != nil {
        logger.Errorf("Unmarshal ChaincodeSpec failed: %s", err)
        return shim.Error(err.Error())
    }

    ccName := spec.GetChaincodeId().GetName()
    ccArgs := spec.GetInput().GetArgs()
    fnName := ccArgs[0]
    for _, arg := range ccArgs[1:] {
        // do what you want with your args
    }