What is a transaction?
According to Hyperledger Fabric’s official documentation,
A transaction is an invoke result or an instantiate result that is submitted for ordering, validation, and committing.
Instantiate transaction initializes and starts a chaincode in a particular channel. Invoke transactions perform read/write operation on the ledger. Both these core transactions adhere to the endorsement policy to commit the final result to the ledger and the state. In case of a failure, the blockchain state gets updated with a failed transaction information and the ledger stays untouched.
What is an Endorsement Policy? And why it is important for a transaction to succeed?
Endorsement Policy defines the required peer responses for a transaction to be considered valid. The definition might sound vague but with some workflow explanation it can easily be understood.
Let’s look at how an endorsement policy is defined. Below are a few common ways these policies are defined,
1. OR Structured
OR (Org1.member, Org2.member, Org3.member)
This means that even if just one peer response from the members of Org1, Org2, or Org3 is received, then the transaction is considered valid. This should never be used in a production-case structure - because if either one of them is compromised, then it would result in a single point of failure.
2. AND Structured
AND (Org1.member, Org2.member, Org3.member)
This defines the policy in a way that only if all the responses from Org1, Org2, and Org3 members are the same, only then the transaction is considered valid. For all other scenarios, the transaction will never get committed to the ledger.
3. NOutOf Structured
2OutOf (Org1.member, Org2.member, Org3.member).
You guessed it! This will validate the transaction if at least two members approve.
Transaction Workflow Explained
Let’s consider a Fabric network which has two organizations and each organization has two peers. Consider that we installed the chaincode using the AND Structure.
Now, when a user invokes a transaction using the SDK, it pings the peer with the transaction data (aka transaction proposal) and simulates the transaction inside the peer. Now, the peer’s response is sent to the SDK. The SDK consequently wraps the responses and makes an invocation request to the orderer. This is where the validation of endorsement policy happens.
The orderer reads through the invocation proposal and validates the endorsements within the policy. If there is an endorsement failure, the transaction is registered/updated to the state to show the failed transaction as well. But the ledger stays untouched.
A word of caution: When a peer simulates a transaction proposal and sends a peer response, it has to be same with other peer responses. So using a random number in the chaincode logic will most likely result in different peer responses, which consequently lands you with an “ENDORSEMENT POLICY FAILURE”.
Make sure your chaincode logic is deterministic.