Finished updating README with new functionality
This commit is contained in:
parent
fc2d9a8607
commit
4bfc29695b
1 changed files with 22 additions and 25 deletions
47
README.md
47
README.md
|
@ -1,10 +1,10 @@
|
||||||
# PoW-SHA256
|
# PoW_SHA256
|
||||||
|
|
||||||
Rust crate which generates SHA256 Proofs of Work on serializable datatypes.
|
Rust crate which generates SHA256 Proofs of Work on serializable datatypes.
|
||||||
|
|
||||||
Any type that implements `serde::Deserialize` can be used.
|
Whether for blockchain-related projects or Hashcash-like schemes, this crate can be used to prove work was done on a given serializable input. The input merely needs to implement `serde::Deserialize` to be used.
|
||||||
|
|
||||||
This is a fork of the [`Pow` library](https://github.com/bddap/pow) by bddap with some new additions. Primary of these being:
|
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
|
- 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
|
- `is_valid_proof` method to do the above mentioned
|
||||||
|
@ -13,39 +13,37 @@ Other small changes have also been included of various importance but mostly jus
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
Prove we did work targeting a phrase.
|
Prove work was done, specifically targeting a phrase.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use PoW::PoW;
|
use PoW_SHA256::PoW;
|
||||||
|
|
||||||
// very easy mode
|
// Very easy difficulty
|
||||||
let difficulty = u128::max_value() - u128::max_value() / 2;
|
let difficulty = u128::max_value() - u128::max_value() / 2;
|
||||||
|
|
||||||
let phrase = b"Phrase to tag.".to_vec();
|
let phrase = b"Phrase to be used.".to_vec();
|
||||||
let pw = PoW::prove_work(&phrase, difficulty).unwrap();
|
let pw = PoW::prove_work(&phrase, difficulty).unwrap();
|
||||||
assert!(pw.score(&phrase).unwrap() >= difficulty);
|
|
||||||
|
// Asserting that the result is of sufficient difficulty
|
||||||
|
assert!(pw.result >= difficulty);
|
||||||
|
|
||||||
|
// Asserting that the PoW was generated from the provided phrase
|
||||||
|
assert!(pw.is_valid_proof(&phrase))
|
||||||
```
|
```
|
||||||
|
|
||||||
Prove more difficult work. This time targeting a time.
|
Prove more difficult work. This time targeting a time.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// more diffcult, takes around 100_000 hashes to generate proof
|
// 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 difficulty = u128::max_value() - u128::max_value() / 100_000;
|
||||||
|
|
||||||
let now: u64 = get_unix_time_seconds();
|
let now: u64 = get_unix_time_seconds();
|
||||||
let pw = PoW::prove_work(&now, difficulty).unwrap();
|
let pw = PoW::prove_work(&now, difficulty).unwrap();
|
||||||
assert!(pw.score(&now).unwrap() >= difficulty);
|
|
||||||
|
assert!(pw.result >= difficulty);
|
||||||
|
assert!(pw.is_valid_proof(&phrase))
|
||||||
```
|
```
|
||||||
|
|
||||||
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)>,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Hashing Scheme
|
# Hashing Scheme
|
||||||
|
|
||||||
|
@ -60,23 +58,22 @@ A randomly generated constant, `SALT`, is used as prefix to prevent PoW reuse fr
|
||||||
|
|
||||||
# Choosing a difficulty setting.
|
# Choosing a difficulty setting.
|
||||||
|
|
||||||
Difficulty settings are usually best adjusted dynamically a la bitcoin.
|
Depending on your use case, difficulty settings often are best set dynamically a la bitcoin.
|
||||||
|
|
||||||
To manually select a difficulty, choose the average number of hashes required.
|
However if your use case requires manual setting then it is trivial to set one yourself. One way to manually select a difficulty is to choose the average Hnumber of hashes desired with a function like this:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn difficulty(average: u128) -> u128 {
|
fn get_difficulty(average: u128) -> u128 {
|
||||||
debug_assert_ne!(average, 0, "It is impossible to prove work in zero attempts.");
|
debug_assert_ne!(average, 0, "It is impossible to prove work in zero attempts.");
|
||||||
let m = u128::max_value();
|
let m = u128::max_value();
|
||||||
m - m / average
|
m - m / average
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Conversely, to calculate probable number of hashes required to satisfy a given minimum
|
Conversely we can use the same equation to calculate the probable number of hashes required to satisfy a given difficulty:
|
||||||
difficulty.
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn average(difficulty: u128) -> u128 {
|
fn est_average(difficulty: u128) -> u128 {
|
||||||
let m = u128::max_value();
|
let m = u128::max_value();
|
||||||
if difficulty == m {
|
if difficulty == m {
|
||||||
return m;
|
return m;
|
||||||
|
|
Loading…
Reference in a new issue