1. Block
Before starting, take a look at the structure of the block
. The picture above shows the information of the 0th block of Bitcoin. Normally, the block structure is divided into a block header and a block body. The block structure after classification can be represented by the following figure
Start to implement blocks and corresponding functions below
Define the block structure
//定义简单区块结构
type Block struct {
//版本
Version uint64
//前区块哈希
PrevHash []byte
//Merkel根
MerkelRoot []byte
//时间戳
TimeStamp uint64
//难度值
Difficulty uint64
//随机数
Nonce uint64
//当前区块哈希,正常情况下比特币区块中没有当前区块哈希,我们为了方便做了简化
Hash []byte
//数据
Data []byte
}
Create block function
After defining the block, you need to create it to create the block.
func NewBlock (data string, prevBlockHash []byte) *Block{
block := Block{
Version: 00, //这里的版本号随便为随便填写,以后会完善
PrevHash: prevBlockHash,
MerkelRoot: []byte{
}, //同上
TimeStamp: uint64(time.Now().Unix()),
Difficulty: 0, //同上
Nonce: 0, //同上
Hash: []byte{
},
Data: []byte(data),
}
block.SetHash()
return &block
}
Create a method to generate the current block hash
func (block *Block) SetHash(){
//拼装数据
tmp := [][]byte{
Uint64ToByte(block.Version),
block.PrevHash,
block.MerkelRoot,
Uint64ToByte(block.TimeStamp),
Uint64ToByte(block.Difficulty),
Uint64ToByte(block.Nonce),
block.Data,
}
blockInfo := bytes.Join(tmp, []byte{
})
//对数据进行sha256
hash := sha256.Sum256(blockInfo)
//设置当前区块的hash为新生成的hash
block.Hash = hash[:]
}
Create Uint64ToByte function, convert uint64 to byte
func Uint64ToByte(num uint64) []byte{
//使用二进制转换
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, num)
if err != nil{
log.Panic(err)
}
return buffer.Bytes()
}
2. Blockchain
Use arrays to introduce blockchain
Here we simply use the array as a blockchain, and then we will use bolt for optimization.
type BlockChain struct {
//定义一个区块类型的数组
blocks []*Block
}
Create a blockchain
func NewBlockChain () *BlockChain{
//定义创世块
genesisBlock := GenesisBlock()
//返回一个区块链
return &BlockChain{
blocks: []*Block{
genesisBlock}}
}
Create a genesis block
func GenesisBlock() *Block {
return NewBlock("创世块!", []byte{
})
}
Create a method to add blocks
func (bc *BlockChain) AddBlock (data string) {
//获取前区块哈希
lastBlock := bc.blocks[len(bc.blocks)-1]
prevHash := lastBlock.Hash
//创建新区块,并设置数据和前区块hash
block := NewBlock(data, prevHash)
//把新区块添加到区块链后面
bc.blocks = append(bc.blocks, block)
}
test
func main () {
//获取区块链
bc := NewBlockChain()
//为区块链添加一个新的区块
bc.AddBlock("第二个区块")
for i, block := range bc.blocks{
fmt.Printf("============当前区块高度%d==============\n", i)
fmt.Printf("前区块哈希: %x\n", block.PrevHash)
fmt.Printf("区块哈希: %x\n", block.Hash)
fmt.Printf("区块数据: %s\n", block.Data)
}
}
Source code: https://gitee.com/xiaoshengdada/go_bitcoin.git
Since then, a simple Bitcoin architecture design has been completed, but the essence of the Bitcoin system is much more than that. We will continue to improve this system in the future. The next blog will add the pow consensus algorithm (mining function).
If you have any questions, you can come to the WeChat group to communicate and learn and make progress together.
Finally, I recommend the official account of a big guy: the blockchain technology stack , which is the official account of the author of the Ethereum source code.