Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Address w/ checksum support to primitives #19

Merged
merged 21 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
1 change: 0 additions & 1 deletion abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ ethers-primitives.workspace = true
sol-type-parser.workspace = true

hex = { workspace = true, features = ["alloc"] }
tiny-keccak = { workspace = true, features = ["keccak"] }

thiserror = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
Expand Down
2 changes: 1 addition & 1 deletion abi/sol-type-parser/src/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl SolStructDef {

#[allow(non_snake_case)]
const _: () = {
use ::ethers_abi_enc::{SolType, keccak256, no_std_prelude::*};
use ::ethers_abi_enc::{SolType, no_std_prelude::*};

#convert

Expand Down
24 changes: 12 additions & 12 deletions abi/src/coder/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ where

#[cfg(test)]
mod tests {
use ethers_primitives::{B160, B256, U256};
use ethers_primitives::{Address, B256, U256};
use hex_literal::hex;

#[cfg(not(feature = "std"))]
Expand All @@ -323,8 +323,8 @@ mod tests {
1111111111111111111111111111111111111111111111111111111111111111
"
);
let address1 = B160([0x11u8; 20]);
let address2 = B160([0x22u8; 20]);
let address1 = Address::from([0x11u8; 20]);
let address2 = Address::from([0x22u8; 20]);
let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
let expected = (address1, address2, uint);
let decoded = MyTy::decode(&encoded, true).unwrap();
Expand Down Expand Up @@ -430,8 +430,8 @@ mod tests {
);
let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
let string = "gavofyork".to_string();
let address1 = B160([0x11u8; 20]);
let address2 = B160([0x22u8; 20]);
let address1 = Address::from([0x11u8; 20]);
let address2 = Address::from([0x22u8; 20]);
let expected = (uint, string, address1, address2);

let decoded = MyTy::decode_single(&encoded, true).unwrap();
Expand Down Expand Up @@ -464,13 +464,13 @@ mod tests {
6379626f72670000000000000000000000000000000000000000000000000000
"
);
let address1 = B160([0x22u8; 20]);
let address1 = Address::from([0x22u8; 20]);
let bool1 = true;
let string1 = "spaceship".to_string();
let string2 = "cyborg".to_string();
let tuple = (bool1, string1, string2);
let address2 = B160([0x33u8; 20]);
let address3 = B160([0x44u8; 20]);
let address2 = Address::from([0x33u8; 20]);
let address3 = Address::from([0x44u8; 20]);
let bool2 = false;
let expected = (address1, tuple, address2, address3, bool2);

Expand All @@ -497,13 +497,13 @@ mod tests {
0000000000000000000000004444444444444444444444444444444444444444
"
);
let address1 = B160([0x11u8; 20]);
let address2 = B160([0x22u8; 20]);
let address1 = Address::from([0x11u8; 20]);
let address2 = Address::from([0x22u8; 20]);
let bool1 = true;
let bool2 = false;
let tuple = (address2, bool1, bool2);
let address3 = B160([0x33u8; 20]);
let address4 = B160([0x44u8; 20]);
let address3 = Address::from([0x33u8; 20]);
let address4 = Address::from([0x44u8; 20]);

let expected = (address1, tuple, address3, address4);

Expand Down
59 changes: 33 additions & 26 deletions abi/src/coder/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ where

#[cfg(test)]
mod tests {
use ethers_primitives::{B160, U256};
use ethers_primitives::{Address, U256};
use hex_literal::hex;

#[cfg(not(feature = "std"))]
Expand All @@ -198,7 +198,7 @@ mod tests {

#[test]
fn encode_address() {
let address = B160([0x11u8; 20]);
let address = Address::from([0x11u8; 20]);
let expected = hex!("0000000000000000000000001111111111111111111111111111111111111111");
let encoded = sol_type::Address::encode_single(address);
assert_eq!(encoded, expected);
Expand All @@ -207,7 +207,7 @@ mod tests {
#[test]
fn encode_dynamic_array_of_addresses() {
type MyTy = sol_type::Array<sol_type::Address>;
let rust = vec![B160([0x11u8; 20]), B160([0x22u8; 20])];
let rust = vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])];
let encoded = MyTy::encode_single(rust);
let expected = hex!(
"
Expand All @@ -225,7 +225,7 @@ mod tests {
fn encode_fixed_array_of_addresses() {
type MyTy = sol_type::FixedArray<sol_type::Address, 2>;

let addresses = [B160([0x11u8; 20]), B160([0x22u8; 20])];
let addresses = [Address::from([0x11u8; 20]), Address::from([0x22u8; 20])];

let encoded = MyTy::encode_single(addresses);
let encoded_params = MyTy::encode_params(addresses);
Expand All @@ -243,7 +243,7 @@ mod tests {
#[test]
fn encode_two_addresses() {
type MyTy = (sol_type::Address, sol_type::Address);
let addresses = (B160([0x11u8; 20]), B160([0x22u8; 20]));
let addresses = (Address::from([0x11u8; 20]), Address::from([0x22u8; 20]));

let encoded = MyTy::encode(addresses);
let encoded_params = MyTy::encode_params(addresses);
Expand All @@ -262,8 +262,8 @@ mod tests {
fn encode_fixed_array_of_dynamic_array_of_addresses() {
type MyTy = sol_type::FixedArray<sol_type::Array<sol_type::Address>, 2>;
let fixed = [
vec![B160([0x11u8; 20]), B160([0x22u8; 20])],
vec![B160([0x33u8; 20]), B160([0x44u8; 20])],
vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
vec![Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
];

let expected = hex!(
Expand Down Expand Up @@ -292,8 +292,8 @@ mod tests {
type MyTy = sol_type::Array<TwoAddrs>;

let dynamic = vec![
[B160([0x11u8; 20]), B160([0x22u8; 20])],
[B160([0x33u8; 20]), B160([0x44u8; 20])],
[Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
[Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
];

let expected = hex!(
Expand All @@ -318,7 +318,10 @@ mod tests {
fn encode_dynamic_array_of_dynamic_arrays() {
type MyTy = sol_type::Array<sol_type::Array<sol_type::Address>>;

let dynamic = vec![vec![B160([0x11u8; 20])], vec![B160([0x22u8; 20])]];
let dynamic = vec![
vec![Address::from([0x11u8; 20])],
vec![Address::from([0x22u8; 20])],
];

let expected = hex!(
"
Expand All @@ -345,8 +348,8 @@ mod tests {
type MyTy = sol_type::Array<sol_type::Array<sol_type::Address>>;

let dynamic = vec![
vec![B160([0x11u8; 20]), B160([0x22u8; 20])],
vec![B160([0x33u8; 20]), B160([0x44u8; 20])],
vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
vec![Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
];
let expected = hex!(
"
Expand Down Expand Up @@ -375,8 +378,8 @@ mod tests {
type MyTy = sol_type::FixedArray<sol_type::FixedArray<sol_type::Address, 2>, 2>;

let fixed = [
[B160([0x11u8; 20]), B160([0x22u8; 20])],
[B160([0x33u8; 20]), B160([0x44u8; 20])],
[Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
[Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
];

let encoded = MyTy::encode(fixed);
Expand Down Expand Up @@ -406,9 +409,13 @@ mod tests {
(
U256::from(93523141),
U256::from(352332135),
B160([0x44u8; 20]),
Address::from([0x44u8; 20]),
),
(
U256::from(12411),
U256::from(451),
Address::from([0x22u8; 20]),
),
(U256::from(12411), U256::from(451), B160([0x22u8; 20])),
],
"gavofyork".to_string(),
);
Expand Down Expand Up @@ -805,7 +812,7 @@ mod tests {
#[test]
fn encode_static_tuple_of_addresses() {
type MyTy = (sol_type::Address, sol_type::Address);
let data = (B160([0x11u8; 20]), B160([0x22u8; 20]));
let data = (Address::from([0x11u8; 20]), Address::from([0x22u8; 20]));

let encoded = MyTy::encode(data);
let encoded_params = MyTy::encode_params(data);
Expand Down Expand Up @@ -894,8 +901,8 @@ mod tests {
let data = (
U256::from_be_bytes::<32>([0x11u8; 32]),
"gavofyork".to_owned(),
B160([0x11u8; 20]),
B160([0x22u8; 20]),
Address::from([0x11u8; 20]),
Address::from([0x22u8; 20]),
);

let expected = hex!(
Expand Down Expand Up @@ -990,10 +997,10 @@ mod tests {
sol_type::Bool,
);
let data = (
B160([0x22u8; 20]),
Address::from([0x22u8; 20]),
(true, "spaceship".to_owned(), "cyborg".to_owned()),
B160([0x33u8; 20]),
B160([0x44u8; 20]),
Address::from([0x33u8; 20]),
Address::from([0x44u8; 20]),
false,
);

Expand Down Expand Up @@ -1035,10 +1042,10 @@ mod tests {
);

let data = (
B160([0x11u8; 20]),
(B160([0x22u8; 20]), true, false),
B160([0x33u8; 20]),
B160([0x44u8; 20]),
Address::from([0x11u8; 20]),
(Address::from([0x22u8; 20]), true, false),
Address::from([0x33u8; 20]),
Address::from([0x44u8; 20]),
);

let encoded = MyTy::encode(data);
Expand Down
10 changes: 5 additions & 5 deletions abi/src/coder/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use core::fmt;

use ethers_primitives::{B160, U256};
use ethers_primitives::{Address, U256};

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::*;
Expand Down Expand Up @@ -87,19 +87,19 @@ impl From<bool> for WordToken {

impl From<U256> for WordToken {
fn from(value: U256) -> Self {
Self(value.into())
Self(value.to_be_bytes().into())
}
}

impl From<B160> for WordToken {
fn from(value: B160) -> Self {
impl From<Address> for WordToken {
fn from(value: Address) -> Self {
Self(value.into())
}
}

impl From<[u8; 20]> for WordToken {
fn from(value: [u8; 20]) -> Self {
Self(B160::from(value).into())
Self(Address::from(value).into())
}
}

Expand Down
14 changes: 6 additions & 8 deletions abi/src/eip712.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::{
no_std_prelude::{Cow, String, Vec},
sol_type,
util::keccak256,
SolType,
sol_type, SolType,
};
use ethers_primitives::{B160, B256, U256};
use ethers_primitives::{keccak256, Address, B256, U256};

/// Eip712 Domain attributes used in determining the domain separator;
/// Unused fields are left out of the struct type.
Expand Down Expand Up @@ -47,7 +45,7 @@ pub struct Eip712Domain {
feature = "eip712-serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub verifying_contract: Option<B160>,
pub verifying_contract: Option<Address>,

/// A disambiguating salt for the protocol. This can be used as a domain separator of last
/// resort.
Expand All @@ -67,7 +65,7 @@ impl Eip712Domain {
name: Option<Cow<'static, str>>,
version: Option<Cow<'static, str>>,
chain_id: Option<U256>,
verifying_contract: Option<B160>,
verifying_contract: Option<Address>,
salt: Option<B256>,
) -> Self {
Self {
Expand Down Expand Up @@ -676,7 +674,7 @@ mod test {
name: "abcd",
version: "1",
chain_id: U256::from_limbs([0u64, 0, 0, 1]),
verifying_contract: B160([0u8;20]),
salt: B256([0u8;32]),
verifying_contract: Address::new([0u8;20]),
salt: B256::new([0u8;32]),
};
}
1 change: 0 additions & 1 deletion abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ pub use sol_types::{sol_type, SolStruct, SolType};
mod util;
#[doc(hidden)]
pub use util::just_ok;
pub use util::keccak256;

mod eip712;
pub use eip712::Eip712Domain;
6 changes: 2 additions & 4 deletions abi/src/sol_types/sol_struct.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
//! This module contains the [`SolStruct`] trait, which is used to implement
//! Solidity structs logic, particularly for EIP-712 encoding/decoding.

use ethers_primitives::B256;
use ethers_primitives::{keccak256, B256};

use crate::{util::keccak256, SolType, Word};

use crate::{no_std_prelude::*, Eip712Domain};
use crate::{no_std_prelude::*, Eip712Domain, SolType, Word};

type TupleFor<T> = <T as SolStruct>::Tuple;
type TupleTokenTypeFor<T> = <TupleFor<T> as SolType>::TokenType;
Expand Down
10 changes: 4 additions & 6 deletions abi/src/sol_types/sol_type.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use alloc::borrow::Cow;
use core::marker::PhantomData;
use ethers_primitives::{B160, I256, U256};
use ethers_primitives::{keccak256, Address as RustAddress, I256, U256};

#[cfg(not(feature = "std"))]
use crate::no_std_prelude::{Borrow, String as RustString, ToOwned, Vec};
#[cfg(feature = "std")]
use std::{borrow::Borrow, string::String as RustString};

use crate::{
decode, decode_params, decode_single, keccak256, token::*, util, AbiResult, Error, Word,
};
use crate::{decode, decode_params, decode_single, token::*, util, AbiResult, Error, Word};

/// A Solidity Type, for ABI enc/decoding
///
Expand Down Expand Up @@ -339,7 +337,7 @@ pub trait SolType {
pub struct Address;

impl SolType for Address {
type RustType = B160;
type RustType = RustAddress;
type TokenType = WordToken;

fn sol_type_name() -> Cow<'static, str> {
Expand All @@ -366,7 +364,7 @@ impl SolType for Address {

fn detokenize(token: Self::TokenType) -> AbiResult<Self::RustType> {
let sli = &token.as_slice()[12..];
Ok(B160::from_slice(sli))
Ok(RustAddress::from_slice(sli))
}

fn tokenize<B>(rust: B) -> Self::TokenType
Expand Down
10 changes: 0 additions & 10 deletions abi/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ pub(crate) fn pad_u32(value: u32) -> Word {
padded
}

/// Simple interface to keccak256 hash function
pub fn keccak256(bytes: impl AsRef<[u8]>) -> ethers_primitives::B256 {
use tiny_keccak::{Hasher, Keccak};
let mut output = [0u8; 32];
let mut hasher = Keccak::v256();
hasher.update(bytes.as_ref());
hasher.finalize(&mut output);
output.into()
}

// clippy issue
#[doc(hidden)]
#[allow(clippy::missing_const_for_fn)]
Expand Down
Loading