首页 > 其他分享 >POW(工作量证明)共识机制

POW(工作量证明)共识机制

时间:2023-11-04 14:34:12浏览次数:31  
标签:nonce hash POW let 工作量 哈希 共识 区块 block

POW(工作量证明)共识机制

POW(Proof of Work)是一种区块链共识机制技术,它是最早被使用的共识机制之一。POW机制的核心思想是通过计算来验证交易和生成新的区块。在POW机制中,区块链网络的参与者需要通过完成一定的难题,证明自己对于生成新区块的贡献,并获得一定的奖励。这个难题通常是一个哈希运算的过程,参与者需要不断尝试不同的输入,直到找到符合要求的输出。

POW机制存在的问题是算力竞争太过激烈,导致能源消耗过多,矿工垄断等问题。也因此,随着区块链技术的发展,越来越多的共识机制被提出和使用,如POS(Proof of Stake)、DPoS(Delegated Proof of Stake)等。

下面是一个使用Rust语言实现的POW机制的简单示例代码:

该示例代码中,我们使用Sha256哈希算法计算“Hello, world!”加上一个随机数(nonce)的哈希值,并且判断该哈希值的前3位是否都为0(即目标前缀),如果符合要求,则停止计算,并输出找到的nonce和哈希值。

use std::time::Instant;
use sha2::{Sha256, Digest};

const TARGET_PREFIX: &[u8] = &[0; 3]; // 目标哈希前缀,此处设置为前3位为0

fn main() {
    let start = Instant::now();
    let mut nonce: u64 = 0;
    let data = "Hello, world!".as_bytes();
    let mut hasher = Sha256::new();
    loop {
        // 拼接数据和nonce,计算哈希值
        let mut buf = Vec::new();
        buf.extend_from_slice(data);
        buf.extend_from_slice(&nonce.to_le_bytes());
        hasher.update(&buf);
        let hash = hasher.finalize_reset();
        // 如果哈希值符合目标前缀,则停止计算
        if hash.starts_with(TARGET_PREFIX) {
            println!("found nonce: {}", nonce);
            println!("hash: {:x}", hash);
            break;
        }
        nonce += 1;
    }
    let elapsed = start.elapsed();
    println!("elapsed: {:?}", elapsed);
}

下面是一个更复杂的示例代码,实现了一个简单的区块链,其中包括POW机制、交易记录等。

该示例代码中,我们实现了一个简单的区块链,其中包括了交易记录、POW机制、区块哈希值等。我们可以通过调用add_transaction方法添加交易记录,然后通过调用mine_block方法来挖矿产生新的区块。在mine_block方法中,我们先计算上一个区块的哈希值(如果是第一个区块,则哈希值为32个字节的0),然后创建一个新的区块,使用find_hash方法查找合法哈希值,并将合法哈希值及相应的nonce赋值给区块。在find_hash方法中,我们不断增加nonce,计算区块哈希值,并检查哈希值的前缀是否为目标前缀,如果符合要求,则返回相应的哈希值和nonce值。最后,我们通过序列化和反序列化方式将区块链和区块等保存为字节数组和结构体,并用println!宏输出区块链的信息。

use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::time::Instant;

// 定义区块结构体(数据块)
#[derive(Debug, Serialize, Deserialize, Clone)]
struct Block {
    index: u64,
    timestamp: u64,
    transactions: Vec<Transaction>,
    prev_block_hash: Vec<u8>,
    nonce: u64,
}

// 定义交易结构体
#[derive(Debug, Serialize, Deserialize, Clone)]
struct Transaction {
    from: String,
    to: String,
    amount: u64,
}

// 定义区块链结构体
#[derive(Debug)]
struct Blockchain {
    blocks: Vec<Block>,
    unconfirmed_transactions: Vec<Transaction>,
    target_prefix: Vec<u8>,
}

impl Blockchain {
    // 创建新的区块链
    fn new() -> Self {
        Blockchain {
            blocks: vec![],
            unconfirmed_transactions: vec![],
            target_prefix: vec![0; 3], // 目标哈希前缀,此处设置为前3位为0
        }
    }

    // 添加交易记录
    fn add_transaction(&mut self, from: String, to: String, amount: u64) {
        self.unconfirmed_transactions
            .push(Transaction { from, to, amount });
    }

    // 挖矿
    fn mine_block(&mut self) {
        let start = Instant::now();
        let prev_block_hash = if let Some(last_block) = self.blocks.last() {
            self.hash_block(last_block)
        } else {
            vec![0; 32]
        };
        let mut block = Block {
            index: self.blocks.len() as u64,
            timestamp: start.elapsed().as_secs(),
            transactions: self.unconfirmed_transactions.clone(),
            prev_block_hash,
            nonce: 0,
        };
        let block_hash = self.find_hash(&mut block);
        block.nonce = block_hash.1;
        self.blocks.push(block.clone());
        self.unconfirmed_transactions.clear();
        let elapsed = start.elapsed();
        println!("Mined block {} in {:?}\n", block.index, elapsed);
    }

    // 查找合法哈希值
    fn find_hash(&self, block: &mut Block) -> (Vec<u8>, u64) {
        let mut hasher = Sha256::new();
        loop {
            block.nonce += 1;
            let block_bytes = bincode::serialize(&block).expect("");
            hasher.update(&block_bytes);
            let hash = hasher.finalize_reset();
            if hash.starts_with(&self.target_prefix) {
                return (hash.to_vec(), block.nonce);
            }
        }
    }

    // 计算区块哈希值
    fn hash_block(&self, block: &Block) -> Vec<u8> {
        let block_bytes = bincode::serialize(block).expect("");
        let mut hasher = Sha256::new();
        hasher.update(&block_bytes);
        hasher.finalize().to_vec()
    }
}

fn main() {
    let mut blockchain = Blockchain::new();
    blockchain.add_transaction("Alice".to_string(), "Bob".to_string(), 100);
    blockchain.add_transaction("Bob".to_string(), "Charlie".to_string(), 50);
    blockchain.mine_block();
    blockchain.add_transaction("Charlie".to_string(), "David".to_string(), 30);
    blockchain.mine_block();
    println!("Blockchain: {:?}", blockchain);
}

err

error[E0382]: borrow of moved value: `block`
  --> src\main.rs:67:46
   |
55 |         let mut block = Block {
   |             --------- move occurs because `block` has type `Block`, which does not implement the `Copy` trait
...
64 |         self.blocks.push(block);
   |                          ----- value moved here
...
67 |         println!("Mined block {} in {:?}\n", block.index, elapsed);
   |                                              ^^^^^^^^^^^ value borrowed here after move
   |
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0382`.
error: could not compile `pow` (bin "pow") due to previous error

这个错误是因为变量 block 被移动后被推入了 self.blocks 向量中,然后在后面被 println! 借用。由于移动使原始变量在内存中无效,因此借用失败。

要修复此错误,您可以在将其推入向量之前克隆 Block,如下所示:

self.blocks.push(block.clone());

这样,向量中添加了 Block 的新副本,原始副本仍然有效,因此稍后仍然可以打印它。

或者,您可以修改 Block 结构以实现 Copy trait,这允许复制其数据而不是移动。为此,在 Block 结构的定义上面添加 #[derive(Copy, Clone)]

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Block {
    // ...
}

标签:nonce,hash,POW,let,工作量,哈希,共识,区块,block
From: https://www.cnblogs.com/liuzonglin/p/17809300.html

相关文章

  • powershell自定义命令,类型linux的alias
    linux里经常取很多alias来方便敲命令。在win上也有类型功能,之前边百度边配过一次,然后今天要加一些,发现记不起来了。百度也不顺利。然后就找了一下之前的命令在哪里。C:\Windows\System32\WindowsPowerShell\v1.0下的profile.ps1。把自定义的函数写进去。就可以直接在powershell......
  • 【Azure Web Job】Azure Web Job执行Powershell脚本报错 The term 'Select-AzContext'
    问题描述AzureWebJob执行Powershell脚本报错 Select-AzContext:Theterm'Select-AzContext'isnotrecognizedasthenameofacmdlet,function,scriptfile,oroperableprogram.Checkthespellingofthename,orifapathwasincluded,verifythatthepa......
  • powerdesigner 数据库建模
    作用,用于数据库建模,形成pdm图,生成数据表或者逆向工程到设计图上1、cdm数据库建模文件表格代表实体,线条代表关系,建模不是建数据库,数据库的一种抽象当前只是建模阶段,不清楚具有以后要向哪种数据库中去生成表,所以这里的数据类型都是一种具体数据库类型的代替名称。name属性的中文名c......
  • PowerShell 快捷打开命令
    使用PowerShell时,有时需要频繁打开窗口,每次开窗口又要执行固定的命令。解决方法:1.设置--添加配置文件--新建配置文件2.填写标题,显示到选项卡上,写入要执行的命令3.要执行的命令,比如:[email protected].下拉时就可以看到快捷方式了参考、来源:https://bl......
  • PowerShell ssh 帮助说明
    PowerShellssh帮助说明ssh命令帮助PSC:\Users>ssh-hunknownoption--husage:ssh[-46AaCfGgKkMNnqsTtVvXxYy][-Bbind_interface][-bbind_address][-ccipher_spec][-D[bind_address:]port][-Elog_file][-eescape_char][-Fconfigf......
  • JavaScript中大于Math.pow(2, 53)的数,如何进行进制转换?精度问题,超过18位的数字如何进
    console.log('JavaScript中大于Math.pow(2,53)的数,如何进行进制转换?')//示例console.group('示例')console.log('使用bignumber.js库完美解决。[https://github.com/MikeMcl/bignumber.js/]')console.log('示例:18446744071545290752转为二进制')console.log......
  • PowerApps Canvas通过当前审批状态控制只允许审批人编辑
    在DetailScreen的OnVisible事件中创建变量varIsApprovalUser判断登录人是否为当前节点的审批人:Set(myself,User());If(!varSelectedParent,UpdateContext({varIsApprovalUser:true}),Switch(varSelectedRecord.'OrderStatus状态'.Value,"待审批",If(User().Email=varSelectedRe......
  • PoW、PoS、DPoS和PBFT简介
    1.概览PoW(工作量证明)、PoS(权益证明)、DPoS(委托权益证明)和PBFT(拜占庭容错)是区块链和分布式系统领域中常见的共识算法。下面将详细介绍这些共识算法的原理和特点:PoW(工作量证明):原理:PoW是比特币等区块链网络使用的共识算法。在PoW中,矿工通过解决一个数学难题(哈希碰撞)来创建新的区......
  • 确定已安装的PowerShell版本
    内容来自DOChttps://q.houxu6.top/?s=确定已安装的PowerShell版本我如何确定计算机上安装了哪种版本的PowerShell,以及是否确实安装了它?使用$PSVersionTable.PSVersion来确定引擎版本。如果该变量不存在,可以安全地假设引擎版本为1.0。请注意,$Host.Version和(Get-Host).Vers......
  • Microsoft 365:如何借助Power Virtual Agents来打造智能客服方案
    Blog链接:https://blog.51cto.com/13969817从ChatGPT问世后,微软的Microsoft365权限产品也陆续拥抱AI,比如PowerVirtualAgents就可以使用生成式AI在几分钟内创建强大的聊天机器人,不需要开发人员的帮助,开箱即用的解决方案,快速地响应客户和员工的需求,适用于相关问题客服支持、相关产......