#pow #sha-256 #proof-of-work

pow_sha256

任何可序列化数据类型的SHA256 PoW

3个不稳定版本

0.2.1 2019年7月29日
0.2.0 2019年7月24日
0.1.0 2019年7月23日

#13 in #proof-of-work


pbd中使用

MIT/Apache

10KB
111 代码行

PoW_SHA256

Rust库,用于在可序列化数据类型上生成SHA256工作量证明。

无论是针对区块链相关项目还是类似Hashcash的方案,此库都可以用于证明在给定的可序列化输入上已经完成了工作量。输入只需实现 serde::Deserialize即可使用。

这是bddap的pow的一个分支,增加了一些新功能。其中最主要的是

  • PoW数据类型现在将计算结果保存下来,用于检查给定输入的证明有效性
  • is_valid_proof方法用于上述功能
  • PoW数据类型不再保存 u128值,因为这些值不被流行的序列化格式(CBOR、Msgpack等)支持
  • is_sufficient_difficulty方法用于检查新的更改带来的难度

还包括一些其他的重要性各异的小改动,但主要是风格和易用性方面的改进。

示例

证明已经完成了工作,具体针对一个短语。

use pow_sha256::PoW;

// Very easy difficulty
let difficulty = u128::max_value() - u128::max_value() / 2;

let phrase = b"Phrase to be used.".to_vec();
let pw = PoW::prove_work(&phrase, difficulty).unwrap();

// Asserting that the result is of sufficient difficulty
assert!(pw.is_sufficient_difficulty(difficulty));

// Asserting that the PoW was generated from the provided phrase
assert!(pw.is_valid_proof(&phrase))

证明更难的工作。这次针对时间。

// Greater diffculty this time around. Takes around 100,000 hashes to find a nonce of the correct difficulty.
let difficulty = u128::max_value() - u128::max_value() / 100_000;

let now: u64 = get_unix_time_seconds();
let pw = PoW::prove_work(&now, difficulty).unwrap();

assert!(pw.is_sufficient_difficulty(difficulty));
assert!(pw.is_valid_proof(&phrase))

哈希方案

使用随机生成的常量SALT作为前缀,以防止PoW在其他系统(如工作量证明区块链)中的重复使用。

在SALT

  • 序列化输入T
  • 上计算SHA256
  • 随机数

结果的前16字节被解释为一个128位无符号整数,并保存为最终结果。

选择难度设置。

根据您的用例,难度设置通常最好设置为动态的,类似于比特币。

但是,如果您的用例需要手动设置,则可以轻松地自行设置一个。一种方法是使用此类函数选择所需的平均哈希数

fn get_difficulty(average: u128) -> u128 {
    debug_assert_ne!(average, 0, "It is impossible to prove work in zero attempts.");
    let m = u128::max_value();
    m - m / average
}

相反,我们可以使用相同的方程来计算满足给定难度所需的可能哈希数

fn est_average(difficulty: u128) -> u128 {
    let m = u128::max_value();
    if difficulty == m {
        return m;
    } 
    m / (m - difficulty)
}

许可

该项目在Apache许可证版本2.0或MIT许可证下双许可。

依赖

~1.1–1.8MB
~41K SLoC