文章目录
- 前言
- 一、PoW——工作量证明
- 二、go语言简单案例
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、PoW——工作量证明
⚫ Proof-of-Work 简称 PoW,即为工作量证明
⚫ 通过计算一个数值,使得拼揍上交易数据后内容的值满足规定的上限,在节点成功
找到满足的 Hash 值之后,会马上对全网进行广播打包区块,网络的节点收到广播
打包区块,会立刻对其进行验证
⚫ 网络中只有最快解密的区块,才会添加的账本中,其他的节点进行复制,这样就保
证了整个账本的唯一性
⚫ 假如节点有任何的作弊行为,都会导致网络的节点验证不通过,直接丢弃其打包的
区块,这个区块就无法记录到总账本中,作弊的节点耗费的成本就白费了,因此在
巨大的挖矿成本下,也使得矿工自觉自愿的遵守比特币系统的共识协议,也就确保
了整个系统的安全
二、go语言简单案例
package mainimport ("time""strconv""crypto/sha256""encoding/hex""fmt""strings"
)//通过代码,实现PoW挖矿//定义区块
type Block struct {//上一个区块的哈希PreHash string//当前区块的哈希HashCode string//时间戳TimeStamp string//难度系数Diff int//交易信息Data string//区块高度Index int//随机值Nonce int
}//第一个区块:创世区块
func GenerateFirstBlock(data string) Block {//创建第一个Blockvar firstblock Blockfirstblock.PreHash = "0"firstblock.TimeStamp = time.Now().String()//暂设为4firstblock.Diff = 4//交易信息firstblock.Data = datafirstblock.Index = 1firstblock.Nonce = 0//通过sha256得到自己的哈希firstblock.HashCode = GenerationHashValue(firstblock)return firstblock
}//生成区块的哈希值
func GenerationHashValue(block Block) string {//按照比特币的写法,将区块的所有属性拼接后做哈希运算//int转为字符串var hashdata = strconv.Itoa(block.Index) + strconv.Itoa(block.Nonce) +strconv.Itoa(block.Diff) + block.TimeStamp//算哈希var sha = sha256.New()sha.Write([]byte(hashdata))hashed := sha.Sum(nil)return hex.EncodeToString(hashed)
}func main() {//测试创建创世区块var firstBlock = GenerateFirstBlock("创世区块")fmt.Println(firstBlock)fmt.Println(firstBlock.Data)//需要生成下一个区块GenerateNextBlock("第二区块", firstBlock)
}//产生新的区块
func GenerateNextBlock(data string, oldBolock Block) Block {//产生一个新的区块var newBlock BlocknewBlock.TimeStamp = time.Now().String()//难度系数newBlock.Diff = 5//高度newBlock.Index = 2newBlock.Data = datanewBlock.PreHash = oldBolock.HashCodenewBlock.Nonce = 0//创建pow()算法的方法//计算前导0为4个的哈希值newBlock.HashCode = pow(newBlock.Diff, &newBlock)return newBlock
}//pow算法
func pow(diff int, block *Block) string {//实现不停地去挖矿for {//认为是挖了一次矿了hash := GenerationHashValue(*block)//挖矿过程的哈希打印fmt.Println(hash)//判断哈希值前导0是否为diff个0//strings.Repeat:判断hash是否有diff个0,写1,就判断为有多少个1if strings.HasPrefix(hash, strings.Repeat("0", diff)) {//挖矿成功fmt.Println("挖矿成功")return hash} else {//没挖到//随机值自增block.Nonce++}}
}