Brief introduction
Digital currency was once the only application scenario for blockchain technology
Support for smart contracts breaks the scene limits and enriches the scope of blockchain applications to support multi-industry, large-scale commercial applications
Blockchain applications
Blockchain applications: typically consists of several smart contracts deployed in a blockchain network, and applications that call these smart contracts
Users focus on applications related to the business itself
Smart contracts encapsulate the process of interacting directly with the blockchain ledger, which is called by the application
Smart Contract Development
The smart contract is essentially to support the upper business logic and deal directly with the ledger structure, at the core.
So designed to simplify the process of upper application development
Application development
The application implements the business logic by invoking the method interface provided by the smart contract, and can be developed using the mainstream languages of JavaScript, Python, Go, Java, etc.
The principle of chain code
Chain code extends from the concept of smart contracts, enabling the use of mainstream advanced programming languages
Once the members of the blockchain network agree on the business logic, the business logic can be programmed into the chain code, and all the people abide by the contract execution
The chain code creates some States (state) and writes to the ledger. The State has a namespace bound to a chain code and is limited to creating his chain code and cannot be accessed directly by other chain codes. However, within the appropriate scope, a chain code can also call another link code, the indirect access to its state
The chain code runs in the isolation sandbox (currently Docker container) on the fabric node and interacts with the node through the GRPC protocol
- Call Chain Code
- Read and Write Ledger
- return response
- ......
Fabric supports multiple languages to implement chain codes, including Golang, JavaScript, Java, etc.
Basic working principle
- First, the user sends a transaction proposal to the fabric's endorsement node via the client through the call chain code.
- The node performs various checks on the transaction proposal, including ACL permission checks, and then creates an environment that simulates the execution of the transaction.
- After that, the node and the chain Code container interact through GRPC messages, simulating the execution of the transaction and giving an endorsement conclusion
- When the code logic of the chain code needs to read and write the ledger, send the corresponding operation type to the node through the shim layer, and return the response message after the node local operation Ledger
- Once the client receives sufficient support for the endorsement node, the transaction can be sent to the sorting node for sorting and eventually to the blockchain
Link code interface and structure
Dependency Packages
The chain code implementation needs to introduce the following dependency packages
- "Github.com/hyperledger/fabric/core/chaincode/shim"
- The shim package provides the middle tier in which the chain code interacts with the ledger
- Chain code through shim. Chaincodestub provides a way to read and modify ledger status
- "Github.com/hyperledger/fabric/protos/peer"
- Peer. Response: Response Information
Link Code Interface
Each chain code needs to implement the Chaincode interface:
type Chaincode interface{ Init(stub ChaincodeStubInterface) peer.Response Invoke(stub ChaincodeStubInterface) peer.Response}
Init and Invoke methods
To write a chain code, the key is to implement the Init and invoke two methods
Init method is called during chain code deployment or upgrade to complete initialization work
The Invoke method is called when the data is manipulated, so the business logic that responds to the invocation or query needs to be implemented in this method
Necessary structure
The necessary structure of a chain code is as follows
package main//引入必要的包import( "fmt" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/protos/peer")//声明一个结构体type SimpleChaincode struct { }//为结构体添加Init方法func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response{ //在该方法中实现链码初始化或升级时的处理逻辑 //编写时可灵活使用stub中的API}//为结构体添加Invoke方法func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response{ //在该方法中实现链码运行中被调用或查询时的处理逻辑 //编写时可灵活使用stub中的API}//主函数,需要调用shim.Start( )方法func main() { err := shim.Start(new(SimpleChaincode)) if err != nil { fmt.Printf("Error starting Simple chaincode: %s", err) }}
Chain Code API
Ledger status Interaction API
The chain code needs to record the data in the distributed ledger. The data that needs to be recorded is called a state, stored as a k-v pair.
Ledger status Interaction API can operate on ledger status
GetState (Key String) ([]byte, error) returns the specific value of the array by key
Putstate (key string, value []byte) write specific keys and values in the error ledger
Delstate (key string) error removing the specified key and value from the Ledger
Getstatebyrange (Startkey, EndKey string) (Statequeryiteratorinterface, error) based on the health value in the specified range
Gethistoryforkey (Key String) (Historyqueryiteratorinterface, error) returns all historical values for the specified health
Getqueryresult (query string) (Statequeryiteratorinterface, error) rich query for state database (Support rich query function)
Trading information related APIs
GETTXID () string returns the transaction ID specified in the trade proposal
Gettxtimestamp () (*timestamp. Timestamp, error) returns the timestamp of the transaction creation, which is the current time that the peer received the transaction
Getbinding () ([]byte, error) returns the binding information for the transaction
Getsignedproposal () (*PB. Signedproposal, error) returns all data related to the transaction proposal
Getcreator () ([]byte, error) returns the identity information of the submitter of the transaction
Gettransient () (Map[string][]byte, error) returns some temporary information that is not written to the ledger in the transaction
Parameter API
Getargs () [][]byte returns the parameters specified in the transaction proposal when the link code is called
Getargsslice () ([]byte, error) returns the parameters specified in the transaction proposal when the link code is called
Getfunctionandparameters () (function string, params []string) returns the called function name and its arguments specified in the transaction proposal when the link code is called
Getstringargs () []string returns the parameter specified when the chain code is called
-C ' {"Args": ["FN", "param1", "param2", "Paramn"]} '
Example (HelloWorld)
Init method
- Gets the parameter and determines whether the parameter length is 2
- Call the Putstate method to write the state to the ledger
- If there is an error, the return
- Print output hint information
- Return success
Invoke method
- Gets the parameter and determines whether the length is 1
- Use the 1th parameter to get the corresponding state getstate (key)
- Returns if there is an error
- Returns an error if the return value is empty
- Return to Success status