Go language to implement a simple Bitcoin system (1): block and blockchain

1. Block

Before starting, take a look at the structure of the block
Insert picture description here
. 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

Insert picture description hereStart 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.
Insert picture description hereFinally, 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.

Guess you like

Origin blog.csdn.net/qq_31639829/article/details/115287531