7 个版本
0.2.0 | 2019年12月6日 |
---|---|
0.1.5 | 2019年5月17日 |
#1025 in 编码
每月 22 次下载
13KB
92 行
Pow
基于类型数据的 sha256 工作证明。
任何实现了 serde::Deserialize 的类型都可以被标记为工作证明。
示例
证明我们对一个短语进行了工作。
use pow::Pow;
// very easy mode
let difficulty = u128::max_value() - u128::max_value() / 2;
let phrase = b"Phrase to tag.".to_vec();
let pw = Pow::prove_work(&phrase, difficulty).unwrap();
assert!(pw.score(&phrase).unwrap() >= difficulty);
证明更困难的工作。这次针对时间。
// more diffcult, takes around 100_000 hashes to generate proof
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.score(&now).unwrap() >= difficulty);
定义一个区块链区块。
struct Block<T> {
prev: [u8; 32], // hash of last block
payload: T, // generic data
proof_of_work: Pow<([u8; 32], T)>,
}
评分方案
为了给给定的(目标,Pow)对评分:对 SALT + 目标 + Pow 的连接进行 Sha256 计算。哈希的前 16 个字节被解释为 128 位无符号整数。该整数是分数。使用一个常数 SALT 作为前缀,以防止工作证明在其他系统(如工作量证明区块链)中的重复使用。
换句话说
fn score<T: Serialize>(target: &T, pow_tag: &Pow<T>) -> u128 {
let bytes = serialize(&SALT) + serialize(target) + serialize(pow_tag);
let hash = sha256(&bytes);
deserialize(&hash[..16])
}
序列化编码。
对于此库的用户来说,这不是很重要,但 bincode crate 用于廉价的确定序列化。所有值都使用网络字节顺序进行序列化。
阈值方案
给定一个最小分数 m。如果 score(t, p) >= m,则 Pow p 满足目标 t 的最小分数。
选择难度设置。
难度设置通常最好像比特币一样动态调整。
要手动选择难度,选择所需的平均哈希数量。
fn 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 average(difficulty: u128) -> u128 {
let m = u128::max_value();
if difficulty == m {
return m;
}
m / (m - difficulty)
}
许可证
本项目可根据您的选择,在 Apache License,Version 2.0 或 MIT 许可证下许可。
依赖项
~1.1–1.8MB
~40K SLoC