Come creare una semplice blockchain in Go

In questo articolo vedremo come costruire una semplice blockchain in Go per comprendere i concetti fondamentali di questa tecnologia. Creeremo una struttura di blocchi collegati tra loro, ciascuno con un hash, un puntatore al blocco precedente e alcuni dati arbitrari.

Struttura di un Blocco

Ogni blocco conterrà i seguenti campi: timestamp, dati, hash del blocco e hash del blocco precedente. Ecco come definire la struttura:


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

Creazione dell'Hash

Per garantire l'integrità del blocco, calcoleremo un hash usando SHA-256 basato sui dati e l'hash del blocco precedente.


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

Funzione per Creare un Nuovo Blocco

Creiamo una funzione per istanziare un nuovo blocco con i dati forniti e l'hash del blocco precedente.


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

La Blockchain

La blockchain è una semplice struttura che mantiene la lista dei blocchi. Il primo blocco, chiamato "genesis block", viene creato manualmente.


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()}}
}

Funzione Principale

Nel main, creeremo una blockchain, aggiungeremo alcuni blocchi e li stamperemo.


func main() {
    bc := NewBlockchain()

    bc.AddBlock("Invio 1 BTC a Mario")
    bc.AddBlock("Invio 2 BTC a Lucia")

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

Conclusione

Abbiamo costruito una blockchain basilare in Go. Sebbene non sia adatta alla produzione, serve come base per capire il funzionamento dei blocchi, degli hash e della catena stessa. Da qui, si può espandere con meccanismi di proof-of-work, persistenza su disco, peer-to-peer networking e smart contracts.

Torna su