golang 区块链:模拟 pow工作量证明(区块生成)

golang 区块链:模拟 pow工作量证明(区块生成),第1张

一、区块结构
type Block struct {
	//1.区块高度
	Height int64

	//2.上个区块HASH
	PrevBlockHash []byte

	//3.交易数据
	Txs []*transaction.Transaction

	//4.时间戳
	Timestamp int64

	//5.当前区块的hash
	Hash []byte

	//6.Nonce
	Nonce int64
}

二、创建创世区块

/*
生成创世区块
 */
func CreateGenesisBlock(address string) (block *Block,err error) {
	//生成transaction
	tx,err := transaction.NewCoinbaseTransaction(address)
	if err != nil {
		log.Println(err)
		return nil,err
	}

	return NewBlock([]*transaction.Transaction{tx},1,[]byte{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),nil
}

1.生成交易的方法

/*
创世块创建的Transaction
 */
func NewCoinbaseTransaction(address string) (tx *Transaction,err error) {
	//代表消费
	txInput := &TXInput{[]byte{},-1,"Genesis"}

	txOutput := &TXOutput{10,address}

	tx = &Transaction{[]byte{},[]*TXInput{txInput},[]*TXOutput{txOutput}}

	//设置交易hash
	err = tx.hashTransaction()

	return
}

2.生成区块的方法

/*
创建新的区块
 */
func NewBlock(txs []*transaction.Transaction,height int64,preBlockHash []byte) *Block {
	//创建区块
	b := &Block{height,preBlockHash,txs,time.Now().Unix(),nil,0}

	//调用工作量证明的方法并且返回有效的Hash和Nonce
	pow := NewProofOfWork(b)
	hash,nonce := pow.Run()

	//设置计算成功返回的hash和nonce
	b.Hash = hash
	b.Nonce = nonce

	return b
}

3.工作量证明算法(proof of work定义成一个struct)

//256位Hash里面前面至少要有20个零
const targetBit = 20	//难度系数

type ProofOfWork struct {
	Block *Block
	target *big.Int
}

/*
创建新的工作量证明对象
 */
func NewProofOfWork(b *Block) *ProofOfWork {
	//1.创建一个初始值为1的target
	target := big.NewInt(1)

	//2.左移256 - targetBit
	target = target.Lsh(target,256 -targetBit)

	return &ProofOfWork{b,target}
}

/*
开始计算
 */
func (pow *ProofOfWork) Run() ([]byte, int64) {
	var nonce = 0
	var hashInt big.Int
	var hash [32]byte
	for {
		//1.拼接数据
		dataBytes := pow.prepareData(nonce)

		//2.生成hash
		hash = sha256.Sum256(dataBytes)
		//将hash存储到hashInt
		hashInt.SetBytes(hash[:])
		fmt.Printf("\r正在挖矿hash:%x",hash)

		//3.判断hash是否小于pow的target,如果满足条件,跳出循环
		if pow.target.Cmp(&hashInt) == 1 {
			break
		}

		nonce = nonce + 1
	}
	return hash[:],int64(nonce)
}

/*
数据拼接,返回字节数组
 */
func (pow *ProofOfWork) prepareData(nonce int) []byte  {
	data := bytes.Join(
		[][]byte{
			pow.Block.PrevBlockHash,
			pow.Block.HashTransactions(),
			utils.IntToHex(pow.Block.Timestamp),
			utils.IntToHex(targetBit),
			utils.IntToHex(int64(nonce)),
			utils.IntToHex(int64(pow.Block.Height)),
		},
		[]byte{})

	return data
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/730333.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存