Hyperledger fabric smart contract writing (3) Endorsement strategy

1. Concept of endorsement strategy

Nodes use the endorsement strategy to determine whether a transaction is correctly endorsed. When a peer accepts a transaction, it will call the VSCC (Validation System Chaincode) related to the transaction Chaincode as part of the transaction verification process to confirm the validity of the transaction. Therefore, a transaction contains one or more endorsements from endorsement nodes. VSCC’s endorsement verification includes:

  • All endorsements are valid (i.e. valid signatures made by valid certificates)
  • The number of endorsements that meet the requirements
  • Endorsements come from expected endorsing nodes

The endorsement policy mentioned in this article is used to constrain the second and third points in the above verification.

Each chaincode has an endorsement policy, which stipulates that the nodes executing the chaincode on the channel must all recognize (endorse) the execution results before the transaction can be considered valid. Endorsement policies define which organizations’ endorsement (endorsement) is required to execute a transaction.

When performing the transaction verification step as a node, each node must check whether the transaction includes the number of endorsements that meet the policy requirements, and whether these endorsements come from the specified source (VSCC’s endorsement verification provisions 2 and 3 above). In addition, it is necessary to check whether the endorsement in the transaction is valid (that is, whether it comes from a valid signature from a valid certificate, VSCC endorsement verification regulations 1 above)

2. Three granularity endorsement strategies in Fabric

According to the official documentation after Fabric2.0, endorsement strategies are divided into the following three categories:

  • Chaincode-level endorsement strategy
  • Collection-level endorsement policy
  • Key-value level endorsement strategy

2.1 How to use chaincode-level endorsement policy?

Channel members approve chaincode-level endorsement policies when they approve the chaincode definition for their organization. A sufficient number of channel members need to approve the chaincode definition to satisfy the channel endorsement policy Channel/Application/Endorsement (default is set to a majority of channel members) before the definition can be submitted to the channel. After the definition is submitted, the chaincode can be used. Any chaincode call that writes data to the ledger needs to be verified by a sufficient number of channels to meet the requirements of the endorsement policy.

When approving and submitting chaincode definitions using Fabric peer binaries, you can create an endorsement policy from the CLI using the --signature-policy flag.

PS: The endorsement policy syntax (Org1MSP.member, etc.) will be introduced in detail in the next section.

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1MSP.member', 'Org2MSP.member')" --name mycc --version 1.0 --package- id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer. example.com/msp/tlscacerts /tlsca.example.com-cert.pem --waitForEvent

The above command approves the chain code definition of mycc through the AND (Org1MSP.member, Org2MSP.member) strategy, which requires that both Org1 and Org2 have a member to sign the transaction. After enough channel members approve mycc’s chaincode definition, you can use the following command to submit the chaincode definition and endorsement policy to the channel:

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --signature-policy "AND('Org1MSP.member', 'Org2MSP.member')" --name mycc --version 1.0 --sequence 1 --init-required --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example .com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer /crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github. com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

PS: If identity classification is enabled, more fine-grained access control and permission management can be performed, such as using the peer role to limit endorsements to only peer, such as:

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1MSP.peer', 'Org2MSP.peer')" --name mycc --version 1.0 --package- id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer. example.com/msp/tlscacerts /tlsca.example.com-cert.pem --waitForEvent

In addition to specifying the endorsement policy through the CLI or SDK, the chaincode can also use the policy in the channel configuration as the endorsement policy. For example, the –channel-config-policy flag selects the channel configuration and the channel policy used by ACLs, such as:

peer lifecycle chaincode approveformyorg --channelID mychannel --channel-config-policy Channel/Application/Admins --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile / opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

2.2 Update of chaincode-level endorsement policy

If no strategy is specified, the chaincode definition will default to the Channel/Application/Endorsement strategy, which requires transactions to be verified by a majority of channel members. The policy depends on channel membership, so when an organization is removed from the channel and members are added, the policy automatically updates.

If you specify an endorsement policy using –signature-policy, the policy needs to be updated when an organization joins or leaves a channel. New organizations that join the channel after the chaincode is defined can query the chaincode (provided the query has the appropriate authorization defined by the channel policy and any application-level checks performed by the chaincode), but cannot execute or endorse the chaincode. Only organizations listed in the endorsement policy syntax can sign transactions.

2.3. Endorsement policy syntax

Policies are expressed in terms of principals (identities that match roles). That is MSP.ROLE, where MSP represents the required MSP ID and ROLE represents one of the following four roles: member, admin, client, and peer.

For example:
Org0MSP.admin: Any administrator of Org0MSP
Org1MSP.member: Any member of Org1MSP
Org1MSP.client: Any client of Org1MSP
Org1MSP.peer: any node of Org1MSP

The syntax of this language is: EXPR(E[, E...])

Where: EXPR is AND, OR, OutOf, E is the principal or another nested call of EXPR

For example:

  • AND('Org1MSP.member','Org2MSP.member','Org3MSP.member') requires each of the three organizational members to sign once.
  • OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')Requires any one of the two organization members to sign once.
  • OR('Org1MSP.member',AND('Org2MSP.member','Org3MSP.member'))Require signatures from people in organization 1, or people from organizations 2 and 3 Sign each once.
  • OutOf('Org1MSP.member','Org2MSP.member') and OR('Org1MSP.member', 'Org2MSP.member')Same
  • Likewise OutOf(2, 'Org1MSP.member', 'Org2MSP.member') is equivalent to AND('Org1MSP.member', 'Org2MSP.member\ '), and OutOf(2, 'Org1MSP.member', 'Org2.member', 'Org3.member') is equivalent to OR( AND('Org1MSP.member', 'Org2MSP.member'), AND('Org1MSP.member', 'Org3MSP.member'), AND('Org2MSP.member', ' Org3MSP.member'))

2.4, Collection-level endorsement strategy

Similar to chaincode-level endorsement policies, when approving and submitting a chaincode definition, you can also specify the chaincode’s private data collection and corresponding collection-level endorsement policy. If a collection-level endorsement policy is set, a transaction writing to a private data collection key will require the specified organization node to approve (endorse) the transaction.

Collection-level endorsement policies can be used to restrict which organization nodes can write to the private data collection Key namespace, for example, to ensure that unauthorized organizations cannot write to the collection and to ensure that any state in the private data collection has been endorsed by the required collection organization.

Compared with the chaincode-level endorsement strategy, the collection-level endorsement strategy is less restrictive. We can use the two in combination. For example, it requires most organizations to recognize (endorse) chaincode transactions, and also requires specific organizations to recognize (endorse) transactions containing specific A transaction that collects Keys.

If you do not specify a collection-level endorsement policy, a chaincode-level endorsement policy will be used to protect writes to the private data collection key namespace. This is possible if a group of organizations that comply with a chaincode-level endorsement policy are authorized to create data in other organizations’ private datasets.

The syntax of a collection-level endorsement policy is exactly the same as that of a chaincode-level endorsement policy – in the collection configuration, you can specify the endorsement policy with a signature policy (signaturePolicy) or a channel configuration policy (channelConfigPolicy).

2.5 Key-level endorsement policy

Setting a general chaincode-level or collection-level endorsement policy is tied to the lifecycle of the corresponding chaincode. They can only be set or modified when chaincodes are defined on the channel. In contrast, key-level endorsement policies can be set and modified in a more granular way within the chaincode.

The shim API provides the following functions for setting and retrieving key-level endorsement policies. Use ep to represent the endorsement policy syntax above to generate a binary version of the endorsement policy, which can be used by the basic shim API.
For the key values of the ledger, the following interfaces are provided:

SetStateValidationParameter(key string, ep []byte) error
GetStateValidationParameter(key string) ([]byte, error)

For key values of private data, the following interfaces are provided:

SetPrivateDataValidationParameter(collection, key string, ep []byte) error
GetPrivateDataValidationParameter(collection, key string) ([]byte, error)

To facilitate setting up endorsement policies and applying them to validations, Go shim provides a convenient extension interface KeyEndorsementPolicy that allows chaincode developers to handle endorsement policies based on the organization’s MSP identifier, such as :

type KeyEndorsementPolicy interface {
    // Policy returns the endorsement policy as bytes
    Policy() ([]byte, error)

    // AddOrgs adds the specified orgs to the list of orgs that are required
    // to endorse
    AddOrgs(roleType RoleType, organizations ...string) error

    // DelOrgs delete the specified channel orgs from the existing key-level endorsement
    // policy for this KVS key. If any org is not present, an error will be returned.
    DelOrgs(organizations ...string) error

    // ListOrgs returns an array of channel orgs that are required to endorse changes
    ListOrgs() ([]string)
}

For example, to set a key-level endorsement policy that requires endorsement by two specific organizations, you can pass the MSPID of the two organizations to AddOrgs(), and then call Policy( )Construct a byte array of the validation policy and pass it to SetStateValidationParameter()

2.6 Endorsement policy effective priority

On commit, setting a Key’s value is no different than setting the Key’s endorsement policy – both update the Key’s state and are validated according to the same rules.

Verification No key-level endorsement policy With key-level endorsement policy
Modify value Check chaincode-level endorsement policy or collection-level endorsement policy Check key-level endorsement policy
Modify key-level endorsement policy Check chaincode-level endorsement policy or collection-level endorsement policy Check key-level endorsement policy

If a key is modified and a key-level endorsement policy exists, the key-level endorsement policy takes precedence over the chaincode-level or collection-level endorsement policy.
If the endorsement policy for a key is deleted (set to zero), the chaincode-level or collection-level endorsement policy will become the default policy again.

If a transaction modifies multiple keys with different associated key-level endorsement policies, all key-level policies need to be satisfied for the transaction to be valid.