区块链技术——工作量证明(代码片段)

焕HAN 焕HAN     2023-01-13     272

关键词:

什么是工作量证明

Proof Of Work,简称POW,即对工作量的证明。

为什么要做工作量证明

**挖矿(计算or工作)**的结果会作为数据加入区块链成为一个区块,完成这个**工作**的人也会获得奖励(即挖矿获得比特币)。
所以**挖矿**的过程是一种多劳多得的按劳分配模式,算力高,花费的时间多,获得的数字货币也就越多。
所以必须要证明矿工们为了得到答案确实进行了**计算**。

怎么样做工作量证明

哈希算法
SHA256:一种将任意长度的消息压缩到某一固定长度的消息摘要的函数

为什么选择哈希算法

①哈希算法不是加密算法,也就是没有密码,根据一个哈希值看不出或者说得不到原始数据,非常安全。
②一个唯一的原始数据,只能有唯一一个哈希,而且在已知原始数据和算法的前提下,可以较快计算出一个哈希值。

工作量证明代码

①pay attention to “//新加”

需要注意的是“ ”不能单独放在一行,但是为了清晰,下面的代码都手动做了处理!

需要注意的是“ ”不能单独放在一行,但是为了清晰,下面的代码都手动做了处理!

需要注意的是“ ”不能单独放在一行,但是为了清晰,下面的代码都手动做了处理!

②main.go文件

package main

import (
	"../core"
	"fmt"
	"strconv"
)

func main()  

bc :=core.NewBlockchain()
	bc.AddBlock("Send 1 BTC to Ivan")
	bc.AddBlock("Send 2 createblockchain -address hanshuhuan more BTC to Ivan")
	
	for _,block :=range bc.Blocks
	
		fmt.Printf( "Prev. hash: %x\\n",block.PrevBlockHash)
		fmt.Printf( "Data: %s\\n",block.Data)
		fmt.Printf( "Hash: %x\\n",block.Hash)
	
		//新加:证明某个block的工作量
		pow :=core.NewProofOfWork(block)
		//新加:校验算法
		fmt.Printf("PoW:%s\\n",strconv.FormatBool(pow.Validate()))
		fmt.Println()
	

③block.go文件

package core

import (
	"bytes"
	"crypto/sha256"
	"encoding/gob"
	"log"
	"time"
)
type Block struct 

	Timestamp     int64
	Transactions  []*Transaction
	PrevBlockHash []byte
	Hash          []byte
	//新加
	Nonce         int


func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block 

	block := &Block
	
		Timestamp:     time.Now().Unix(),
		Transactions:  transactions,
		PrevBlockHash: prevBlockHash,
		Hash:          []byte,
		//新加
		Nonce:         0
	
	//新加:创建一个工作量证明
	pow := NewProofOfWork(block)
	//进行工作量证明
	nonce, hash := pow.Run()

	block.Hash = hash[:]
	//新加
	block.Nonce = nonce

	return block

func (b *Block) SetHash() 

	timestamp :=[]byte(strconv.FormatInt(b.Timestamp,10))
	headers :=bytes.Join([][]byteb.PrevBlockHash,b.Data,timestamp,[]byte)
	hash :=sha256.Sum256(headers)
	b.Hash=hash[:]

func NewGenesisBlock() *Block

	return NewBlock( "Genesis Block",[]byte)

④proofofwork.go文件

package core;l

import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"math"
	"math/big"
)

var
(
	maxNonce=math.MaxInt64
)
//决定了挖矿的难度
const targetBits = 20
//ProofOfWork represents a proof-of-work对这个区块计算要满足目标
type ProofOfWork struct 

	block *Block
	target *big.Int

//NewProofOfWork builds and returns a ProofOfWork
func NewProofOfWork(b *Block) *ProofOfWork 

	//首先确定一个固定的整数1
	target :=big.NewInt(1)
	//做移位操作
	target.Lsh(target,uint(256-targetBits))
	pow :=&ProofOfWorkb,target
	return pow

func (pow *ProofOfWork) prepareData(nonce int) []byte

	data :=bytes.Join
	(
		[][]byte
		
			pow.block.PrevBlockHash,
			pow.block.Data,
			IntToHex(pow.block.Timestamp),
			IntToHex(int64(targetBits)),
			//前面四项都是不可变的
			IntToHex(int64(nonce)),
		,
		[]byte,
		)
	return data

func IntToHex(num int64) []byte 

	buff:=new(bytes.Buffer)
	err :=binary.Write(buff,binary.BigEndian,num)
	if err !=nil
	
		log.Panic(err)
	
	return buff.Bytes()


func (pow *ProofOfWork) Run()(int,[]byte) 

	var hashInt big.Int
	var hash    [32]byte
	nonce :=0
	//开始计算
	fmt.Printf("Mining the blockcontaining \\"%s\\"\\n",pow.block.Data)
	//一个一个对比
	for nonce < maxNonce
	
		//由四项不可变数据+一个可变数字nonce组成
		data :=pow.prepareData(nonce)
		//哈希算法
		hash =sha256.Sum256(data)
		fmt.Printf("\\r%x",hash)
		//把哈希值转成哈希整数
		hashInt.SetBytes(hash[:])
		//对比
		if hashInt.Cmp(pow.target) == -1
		
			break
		 
		else 
		
			nonce++
		
	
	fmt.Printf("\\n\\n")
	return nonce,hash[:]

// Validate 校验算法
func (pow *ProofOfWork) Validate()bool 

	var hashInt big.Int
	//用同样的计算方法计算
	data :=pow.prepareData(pow.block.Nonce)
	hash :=sha256.Sum256(data)
	
	hashInt.SetBytes(hash[:])
	isValid :=hashInt.Cmp(pow.target) == -1

	return isValid

⑤blockchain.go文件

没有改动

⑥util.go文件

package core

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

// IntToHex Convert an int64 to a byte array
func IntToHex(num int64) []byte
 
	buff := new(bytes.Buffer)
	err := binary.Write(buff, binary.BigEndian, num)
	if err != nil 
	
		log.Panic(err)
	

	return buff.Bytes()

运行结果展示

运行结果解释

从main文件开始,创建了一个区块链,返回了一个创世纪块,然后又新加了两个区块(这三个区块都经历了newblock()这个方法,所以都会进行工作量证明),然后遍历这个区块链(数组),输出每一个区块的“前一个哈希值、本身的数据、后一个区块的哈希值”,然后去证明每个区块的工作量(详情请见注释),并输出最后证明的结果。

总结

通过一个“看似没有用的算法”,得到一个“看似没有用,但是又很麻烦的数”,因为这个计算的过程非常耗费时间(其实费电),所以这个工作量就有了价值。
首先得到这个结果的人把答案发布到网上,其他人都可以去证明(校验算法),都承认这个结果正确之后,那个首先拿到答案的人就有了比特币。
随着时间的推移,比特币全网算力不断增加,算法运行需要消耗的CPU越来越多,导致设备所需算力提高,比特币挖矿变得越发困难,所以比特币越来越难拿到,但是它本身数量有限,所以比特币越来越值钱。

区块链入门到实战之区块链–工作量证明(代码片段)

目的:解决艰难的任务,获取记账能力。区块链中,每个人手上都有账本,每个人都可以记账,但怎么能让这些账本的内容保持一致,让大家都认这个账,就需要共识机制。人类社会中,通常的共识机制是,如果某个人能完成某... 查看详情

使用javascript实现简单的区块链(签名+工作量证明机制)(代码片段)

//区块链blockchain//data之前区块的哈希值当前区块的哈希值:是由存储在区块里的信息算出来的(data+之前区块的哈希值)constsha256=require('./crypto-js/sha256')//区块classBlockconstructor(data)this.data=datathi 查看详情

工作量证明和挖矿(代码片段)

概览工作量证明拼图和难易度挖矿难易度共识时间戳校验累积难易度验证测试小结概览本章节我们将会在我们的玩具版区块链的基础上加入工作量证明(POW)的支持。在第一章节的版本中,任何人都都可以在没有任何工作量证明的... 查看详情

创建区块链之v2实现pow(proofofwork工作量证明)(代码片段)

block.gopackagemainimport("time")//定义块结构typeBlockstructVersionint64PrevBlockHash[]byteHash[]byteTimeStampint64TargetBitsint64Nonceint64MerKelRoot[]byteData[]byte//设定创建块的方法funcNewBlock(datastring,pre 查看详情

毕设教程python区块链实现-proofofwork工作量证明共识算法(代码片段)

...结构1.2实现的区块链数据结构1.3注意点1.4区块链的核心-工作量证明算法1.4.1拜占庭将军问题1.4.2解决办法1.4.3代码实现2快速实现一个区块链2.1什么是区块链2.2一个完整的快包含什么2.3什么是挖矿2.4工作量证明算法:2.5实现代... 查看详情

区块链实现之pow分析(代码片段)

...在github上面同步开源,项目地址:linkPoW算法介绍工作量证明(ProofOfWork,简称POW),简单理解就是一份证明,用来确认你做过一定量的工作。监测工作的整个过程通常是极为低效的,而通过对工作的结果进行... 查看详情

用go构建一个区块链--part2:工作量证明(代码片段)

翻译的系列文章我已经放到了GitHub上:blockchain-tutorial,后续如有更新都会在GitHub上,可能就不在这里同步了。如果想直接运行代码,也可以cloneGitHub上的教程仓库,进入src目录执行make即可。在前面一文中,... 查看详情

区块链之工作量证明

区块链之工作量证明在整个区块链中的作用新的区块依赖工作量证明算法(PoW)|ProofOfWork来构造理解PoW的目标是找出一个符合特定条件的数字,这个数字很难计算出来,但容易验证。这就是工作量证明的核心思想。示例代码fromha... 查看详情

区块链,工作证明(pow)代码+原理golang版剖析

...库的本质。而且我们可以用它们之间的链式关系向它添加区块:每个区块与前一个链接。唉,然而在现实中添加一个区块添加到链是艰巨的工作。工作证明块链的一个关键思想是,必须通过工作证明才能将数据放入其中。这是一... 查看详情

1.3.1区块链中的加密算法——hash算法(更新)(代码片段)

...代密码学技术,同时,这些密码学技术也被用于设计基于工作量证明的共识算法并识别用户。  在前边的文章中已经系统的讲述了密码学中的哈希算法,在本节,将会给大家介绍Hash算法在区块链中的应用! 概念回顾: ... 查看详情

区块连游戏开发教程(代码片段)

...加到链中。这个决策过程催生了区块链的去中心化性质。工作量证明(PoW)、取证证明(PoS)和权威证明(PoA)是去中心化机制,通过这些机制&#x 查看详情

区块链原理入门(代码片段)

...saction>transactions;//区块上面记录的交易privateIntegernonce;//工作量证明,计算正确哈希值的次数privateStringprevHash;//前一个区块的hash值@TestpublicvoidtestNewBlock()//区块链List<Block>blockChain=newLinkedList<>();//先生成个创世区... 查看详情

区块链原理入门(代码片段)

...saction>transactions;//区块上面记录的交易privateIntegernonce;//工作量证明,计算正确哈希值的次数privateStringprevHash;//前一个区块的hash值@TestpublicvoidtestNewBlock()//区块链List<Block>blockChain=newLinkedList<>();//先生成个创世区... 查看详情

基于java语言构建区块链——工作量证明

...大量的计算才可以完成,这个过程就是我们熟知的挖矿。工作量证明机制区块链最关键的一个思想就是,必须进行大量且困难的计算工作才能将交易数据存放到区块链上。这种工作机制才能保证整个区块链数据的安全性和一致性... 查看详情

区块链实现之pow分析(代码片段)

...在github上面同步开源,项目地址:linkPoW算法介绍工作量证明(ProofOfWork,简称POW),简单理解就是一份证明,用来确认你做过一定量的工作。监测工作的整个过程通常是极为低效的,而通过对工作的结果进行... 查看详情

tendermint101(代码片段)

...以太坊这样的加密货币,它的目标是提供一个比比特币的工作量证明(PoW)更加高效和安全的共识算法。简单地说,Tendermint是一个可供二次开发的软件包,可以在多台机器上安全、一致地实现应用状态的复制。Tendermint可以在不... 查看详情

区块链技术之密码学技术之数字证书(代码片段)

数字证书数字证书用来证明某个公钥是谁的,并且内容是正确的。对于非对称加密算法和数字签名来说,很重要的一点就是公钥的分发。一旦公钥被人替换(典型的如中间人攻击),则整个安全体系将被破坏掉。怎么确保一个公... 查看详情

区块链工作量证明及哈希算法

什么是工作量证明:1、工作的结果作为数据加入区块链成为一个区块2、完成这个工作的人会获得奖励(这也就是通过挖矿获得比特币)3、整个“努力工作并进行证明”的机制,就叫工作量证明为什么采用哈希算法:1、不... 查看详情