基本链条的实现

基本链条的实现

1. 实现思路

  • 定义区块结构
    • 第一阶段:先实现基础字段:前区块哈希,哈希,数据
    • 第二阶段:补充字段:Version,时间戳,难度值等
  • 创建一个区块(提供一个方法)
  • 定义区块链结构
  • 提供一个创建区块链的方法
  • 提供一个向区块链中添加区块的方法
  • 打印区块链

2. 代码实现

Main.go

package main

import (
	"fmt"
	"time"
)

// 打印区块链

func main() {
	bc := NewBlockChain()

	time.Sleep(time.Second*1)
	bc.AddBlock("25号btc暴涨20%")
	time.Sleep(time.Second*1)
	bc.AddBlock("27号btc暴涨10%")
	time.Sleep(time.Second*1)

	// 遍历区块数据
	for i, block := range bc.Blocks {
		fmt.Printf("\n++++++++++ 当前区块高度: %d ++++++++++\n", i)
		fmt.Printf("Version: %d\n", block.Version)
		fmt.Printf("PrevHash: %x\n", block.PrevHash)
		fmt.Printf("MerkeleRoot: %x\n", block.MerkleRoot)
		fmt.Printf("TimeStamp: %d\n", block.TimeStamp)
		fmt.Printf("Bits: %d\n", block.Bits)
		fmt.Printf("Nonce: %d\n", block.Nonce)
		fmt.Printf("Hash: %x\n", block.Hash)
		fmt.Printf("Data: %s\n", string(block.Data))
	}
}

Block.go

package main

import (
	"bytes"
	"crypto/sha256"
	"time"
)

// 定义区块结构
// 第一阶段:先实现基础字段:前区块哈希,哈希,数据
// 第二阶段:补充字段:Version,时间戳,难度值等
type Block struct {
	// 版本号
	Version uint64

	// 前区块哈希
	PrevHash []byte

	// 交易的根哈希值
	MerkleRoot []byte

	// 时间戳
	TimeStamp uint64

	// 难度值,系统提供一个数据,用于计算出一个哈希值
	Bits uint64

	// 随机数,挖矿要求的数值
	Nonce uint64

	// 哈希,为了方便,把当前区块的哈希放入block中
	Hash []byte

	// 数据
	Data []byte
}

// 创建一个区块(提供一个方法)
// 输入:数据,前区块的哈希值
// 输出:区块
func NewBlock(data string, prevHash []byte) *Block {
	b := Block{
		Version:0,
		MerkleRoot:nil,  // 随意写的
		TimeStamp:uint64(time.Now().Unix()),
		Bits:0,    // 随意写的
		Nonce:0,   // 随意写的
		PrevHash:prevHash,
		Hash:nil,
		Data:[]byte(data),
	}
	// 计算哈希值,对区块中的所有信息的拼接计算哈希
	//TODO
	b.setHash()

	return &b
}

// 提供计算区块哈希值的方法
func (b*Block) setHash() {
	// 比特币哈希算法:sha256
	// data是block各个字段拼成的字节流
	// 拼接三个切片,使用bytes.Join,接收一个二维的切片,使用一个一维的切片拼接
	// func Join(s [][]byte, sep []byte) []byte
	tmp := [][]byte {
		uintToByte(b.Version),
		b.PrevHash,
		b.MerkleRoot,
		uintToByte(b.TimeStamp),
		uintToByte(b.Bits),
		uintToByte(b.Nonce),
		b.Hash,
		b.Data,
	}
	// 使用join方法将二维切片转化为一维切片
	data := bytes.Join(tmp, []byte{})

	hash := sha256.Sum256(data)
	b.Hash = hash[:]
}

Blockchain.go

package main

// 定义区块链结构(使用数组模拟区块链)
type BlockChain struct {
	Blocks []*Block  // 区块链
}

// 创世语
const genesisInfo = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"

// 提供一个创建区块链的方法
func NewBlockChain() *BlockChain {
	// 创建BlockChain,同时添加一个创世块
	genesisBlock := NewBlock(genesisInfo, nil)
	bc := BlockChain{
		Blocks:[]*Block{genesisBlock},
	}
	return &bc
}

// 提供一个向区块链中添加区块的方法
// 参数只需要数据,不需要提供前区块的哈希值,因为bc可以通过自己的下标拿到
func (bc *BlockChain) AddBlock(data string) {
	// 通过下标,得到最后一个区块
	lastBlock := bc.Blocks[len(bc.Blocks)-1]

	// 最后一个区块哈希值是新区块的前哈希
	prevHash := lastBlock.Hash

	// 创建block
	newBlock := NewBlock(data, prevHash)

	// 添加bc中
	bc.Blocks = append(bc.Blocks, newBlock)
}

Utils.go

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
)

func uintToByte(num uint64) []byte {
	//TODO
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.LittleEndian, &num)
	if err != nil {
		fmt.Println("binary.Write error:", err)
		return nil
	}
	return buffer.Bytes()
}

输出结果

++++++++++ 当前区块高度: 0 ++++++++++
Version: 0
PrevHash: 
MerkeleRoot: 
TimeStamp: 1611629077
Bits: 0
Nonce: 0
Hash: eb84dbcf34b4146ed89a9463f7e0af49ab21b6ab94e8835768fed10e658186a9
Data: The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

++++++++++ 当前区块高度: 1 ++++++++++
Version: 0
PrevHash: eb84dbcf34b4146ed89a9463f7e0af49ab21b6ab94e8835768fed10e658186a9
MerkeleRoot: 
TimeStamp: 1611629078
Bits: 0
Nonce: 0
Hash: 558e510a24a550b2aea9fcbb78b8c62e3a1916919508902f582b04930322e386
Data: 25号btc暴涨20%

++++++++++ 当前区块高度: 2 ++++++++++
Version: 0
PrevHash: 558e510a24a550b2aea9fcbb78b8c62e3a1916919508902f582b04930322e386
MerkeleRoot: 
TimeStamp: 1611629079
Bits: 0
Nonce: 0
Hash: b4b6dd54fda7825ac45eb24a9ad59be9451f89cf8e6eecb9673b534e83a1e7b8
Data: 27号btc暴涨10%

此时生成的哈希值没有规则,需要工作量证明的添加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值