Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

refactor: examples #1940

Merged
merged 50 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
247265f
ToC
Dec 15, 2022
535f865
Big numbers section
Dec 16, 2022
a0edb1e
Middleware examples: builder
Dec 16, 2022
47f8d86
Middleware examples: gas_escalator
Dec 16, 2022
dcb1eea
Middleware examples: gas_oracle
Dec 16, 2022
9641955
Middleware examples: signer
Dec 16, 2022
692e277
Middleware examples: missing stubs
Dec 16, 2022
e163986
review: applied DaniPopes suggestions to big numbers
Dec 17, 2022
afdcb1d
typo
Dec 17, 2022
9d6935f
Middleware examples: nonce_manager
Dec 17, 2022
7139097
cargo +nightly fmt
Dec 17, 2022
b8bbc0b
update roadmap
Dec 17, 2022
e64c80c
Middleware examples: policy
Dec 17, 2022
e56386e
Middleware examples: added docs
Dec 17, 2022
d1be75c
Contracts examples: created folder; included abigen example
Dec 18, 2022
a9f63c0
Contracts examples: refactor abigen docs. Fixed cargo example reference
Dec 18, 2022
0fd100f
Contracts examples: contract_events; minor docs changes
Dec 18, 2022
4092ca5
Moved each example under its own crate.
Dec 21, 2022
19125ba
Big numbers examples: used regular operators for math
Dec 21, 2022
7fdd23a
Single examples run correctly (missing overall CI execution)
Dec 21, 2022
a4ce6e4
review: Applied gakonst note to remove commented items in workspace m…
Dec 21, 2022
6e0bfe6
review: Applied gakonst note to restore visibility on contract constr…
Dec 21, 2022
2a2ba3e
ci:
Dec 21, 2022
f4ebd91
cargo +nightly fmt
Dec 21, 2022
aa0cc4b
Merge branch 'master' into docs-examples-refactoring
Dec 21, 2022
4a11cce
ci: fix WASM step error
Dec 21, 2022
629b5c0
Removed deprecated EthGasStation example
Dec 21, 2022
9380c9e
WASM example uses local copy of `contract_abi.json`. In this way we k…
Dec 21, 2022
7dfac21
Cargo.lock aligned to master branch
Dec 21, 2022
3c3bae1
Removed useless comments in examples
Dec 21, 2022
fdf2dcc
review: Applied gakonst note to add panic!() on the policy middleware…
Dec 21, 2022
73b521d
review: Applied gakonst suggestion to add a custom middleware example
Dec 26, 2022
7ecbe08
typos in docs
Dec 26, 2022
8b583b5
Update examples/big-numbers/examples/bn_math_operations.rs
0xMelkor Dec 26, 2022
f89dbbd
review: Applied DaniPopes suggestion on assert_eq!
Dec 26, 2022
36e4c4b
Update examples/big-numbers/README.md
0xMelkor Dec 26, 2022
a9a8cbe
review: All imports now reference the "ethers" crate
Dec 26, 2022
a162e98
Merge branch 'docs-examples-refactoring' of https://github.com/0xMelk…
Dec 26, 2022
df51c10
ci: added features ["ws", "rustls"] where needed
Dec 27, 2022
020b150
Examples with special features (e.g. ipc, trezor etc.) are built alon…
Dec 27, 2022
79e4643
cargo +nightly fmt
Dec 27, 2022
d1f9db8
Examples: Gas oracle API keys from env
Dec 27, 2022
deb7b96
typo: use expect() instead of unwrap()
Dec 27, 2022
d2c4e77
Updated ToC
Dec 27, 2022
20d304f
Gas oracle examples raise panic on middleware errors
Dec 27, 2022
f449f8f
review: removed useless [[example]] in Cargo.toml
Dec 27, 2022
c698efc
review: removed #[allow(unused_must_use)] from gas_escalator example
Dec 27, 2022
2975c97
review: Removed prefixes from file names
Dec 27, 2022
3df7010
review: removed useless [[example]] in Cargo.toml
Dec 27, 2022
25fb72d
docs: Updated description to run examples in the workspace README.md
Dec 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,55 @@ required-features = ["rustls", "ws"]
name = "subscribe_contract_events_with_meta"
path = "examples/subscribe_contract_events_with_meta.rs"
required-features = ["rustls", "ws"]

[[example]]
0xMelkor marked this conversation as resolved.
Show resolved Hide resolved
name = "bn_comparison_equivalence"
path = "examples/big-numbers/bn_comparison_equivalence.rs"

[[example]]
name = "bn_conversion"
path = "examples/big-numbers/bn_conversion.rs"

[[example]]
name = "bn_create_instances"
path = "examples/big-numbers/bn_create_instances.rs"

[[example]]
name = "bn_math_operations"
path = "examples/big-numbers/bn_math_operations.rs"

[[example]]
name = "bn_utilities"
path = "examples/big-numbers/bn_utilities.rs"

[[example]]
name = "builder"
path = "examples/middleware/builder.rs"

[[example]]
name = "gas_escalator"
path = "examples/middleware/gas_escalator.rs"

[[example]]
name = "gas_oracle"
path = "examples/middleware/gas_oracle.rs"

[[example]]
name = "nonce_manager"
path = "examples/middleware/nonce_manager.rs"

[[example]]
name = "policy"
path = "examples/middleware/policy.rs"

[[example]]
name = "signer"
path = "examples/middleware/signer.rs"

[[example]]
name = "timelag"
path = "examples/middleware/timelag.rs"

[[example]]
name = "transformer"
path = "examples/middleware/transformer.rs"
61 changes: 61 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# ToC
- [ ] Address book
- [ ] Anvil
- [ ] Boot anvil
- [ ] Deploy contracts
- [ ] Testing
- [x] Big numbers
- [x] Comparison and equivalence
- [x] Conversion
- [x] Creating Instances
- [x] Math operations
- [x] Utilities
- [ ] Contracts
- [ ] Abigen
- [ ] Creating Instances
- [ ] Events
- [ ] Methods
- [ ] Events
- [ ] Logs and filtering
- [ ] Solidity topics
- [ ] Middleware
- [ ] Builder
- [ ] Gas escalator
- [ ] Gas oracle
- [ ] Nonce manager
- [ ] Policy
- [ ] Signer
- [ ] Time lag
- [ ] Transformer
- [ ] Provider
- [ ] Http
- [ ] IPC
- [ ] Mock
- [ ] Quorum
- [ ] Retry
- [ ] RW
- [ ] WS
- [ ] Query
- [ ] Blocks
- [ ] Contracts
- [ ] Events
- [ ] Transactions
- [ ] Solc
- [ ] Subscriptions
- [ ] Blocks
- [ ] Event logs
- [ ] Transaction
- [ ] Create raw transaction
- [ ] Create typed transaction
- [ ] EIP-1559
- [ ] Estimate gas
- [ ] Get gas price
- [ ] Set gas for a transaction
- [ ] Send raw transaction
- [ ] Send typed transaction
- [ ] Transaction receipt
- [ ] Transaction status
- [ ] Wallets
- [ ] Ledger
- [ ] Local
- [ ] Wasm
260 changes: 260 additions & 0 deletions examples/big-numbers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
# Big numbers
Ethereum uses big numbers (also known as "bignums" or "arbitrary-precision integers") to represent certain values in its codebase and in blockchain transactions. This is necessary because Ethereum uses a 256-bit numbering system, which is much larger than the number systems typically used in modern computers (such as base-10 or base-2). Using big numbers allows Ethereum to handle very large numbers, such as those that may be required to represent very large balances or quantities of a particular asset.
0xMelkor marked this conversation as resolved.
Show resolved Hide resolved

It is worth noting that Ethereum is not the only blockchain or cryptocurrency that uses big numbers. Many other blockchains and cryptocurrencies also use big numbers to represent values in their respective systems.

## Comparison and equivalence

```rust
use ethers::types::U256;

fn main() {
// a == b
let a = U256::from(100_u32);
let b = U256::from(100_u32);
assert!(a.eq(&b));

// a < b
let a = U256::from(1_u32);
let b = U256::from(100_u32);
assert!(a.lt(&b));

// a <= b
let a = U256::from(100_u32);
let b = U256::from(100_u32);
assert!(a.le(&b));

// a > b
let a = U256::from(100_u32);
let b = U256::from(1_u32);
assert!(a.gt(&b));

// a >= b
let a = U256::from(100_u32);
let b = U256::from(100_u32);
assert!(a.ge(&b));

// a == 0
let a = U256::zero();
assert!(a.is_zero());
}
```

## Conversion

```rust
use ethers::{types::U256, utils::format_units};

fn main() {
let num = U256::from(42_u8);

let a: u128 = num.as_u128();
assert_eq!(a, 42);

let b: u64 = num.as_u64();
assert_eq!(b, 42);

let c: u32 = num.as_u32();
assert_eq!(c, 42);

let d: usize = num.as_usize();
assert_eq!(d, 42);

let e: String = num.to_string();
assert_eq!(e, "42".to_string());

let f: String = format_units(num, 4).unwrap();
assert_eq!(f, "0.0042".to_string());
}
```

## Create instances
```rust
use ethers::{types::{serde_helpers::Numeric, U256}, utils::{parse_units, ParseUnits}};

fn main() {
// From strings
let a = U256::from_dec_str("42").unwrap();
assert_eq!(&*format!("{a:?}"), "42");

let amount = "42";
let units = 4;
let pu: ParseUnits = parse_units(amount, units).unwrap();
let b = U256::from(pu);
assert_eq!(&*format!("{b:?}"), "420000");

// From numbers
let c = U256::from(42_u8);
assert_eq!(&*format!("{c:?}"), "42");

let d = U256::from(42_u16);
assert_eq!(&*format!("{d:?}"), "42");

let e = U256::from(42_u32);
assert_eq!(&*format!("{e:?}"), "42");

let f = U256::from(42_u64);
assert_eq!(&*format!("{f:?}"), "42");

let g = U256::from(42_u128);
assert_eq!(&*format!("{g:?}"), "42");

let h = U256::from(0x2a);
assert_eq!(&*format!("{h:?}"), "42");

let i: U256 = 42.into();
assert_eq!(&*format!("{i:?}"), "42");

// From `Numeric`
let num: Numeric = Numeric::U256(U256::one());
let l = U256::from(num);
assert_eq!(&*format!("{l:?}"), "1");

let num: Numeric = Numeric::Num(42);
let m = U256::from(num);
assert_eq!(&*format!("{m:?}"), "42");
}
```

## Math operations
```rust
use std::ops::{Add, Div, Mul, Sub};

use ethers::{types::U256, utils::format_units};

fn main() {
let a = U256::from(100);
let b = U256::from(10);

// a + b
let sum = a.add(b);
assert!(sum.eq(&U256::from(110)));

// a - b
let diff = a.sub(b);
assert!(diff.eq(&U256::from(90)));

// a / b
let div = a.div(b);
assert!(div.eq(&U256::from(10)));

// a * b
let mul = a.mul(b);
assert!(mul.eq(&U256::from(1000)));

// a % b
let module = a.div_mod(b).1;
assert!(module.eq(&U256::zero()));

// a ^ b
let base = U256::from(10);
let expon = U256::from(2);
let pow = base.pow(expon);
assert!(pow.eq(&U256::from(100)));

// Multiply two 'ether' numbers:
// Big numbers are integers, that can represent fixed point numbers.
// For instance, 1 ether has 18 fixed
// decimal places (1.000000000000000000), and its big number
// representation is 10^18 = 1000000000000000000.
// When we multiply such numbers we are summing up their exponents.
// So if we multiply 10^18 * 10^18 we get 10^36, that is obviously incorrect.
// In order to get the correct result we need to divide by 10^18.
let eth1 = U256::from(10_000000000000000000_u128); // 10 ether
let eth2 = U256::from(20_000000000000000000_u128); // 20 ether
let base = U256::from(10).pow(18.into());
let mul = eth1.mul(eth2).div(base); // We also divide by 10^18
let s: String = format_units(mul, "ether").unwrap();
assert_eq!(&*s, "200.000000000000000000"); // 200
}
```

## Utilities
In order to create an application, it is often necessary to convert between the representation of values that is easily understood by humans (such as ether) and the machine-readable form that is used by contracts and math functions (such as wei). This is particularly important when working with Ethereum, as certain values, such as balances and gas prices, must be expressed in wei when sending transactions, even if they are displayed to the user in a different format, such as ether or gwei. To help with this conversion, ethers-rs provides two functions, `parse_units` and `format_units`, which allow you to easily convert between human-readable and machine-readable forms of values. `parse_units` can be used to convert a string representing a value in ether, such as "1.1", into a big number in wei, which can be used in contracts and math functions. `format_units` can be used to convert a big number value into a human-readable string, which is useful for displaying values to users.

### `parse_units`
```rust
use ethers::{types::U256, utils::{parse_units, ParseUnits}};

fn main() {
let pu: ParseUnits = parse_units("1.0", "wei").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1)));

let pu: ParseUnits = parse_units("1.0", "kwei").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000)));

let pu: ParseUnits = parse_units("1.0", "mwei").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000)));

let pu: ParseUnits = parse_units("1.0", "gwei").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000000)));

let pu: ParseUnits = parse_units("1.0", "szabo").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000000000_u128)));

let pu: ParseUnits = parse_units("1.0", "finney").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000000000000_u128)));

let pu: ParseUnits = parse_units("1.0", "ether").unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000000000000000_u128)));

let pu: ParseUnits = parse_units("1.0", 18).unwrap();
let num = U256::from(pu);
assert!(num.eq(&U256::from(1000000000000000000_u128)));

}
```

### `format_units`
```rust
use ethers::{types::U256, utils::format_units};

fn format_units_example() {
// 1 ETHER = 10^18 WEI
let one_ether = U256::from(1000000000000000000_u128);

let num: String = format_units(one_ether, "wei").unwrap();
assert_eq!(&*num, "1000000000000000000.0");
0xMelkor marked this conversation as resolved.
Show resolved Hide resolved

let num: String = format_units(one_ether, "gwei").unwrap();
assert_eq!(&*num, "1000000000.000000000");

let num: String = format_units(one_ether, "ether").unwrap();
assert_eq!(&*num, "1.000000000000000000");

// 1 GWEI = 10^9 WEI
let one_gwei = U256::from(1000000000_u128);

let num: String = format_units(one_gwei, 0).unwrap();
assert_eq!(&*num, "1000000000.0");

let num: String = format_units(one_gwei, "wei").unwrap();
assert_eq!(&*num, "1000000000.0");

let num: String = format_units(one_gwei, "kwei").unwrap();
assert_eq!(&*num, "1000000.000");

let num: String = format_units(one_gwei, "mwei").unwrap();
assert_eq!(&*num, "1000.000000");

let num: String = format_units(one_gwei, "gwei").unwrap();
assert_eq!(&*num, "1.000000000");

let num: String = format_units(one_gwei, "szabo").unwrap();
assert_eq!(&*num, "0.001000000000");

let num: String = format_units(one_gwei, "finney").unwrap();
assert_eq!(&*num, "0.000001000000000");

let num: String = format_units(one_gwei, "ether").unwrap();
assert_eq!(&*num, "0.000000001000000000");
}
```

Loading