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.