区块链学习(2)— 工作量证明

在上次的学习中(区块链学习(1))我们已经学会了搭建一个非常简单的区块链,但是真的区块链中有一个核心思想:向区块链中添加一个新的区块时,需要先完成一些困难的工作,从而保证区块链的稳定和安全。

如果我想向区块链中添加一个新区块,有什么方法能证明我的工作已经足够了呢,这就会引入一个新的概念,即工作量证明。

以比特币为例,获得新的比特币(新增一个区块)的方法流程如下:

1. 取一些公开的数据;

2. 给这个公开数据添加一个计数器。计数器默认从 0 开始;

3. 将 data(数据) 和 counter(计数器) 组合到一起,获得一个哈希;

4. 若哈希符合一定条件则结束,不符合则重复3-4;

 代码实现

以比特币为例,首先我们需要定义一个难度:

const targetBits = 24 // 目标哈希值前缀0的个数

 这里进行前缀0验证的方式非常有趣,构造了一个符合前缀24个0的最小数,即(0000...100000....)将哈希值与这个数进行大小比较

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

func NewProofOfWork(b *Block) *ProofOfWork {
	target := big.NewInt(1)
	target.Lsh(target, uint(256-targetBits))

	pow := &ProofOfWork{b, target}

	return pow
}

下面是工作量证明的核心代码:

func (pow *ProofOfWork) Run() (int, []byte) {
	var hashInt big.Int
	var hash [32]byte
	nonce := 0

	fmt.Printf("Mining the block containing \"%s\"\n", pow.block.Data)
	for nonce < maxNonce {
		data := pow.prepareData(nonce)
		hash = sha256.Sum256(data)
		hashInt.SetBytes(hash[:])

		if hashInt.Cmp(pow.target) == -1 {
		    fmt.Printf("\r%x", hash)
			break
		} else {
			nonce++
		}
	}
	fmt.Print("\n\n")

	return nonce, hash[:]
}

 nonce作为计数器其实可以作为新的区块的一个属性添加到Block结构体中:

type Block struct {
	Timestamp     int64
	Data          []byte
	PrevBlockHash []byte
	Hash          []byte
	Nonce         int
}

我们离真正的区块链又进了一步:现在需要经过一些困难的工作才能加入新的块,因此挖矿就有可能了。但是,它仍然缺少一些至关重要的特性:区块链数据库并不是持久化的,没有钱包,地址,交易,也没有共识机制。

参考:https://jeiwan.net/posts/building-blockchain-in-go-part-2/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值