fix: switch between units correctly (#170)
This commit is contained in:
parent
b19f8f3c14
commit
0b9375688e
|
@ -20,6 +20,9 @@ pub use solc::{CompiledContract, Solc};
|
||||||
mod hash;
|
mod hash;
|
||||||
pub use hash::{hash_message, id, keccak256, serialize};
|
pub use hash::{hash_message, id, keccak256, serialize};
|
||||||
|
|
||||||
|
mod units;
|
||||||
|
pub use units::Units;
|
||||||
|
|
||||||
/// Re-export RLP
|
/// Re-export RLP
|
||||||
pub use rlp;
|
pub use rlp;
|
||||||
|
|
||||||
|
@ -38,9 +41,11 @@ pub fn format_ether<T: Into<U256>>(amount: T) -> U256 {
|
||||||
amount.into() / WEI_IN_ETHER
|
amount.into() / WEI_IN_ETHER
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides with the number of decimals
|
/// Divides the provided amount with 10^{units} provided.
|
||||||
pub fn format_units<T: Into<U256>>(amount: T, decimals: usize) -> U256 {
|
pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> U256 {
|
||||||
amount.into() / decimals
|
let units = units.into();
|
||||||
|
let amount = amount.into();
|
||||||
|
amount / 10u64.pow(units.as_num())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the input to a U256 and converts from Ether to Wei.
|
/// Converts the input to a U256 and converts from Ether to Wei.
|
||||||
|
@ -59,12 +64,13 @@ where
|
||||||
Ok(eth.try_into()? * WEI_IN_ETHER)
|
Ok(eth.try_into()? * WEI_IN_ETHER)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Multiplies with the number of decimals
|
/// Multiplies the provided amount with 10^{units} provided.
|
||||||
pub fn parse_units<S>(eth: S, decimals: usize) -> Result<U256, S::Error>
|
pub fn parse_units<S, K>(amount: S, units: K) -> Result<U256, S::Error>
|
||||||
where
|
where
|
||||||
S: TryInto<U256>,
|
S: TryInto<U256>,
|
||||||
|
K: Into<Units>,
|
||||||
{
|
{
|
||||||
Ok(eth.try_into()? * decimals)
|
Ok(amount.try_into()? * 10u64.pow(units.into().as_num()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The address for an Ethereum contract is deterministically computed from the
|
/// The address for an Ethereum contract is deterministically computed from the
|
||||||
|
@ -166,6 +172,24 @@ mod tests {
|
||||||
assert_eq!(WEI_IN_ETHER.as_u64(), 1e18 as u64);
|
assert_eq!(WEI_IN_ETHER.as_u64(), 1e18 as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_format_units() {
|
||||||
|
let gwei_in_ether = format_units(WEI_IN_ETHER, 9);
|
||||||
|
assert_eq!(gwei_in_ether.as_u64(), 1e9 as u64);
|
||||||
|
|
||||||
|
let eth = format_units(WEI_IN_ETHER, "ether");
|
||||||
|
assert_eq!(eth.as_u64(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_units() {
|
||||||
|
let gwei = parse_units(1, 9).unwrap();
|
||||||
|
assert_eq!(gwei.as_u64(), 1e9 as u64);
|
||||||
|
|
||||||
|
let eth = parse_units(1, "ether").unwrap();
|
||||||
|
assert_eq!(eth, WEI_IN_ETHER);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn addr_checksum() {
|
fn addr_checksum() {
|
||||||
let addr_list = vec![
|
let addr_list = vec![
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/// Common Ethereum unit types.
|
||||||
|
pub enum Units {
|
||||||
|
/// Ether corresponds to 1e18 Wei
|
||||||
|
Ether,
|
||||||
|
/// Gwei corresponds to 1e9 Wei
|
||||||
|
Gwei,
|
||||||
|
/// Wei corresponds to 1 Wei
|
||||||
|
Wei,
|
||||||
|
/// Use this for other less frequent unit sizes
|
||||||
|
Other(u32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Units {
|
||||||
|
pub fn as_num(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
Units::Ether => 18,
|
||||||
|
Units::Gwei => 9,
|
||||||
|
Units::Wei => 1,
|
||||||
|
Units::Other(inner) => *inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u32> for Units {
|
||||||
|
fn from(src: u32) -> Self {
|
||||||
|
Units::Other(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<i32> for Units {
|
||||||
|
fn from(src: i32) -> Self {
|
||||||
|
Units::Other(src as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<usize> for Units {
|
||||||
|
fn from(src: usize) -> Self {
|
||||||
|
Units::Other(src as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Units {
|
||||||
|
fn from(src: &str) -> Self {
|
||||||
|
match src.to_lowercase().as_str() {
|
||||||
|
"ether" => Units::Ether,
|
||||||
|
"gwei" => Units::Gwei,
|
||||||
|
"wei" => Units::Wei,
|
||||||
|
_ => panic!("unrecognized units"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue