How to Create a Simple Blockchain in Go

In this article, we will see how to build a simple blockchain in Go to understand the fundamental concepts of this technology. We will create a structure of blocks linked together, each with a hash, a pointer to the previous block, and some arbitrary data.

Block Structure

Each block will contain the following fields: timestamp, data, block hash, and previous block hash. Here's how to define the structure:


type Block struct {
    Timestamp     int64
    Data          []byte
    PrevBlockHash []byte
    Hash          []byte
}

Hash Creation

To ensure the block's integrity, we will calculate a SHA-256 hash based on the data and the previous block's hash.


func (b *Block) SetHash() {
    headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, IntToHex(b.Timestamp)}, []byte{})
    hash := sha256.Sum256(headers)
    b.Hash = hash[:]
}

Function to Create a New Block

We create a function to instantiate a new block with the provided data and the previous block's hash.


func NewBlock(data string, prevBlockHash []byte) *Block {
    block := &Block{
        Timestamp:     time.Now().Unix(),
        Data:          []byte(data),
        PrevBlockHash: prevBlockHash,
        Hash:          []byte{},
    }
    block.SetHash()
    return block
}

The Blockchain

The blockchain is a simple structure that maintains a list of blocks. The first block, called the "genesis block," is created manually.


type Blockchain struct {
    blocks []*Block
}

func (bc *Blockchain) AddBlock(data string) {
    prevBlock := bc.blocks[len(bc.blocks)-1]
    newBlock := NewBlock(data, prevBlock.Hash)
    bc.blocks = append(bc.blocks, newBlock)
}

func NewGenesisBlock() *Block {
    return NewBlock("Genesis Block", []byte{})
}

func NewBlockchain() *Blockchain {
    return &Blockchain{[]*Block{NewGenesisBlock()}}
}

Main Function

In main, we will create a blockchain, add some blocks, and print them.


func main() {
    bc := NewBlockchain()

    bc.AddBlock("Sending 1 BTC to Mario")
    bc.AddBlock("Sending 2 BTC to Lucia")

    for _, block := range bc.blocks {
        fmt.Printf("Timestamp: %d\n", block.Timestamp)
        fmt.Printf("Data: %s\n", block.Data)
        fmt.Printf("Hash: %x\n", block.Hash)
        fmt.Printf("Prev. hash: %x\n\n", block.PrevBlockHash)
    }
}

Conclusion

We have built a basic blockchain in Go. Although it is not production-ready, it serves as a foundation to understand how blocks, hashes, and the chain itself work. From here, it can be expanded with proof-of-work mechanisms, disk persistence, peer-to-peer networking, and smart contracts.

Back to top