pow_sha256/README.md

91 lines
2.4 KiB
Markdown
Raw Normal View History

# PoW-SHA256
2019-05-11 02:58:06 +05:30
2019-07-23 00:59:16 +05:30
Rust crate which generates SHA256 Proofs of Work on serializable datatypes.
Any type that implements `serde::Deserialize` can be used.
2019-05-11 02:58:06 +05:30
This is a fork of the [`Pow` library](https://github.com/bddap/pow) by bddap with some new additions. Primary of these being:
- PoW datatype now saves the calculation result to be used for checking proof validity given input
- `is_valid_proof` method to do the above mentioned
Other small changes have also been included of various importance but mostly just stylistic/ease of use improvements.
# Examples
Prove we did work targeting a phrase.
2019-05-13 22:53:00 +05:30
```rust
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);
```
Prove more difficult work. This time targeting a time.
2019-05-13 22:53:00 +05:30
```rust
// 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);
```
Define a blockchain block.
```rust
struct Block<T> {
prev: [u8; 32], // hash of last block
payload: T, // generic data
proof_of_work: PoW<([u8; 32], T)>,
}
```
2019-07-23 00:59:16 +05:30
# Hashing Scheme
2019-07-23 00:59:16 +05:30
SHA256 is calculated over the concatenation of the:
- SALT
- Serialized Input `T`
- Nonce
2019-07-23 00:59:16 +05:30
The first 16 bytes of the resulting hash are interpreted as a 128 bit unsigned integer.
2019-07-23 00:59:16 +05:30
A randomly generated constant, `SALT`, is used as prefix to prevent PoW reuse from other systems such as proof of work blockchains.
# Choosing a difficulty setting.
Difficulty settings are usually best adjusted dynamically a la bitcoin.
To manually select a difficulty, choose the average number of hashes required.
2019-05-13 22:53:00 +05:30
```rust
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
}
```
Conversely, to calculate probable number of hashes required to satisfy a given minimum
difficulty.
2019-05-13 22:53:00 +05:30
```rust
fn average(difficulty: u128) -> u128 {
let m = u128::max_value();
if difficulty == m {
return m;
}
m / (m - difficulty)
}
```
# License
2019-07-23 00:59:16 +05:30
This project is dual-licensed under `Apache License Version 2.0` & `MIT license`.