Getting Started with Smart Contracts in Hyperledger Fabric using Go

Nova Novriansyah
Novai-Hyperledger Fabric 101
4 min readJun 3, 2024

Introduction: Smart contracts play a crucial role in blockchain technology, facilitating automated execution of predefined logic upon certain conditions being met. In Hyperledger Fabric, smart contracts, also known as chaincode, are written in various programming languages, including Go. This article will guide you through the process of creating a very simple smart contract in Go for Hyperledger Fabric.

Prerequisites:

  • Basic understanding of Hyperledger Fabric architecture and concepts.
  • Go programming language installed on your system.

Step 1: Set up your development environment
Before you begin writing your smart contract, ensure you have a development environment set up with Hyperledger Fabric. You can follow the official Hyperledger Fabric documentation to set up your environment.

Step 2: Create a new Go module
Start by creating a new directory for your project and initialize it as a Go module:

mkdir simple-contract
cd simple-contract
go mod init simple-contract

Step 3: Write your smart contract
Create a new Go file, for example, simple_contract.go, and define your smart contract logic. Let's create a simple smart contract that increments a counter every time it's invoked.

package main

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

type SimpleContract struct {
contractapi.Contract
}

func (s *SimpleContract) IncrementCounter(ctx contractapi.TransactionContextInterface) error {
// Retrieve the current value of the counter from the world state
counter, err := ctx.GetStub().GetState("counter")
if err != nil {
return fmt.Errorf("failed to read from world state: %v", err)
}

// Increment the counter
var newCounter int
if counter == nil {
newCounter = 1
} else {
newCounter = int(counter[0]) + 1
}

// Update the counter value in the world state
err = ctx.GetStub().PutState("counter", []byte{byte(newCounter)})
if err != nil {
return fmt.Errorf("failed to write to world state: %v", err)
}

// Print the new counter value
fmt.Println("Counter incremented to:", newCounter)
return nil
}

func main() {
// Create a new instance of the simple contract
contract := new(SimpleContract)

// Create a new chaincode instance
cc, err := contractapi.NewChaincode(contract)
if err != nil {
fmt.Printf("Error creating simple contract: %v", err)
return
}

// Start the chaincode
if err := cc.Start(); err != nil {
fmt.Printf("Error starting simple contract: %v", err)
}
}

Explanation of the Code:

  • We define a struct SimpleContract that implements the contractapi.Contract interface. This struct represents our smart contract.
  • The IncrementCounter method is defined on the SimpleContract struct. This method increments a counter stored in the blockchain's world state every time it's invoked.
  • Inside the method, we use the TransactionContextInterface to interact with the blockchain's world state. We retrieve the current value of the counter, increment it, and update the world state with the new value.
  • The main function initializes a new instance of the simple contract and starts a new chaincode instance.

This smart contract defines a SimpleContract struct with a single method IncrementCounter. The IncrementCountermethod increments a counter stored in the blockchain's world state every time it's invoked.

Step 4: Build and deploy the smart contract
To build your smart contract, run the following command:

go build

This will generate an executable file named simple-contract.

Step 5: Test your smart contract
You can test your smart contract locally using the shim package provided by Hyperledger Fabric or by deploying it to a Fabric network for integration testing.

Step 6: Example Invoking the Smart Contract Function
Here’s an example of how you can invoke the IncrementCounter function within the smart contract:

func main() {
// Instantiate contract
contract := new(SimpleContract)
// Simulate transaction context
stub := new(mockStub) // Implement your mock stub
// Invoke contract function
err := contract.IncrementCounter(stub)
if err != nil {
fmt.Printf("Error invoking contract function: %v", err)
return
}
}

Or using this code:

package main

import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)

type SimpleContract struct {}

func (s *SimpleContract) IncrementCounter(stub shim.ChaincodeStubInterface) peer.Response {
counter, err := stub.GetState("counter")
if err != nil {
return shim.Error(fmt.Sprintf("failed to read from world state: %v", err))
}

var newCounter int
if counter == nil {
newCounter = 1
} else {
newCounter = int(counter[0]) + 1
}

err = stub.PutState("counter", []byte{byte(newCounter)})
if err != nil {
return shim.Error(fmt.Sprintf("failed to write to world state: %v", err))
}

fmt.Println("Counter incremented to:", newCounter)
return shim.Success(nil)
}

func main() {
err := shim.Start(new(SimpleContract))
if err != nil {
fmt.Printf("Error starting SimpleContract chaincode: %s", err)
}
}

Step 7: Example Invoking from Command line

# Set environment variables
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=/path/to/your/org1/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/path/to/your/org1/tls/ca.crt

# Invoke the IncrementCounter function directly from the command line

peer chaincode invoke -o orderer.example.com:7050 - tls - cafile /path/to/orderer/tls/ca.crt -C mychannel -n mychaincode -c '{"Args":["IncrementCounter"]}'

In this article, we’ve demonstrated how to create a very simple smart contract in Go for Hyperledger Fabric. Smart contracts serve as the backbone of blockchain applications, enabling automated execution of business logic in a secure and transparent manner. With the knowledge gained from this tutorial, you can start building more complex smart contracts to power your own blockchain applications.

--

--

Nova Novriansyah
Novai-Hyperledger Fabric 101

C|CISO, CEH, CC, CVA,CertBlockchainPractitioner, Google Machine Learning , Tensorflow, Unity Cert, Arduino Cert, AWS Arch Cert. CTO, IT leaders. Platform owners