Starting with Blockchain Chaincode using Golang

Reading Time: 2 minutes

Chaincode, or a smart contract is a fragment of code written in supported languages like Java or Go that is deployed onto a network of HyperLedger Fabric peer nodes. In this blog, we will learn how to develop Chaincode using Golang for a blockchain network based on Hyperledger Fabric v0.6.

Chaincodes run network transactions which are validated and then appended to the shared ledger. In simple terms, they are encapsulation of business network transactions in a code.

 

Development environment required for Chaincode development:

  • Go Go 1.6 install
  • Hyperledger Fabric
    • Use the following command to install Hyperledger fabric 0.6:

git clone -b v0.6 http://gerrit.hyperledger.org/r/fabric

Implementing the chaincode interface

Following are the main functions required to implement the chaincode shim interface in your Go code.

Init() :

  • Init() is called when you first deploy your chaincode.

An example of using this function with Go can be,



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


func (t *SampleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
if len(args) != 1 {
       return nil, errors.New("Incorrect number of arguments. Expecting 1")
   }
   err := stub.PutState("emp_name", []byte(args[0]))
   if err != nil {
       return nil, err
   }
   return nil, nil
}
view raw

Init()

hosted with ❤ by GitHub

As the name suggests, Init() is used to do any initialization your chaincode needs. In this example, stub.PutState() stores the first value in the args argument in the key “emp_name”.

Invoke()

  • It is called when we expect some “real work” to be done by the chaincode.

Example: Every time there’s a transaction, the ledger will be updated by invoking the chaincode.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
   fmt.Println("invoke is running " + function)
   // Handle different functions
   if function == "init" {
       return t.Init(stub, "init", args)
   } else if function == "write" {
       return t.write(stub, args)
   }
   fmt.Println("invoke did not find func: " + function)
   return nil, errors.New("Received unknown function invocation")
}
view raw

Invoke()

hosted with ❤ by GitHub

Here, the Invoke() function calls a generic write function which will help you store any key value pair in the ledger.

Query() 

  • This function is called to get the state of chaincode.
  • Query is used to  only read the value of your chaincode state’s key/value pairs and it does not add any new blocks to the ledger.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


func (t *SampleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
fmt.Println("query is running " + function)
// Handle different functions
if function == "dummy_query" { //read a variable
fmt.Println("hi there " + function) //error
return nil, nil;
}
fmt.Println("query did not find func: " + function) //error
return nil, errors.New("Received unknown function query: " + function)
}
view raw

Query()

hosted with ❤ by GitHub

Main()

  • The starting point for any Go program is the main function, so here it is used for starting the chaincode.
  • When the peer deploys its instance of the chaincode, the main function gets executed.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


func main() {
err := shim.Start(new(SampleChaincode))
if err != nil {
fmt.Println("Could not start SampleChaincode")
} else {
fmt.Println("SampleChaincode successfully started")
}
}
view raw

main()

hosted with ❤ by GitHub
  • In this example, shim.Start(new(SampleChaincode)) line is used to start the chaincode and register it with the peer.
  • To verify this locally,  run the chaincode in your development environment, which should produce the following error:

[shim] CRIT : peer.address not configured, can’t connect to peer.

 

References:

Written by 

Himani is a Software Consultant, having experience of more than 2.5 years. She is very dedicated, hardworking and focussed. She is Familiar with C#, C++, C , PHP, Scala and Java and has interest in Functional programming. She is very helpful and loves to share her knowledge. Her hobbies include reading books and cooking.

1 thought on “Starting with Blockchain Chaincode using Golang2 min read

Comments are closed.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading