赞
踩
真正理解区块链底层原理的方法就是写一个底层,UTXO模型区块链的开发难度还是比较简单的,等开发完后再去尝试一下基于account模型的。
什么是区块链以及UTXO模型和account模型等问题我就不在这里写了,网上的资料有很多,跟着写之前可以先去了解一下区块链的基础知识。
开发环境:goland+go1.20
该项目github地址:lighteningchain
mirror地址:lighteningchain(1)
使用goland创建项目,取名为lighteningchain,并使用go mod init lighteningchain
初始化项目
每个区块应该包含头部(head)信息用于总结性的描述这个区块,然后在区块的数据存放区(body)中存放要保存的重要数据
首先定义区块结构体和区块链的结构体
type Block struct {
Timestamp int64
Hash []byte //区块hash值就是其ID
PrevHash []byte
Data []byte
}
type BlockChain struct {
Blocks []*Block
}
有了结构体后,区块的哈希计算也是必不可少的
func (b *Block) SetHash() {
information := bytes.Join([][]byte{Int64ToByte(b.Timestamp), b.PrevHash, b.Data}, []byte{})
hash := sha256.Sum256(information) //软件包sha256 实现 FIPS 180-4 中定义的 SHA224 和 SHA256 哈希算法。
b.Hash = hash[:]
}
func Int64ToByte(num int64) []byte {
var buf = make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(num))
return buf
}
information变量是将区块的各项属性串联之后的字节串。bytes.Join可以将多个字节串连接,第二个参数是将字节串连接时的分隔符,这里设置为[]byte{}即为空。
好了,区块链的准备工作完成,下面就要开始创建区块并将它们连在一起。
首先定义区块创建函数
func CreateBlock(prevhash []byte, data []byte) *Block {
block := Block{time.Now().Unix(), []byte{}, prevhash, data}
block.SetHash() //所有数据添加好后再计算hash
return &block
}
可是每个区块都要链接上一个区块的hash,那第一个区块怎么办?这时就需要创世区块。
func GenesisBlock() *Block {
genesisWords := "HelloWorld!"
return CreateBlock([]byte{}, []byte(genesisWords))
}
把创建好的区块添加到区块链上
func (bc *BlockChain) AddBlock(data string) {
newBlock := CreateBlock(bc.Blocks[len(bc.Blocks)-1].Hash, []byte(data))
bc.Blocks = append(bc.Blocks, newBlock)
}
这下整个区块链就搭建好了,下面我们运行试试。对了,不要忘记初始化。
func CreateBlockChain() *BlockChain {
myBlockchain := BlockChain{}
myBlockchain.Blocks = append(myBlockchain.Blocks, GenesisBlock())
return &myBlockchain
}
接下来我们就可以运行区块链了,我们自己编写几个实例加进去然后输出看看:
func main() { blockchain := CreateBlockChain() time.Sleep(time.Second) blockchain.AddBlock("This is first Block after Genesis") time.Sleep(time.Second) blockchain.AddBlock("This is second!") time.Sleep(time.Second) blockchain.AddBlock("Awesome!") time.Sleep(time.Second) for num, block := range blockchain.Blocks { fmt.Printf("number:%d Timestamp: %d\n", num, block.Timestamp) fmt.Printf("number:%d hash: %x\n", num, block.Hash) fmt.Printf("number:%d Previous hash: %x\n", num, block.PrevHash) fmt.Printf("number:%d data: %s\n", num, block.Data) } }
点击运行,输出如下:
number:0 Timestamp: 1677568251 number:0 hash: 5af650b22cc85f225c2c42850714be9466408025dfec7191436d7efa7a716433 number:0 Previous hash: number:0 data: HelloWorld! number:1 Timestamp: 1677568252 number:1 hash: 3b2eafc41f8c0bd319fd2e7fd44ff2d15215ab931e6a599dc83b60f055653cb8 number:1 Previous hash: 5af650b22cc85f225c2c42850714be9466408025dfec7191436d7efa7a716433 number:1 data: This is first Block after Genesis number:2 Timestamp: 1677568253 number:2 hash: 1be2cf3334f59a54a33e9c28957ecb836f17d731f6731bc7540066f99c2338c7 number:2 Previous hash: 3b2eafc41f8c0bd319fd2e7fd44ff2d15215ab931e6a599dc83b60f055653cb8 number:2 data: This is second! number:3 Timestamp: 1677568254 number:3 hash: 460d954e05c98774b58426372f61997bed92ce7b4e2effb749b7bc2f0c19bdf3 number:3 Previous hash: 1be2cf3334f59a54a33e9c28957ecb836f17d731f6731bc7540066f99c2338c7 number:3 data: Awesome! Process finished with the exit code 0
一切正常!
本章搭建了一个最简易的区块链,主要是加深对于区块和区块链数据结构的认识。可以看出来,此项目目前并不符合高内聚低耦合思想,因此下一章将对此进行优化,并引入POW(工作量证明)共识机制。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。