You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在Hyperledger Fabric交易层面指定背书策略?

Transaction-Level Endorsement Policies in Hyperledger Fabric

Great question! While setting endorsement policies during chaincode instantiation (like the command you shared) is the standard approach, Hyperledger Fabric lets you define transaction-specific or asset-specific endorsement rules to meet more granular access control needs. Here are the two primary methods to do this:

1. Dynamic Endorsement Policy in Chaincode Logic

You can use Fabric's chaincode API to set a custom endorsement policy directly within a transaction function. This policy will apply only to that specific transaction execution.

Example (Go Chaincode)

import (
    "fmt"
    "strconv"
    "github.com/hyperledger/fabric-contract-api-go/contractapi"
    "github.com/hyperledger/fabric/common/cid"
)

type SmartContract struct {
    contractapi.Contract
}

// Transfer sets a custom endorsement policy before executing the balance transfer
func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface, from string, to string, amount int) error {
    // Define a custom policy: requires endorsements from both Org1 and Org3 peers
    customPolicyStr := "AND ('Org1MSP.peer', 'Org3MSP.peer')"
    policy, err := cid.NewPolicy(customPolicyStr)
    if err != nil {
        return fmt.Errorf("failed to create custom policy: %v", err)
    }

    // Attach this policy to the current transaction
    err = ctx.GetStub().SetEndorsementPolicy(policy)
    if err != nil {
        return fmt.Errorf("failed to set transaction endorsement policy: %v", err)
    }

    // Execute your core transaction logic below
    fromBalance, err := s.getBalance(ctx, from)
    if err != nil {
        return err
    }
    if fromBalance < amount {
        return fmt.Errorf("%s has insufficient balance: %d", from, fromBalance)
    }

    // Update balances
    err = ctx.GetStub().PutState(from, []byte(strconv.Itoa(fromBalance-amount)))
    if err != nil {
        return err
    }
    toBalance, err := s.getBalance(ctx, to)
    if err != nil {
        return err
    }
    return ctx.GetStub().PutState(to, []byte(strconv.Itoa(toBalance+amount)))
}

func (s *SmartContract) getBalance(ctx contractapi.TransactionContextInterface, user string) (int, error) {
    balanceBytes, err := ctx.GetStub().GetState(user)
    if err != nil {
        return 0, err
    }
    if balanceBytes == nil {
        return 0, fmt.Errorf("user %s does not exist", user)
    }
    return strconv.Atoi(string(balanceBytes))
}

How It Works

When a client calls the Transfer function, the peer will use this custom policy to validate endorsements instead of the chaincode's default instantiation policy. This is ideal for transactions that require stricter or more permissive rules than the general chaincode policy.

2. Key Endorsement Policies (Asset-Specific)

If you need to enforce a policy for any transaction that modifies a specific state key (e.g., an asset like a in your example), you can set a Key Endorsement Policy (KEP). This applies to all transactions that write to that key.

Option 1: Command Line

Use the peer chaincode setendorsementpolicy command to attach a policy to a specific key:

peer chaincode setendorsementpolicy -C $CHANNEL_NAME -n mycc -P "AND ('Org1MSP.peer','Org3MSP.peer')" -k "a"

Option 2: Chaincode API

You can also set KEP directly within your chaincode:

func (s *SmartContract) SetAssetPolicy(ctx contractapi.TransactionContextInterface, assetKey string) error {
    policyStr := "AND ('Org1MSP.peer','Org3MSP.peer')"
    policy, err := cid.NewPolicy(policyStr)
    if err != nil {
        return err
    }
    policyBytes, err := policy.MarshalJSON()
    if err != nil {
        return err
    }
    // Attach policy to the specified asset key
    return ctx.GetStub().SetStateValidationParameter(assetKey, policyBytes)
}

How It Works

Any subsequent transaction that modifies the a key will need endorsements from both Org1 and Org3 peers, overriding the chaincode's default policy. This is perfect for protecting sensitive assets that require specialized access.

Key Notes

  • Priority Order: Transaction-specific policies > Key Endorsement Policies > Chaincode default policy.
  • Policy Syntax: Uses the same AND/OR logic as instantiation policies (e.g., 'Org1MSP.member' for any member of Org1, 'Org2MSP.admin' for admins only).
  • Client Experience: Clients don't need to modify their transaction calls—peers automatically enforce the appropriate policy during validation.

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

火山引擎 最新活动