Simple Blockchain Implementation in Go
This documentation provides an overview and detailed explanation of a simple blockchain implementation in Go. The code is divided into sections for clarity and ease of understanding.
Table of Contents
- Introduction
- Block Structure
- Blockchain Structure
- Hash Function
- Creating the Genesis Block
- Adding New Blocks
- Main Function
- Complete Code
Introduction
A blockchain is a series of blocks, each of which carries data and is connected to the ones before it by a cryptographic hash. The basic ideas of blockchain, such as block creation, hashing, and block linking, are illustrated by this implementation.
Block Structure
Each block in the blockchain has the following attributes:
-
ID:
A unique identifier for the block. -
TimeStamp:
The time when the block was created. -
Data:
The data contained in the block. -
PrevHash:
The hash of the previous block. -
Hash:
The hash of the current block.
type Block struct {
ID int
TimeStamp string
Data string
PrevHash string
Hash string
}
Blockchain Structure
The blockchain itself is a slice of blocks. It starts with a genesis block, and new blocks are added to it.
type Blockchain struct {
blocks []Block
}
Hash Function
The CreateHash function generates a cryptographic hash for a block using its ID, timestamp, data, and previous hash. The MD5 algorithm is used for hashing in this example.
func CreateHash(b *Block) string {
res := strconv.Itoa(b.ID) + b.TimeStamp + b.Data + b.PrevHash
h := md5.New()
h.Write([]byte(res))
hashed := h.Sum(nil)
return hex.EncodeToString(hashed)
}
Creating the Genesis Block
The genesis block is the first block in the blockchain and is created with predefined data. It does not have a previous hash.
func CreateGenesis() Block {
genesis := Block{ID: 0, TimeStamp: time.Now().String(), Data: "Genesis Block"}
genesis.Hash = CreateHash(&genesis)
return genesis
}
Adding New Blocks
New blocks are added to the blockchain with the AddBlock method. Each new block contains data, the current timestamp, and the hash of the previous block.
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1]
newBlock := Block{
ID: prevBlock.ID + 1,
TimeStamp: time.Now().String(),
Data: data,
PrevHash: prevBlock.Hash,
}
newBlock.Hash = CreateHash(&newBlock)
bc.blocks = append(bc.blocks, newBlock)
}
Main Function
The main function initializes the blockchain with a genesis block and adds a few more blocks. It then prints the details of each block in the blockchain.
func main() {
genesisBlock := CreateGenesis()
blockchain := Blockchain{[]Block{genesisBlock}}
blockchain.AddBlock("second block")
blockchain.AddBlock("third block")
blockchain.AddBlock("fourth block")
for _, block := range blockchain.blocks {
fmt.Printf("ID: %d\n", block.ID)
fmt.Printf("TimeStamp: %s\n", block.TimeStamp)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Previous Hash: %s\n", block.PrevHash)
fmt.Printf("Hash: %s\n", block.Hash)
}
}
Complete Code
Here is the complete code for the simple blockchain implementation:
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strconv"
"time"
)
type Block struct {
ID int
TimeStamp string
Data string
PrevHash string
Hash string
}
type Blockchain struct {
blocks []Block
}
func CreateHash(b *Block) string {
res := strconv.Itoa(b.ID) + b.TimeStamp + b.Data + b.PrevHash
h := md5.New()
h.Write([]byte(res))
hashed := h.Sum(nil)
return hex.EncodeToString(hashed)
}
func CreateGenesis() Block {
genesis := Block{ID: 0, TimeStamp: time.Now().String(), Data: "Genesis Block"}
genesis.Hash = CreateHash(&genesis)
return genesis
}
func (bc *Blockchain) AddBlock(data string) {
prevBlock := bc.blocks[len(bc.blocks)-1]
newBlock := Block{
ID: prevBlock.ID + 1,
TimeStamp: time.Now().String(),
Data: data,
PrevHash: prevBlock.Hash,
}
newBlock.Hash = CreateHash(&newBlock)
bc.blocks = append(bc.blocks, newBlock)
}
func main() {
genesisBlock := CreateGenesis()
blockchain := Blockchain{[]Block{genesisBlock}}
blockchain.AddBlock("second block")
blockchain.AddBlock("third block")
blockchain.AddBlock("fourth block")
for _, block := range blockchain.blocks {
fmt.Printf("ID: %d\n", block.ID)
fmt.Printf("TimeStamp: %s\n", block.TimeStamp)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Previous Hash: %s\n", block.PrevHash)
fmt.Printf("Hash: %s\n", block.Hash)
}
}
output
ID: 0 TimeStamp: 2024-07-17 16:48:14.299038516 +0300 EAT m=+0.000026802 Data: Genesis Block Previous Hash: Hash: 3849ac0e830963c34fe18b18ea3d945a
ID: 1 TimeStamp: 2024-07-17 16:48:14.299127941 +0300 EAT m=+0.000116227 Data: second Block Previous Hash: 3849ac0e830963c34fe18b18ea3d945a Hash: fedb1d4405b0330e0e2049e69ccce0de
ID: 2 TimeStamp: 2024-07-17 16:48:14.299135028 +0300 EAT m=+0.000123316 Data: third Block Previous Hash: fedb1d4405b0330e0e2049e69ccce0de Hash: dbcfa81389c07da02b9dbaa429d9eed1
ID: 3 TimeStamp: 2024-07-17 16:48:14.299139949 +0300 EAT m=+0.000128236 Data: forth Block Previous Hash: dbcfa81389c07da02b9dbaa429d9eed1 Hash: 62e57c727a2b48d23c28b1d6db08f85b
This documentation provides a detailed explanation of each part of the blockchain code, ensuring a clear understanding of how the implementation works.
Top comments (1)
stay tuned for more blockchain examples