fix: ethers-contract circular dep on ethers-signers (#2291)
* fix: remove dep of contract on signers * refactor: move ethers/live up a dir * test: move over eip712 test from ethers-contract * chore: rm unused vars * ethers: enable ethers-solc by default * ci: remove --live from ci tests * chore: make ethers-solc always part of ethers * test: ensure rustls is enabled for https * chore: ignore clippy fp
This commit is contained in:
parent
080bb2e068
commit
73c7f6cacc
|
@ -94,7 +94,7 @@ jobs:
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: live tests
|
- name: live tests
|
||||||
run: cargo test -p ethers --test live --all-features
|
run: cargo test -p ethers --all-features
|
||||||
|
|
||||||
# TODO: [#2191](https://github.com/gakonst/ethers-rs/issues/2191)
|
# TODO: [#2191](https://github.com/gakonst/ethers-rs/issues/2191)
|
||||||
# feature-checks:
|
# feature-checks:
|
||||||
|
|
|
@ -1219,6 +1219,7 @@ dependencies = [
|
||||||
"ethers-providers",
|
"ethers-providers",
|
||||||
"ethers-signers",
|
"ethers-signers",
|
||||||
"ethers-solc",
|
"ethers-solc",
|
||||||
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1241,7 +1242,6 @@ dependencies = [
|
||||||
"ethers-core",
|
"ethers-core",
|
||||||
"ethers-derive-eip712",
|
"ethers-derive-eip712",
|
||||||
"ethers-providers",
|
"ethers-providers",
|
||||||
"ethers-signers",
|
|
||||||
"ethers-solc",
|
"ethers-solc",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
"hex",
|
||||||
|
|
|
@ -43,8 +43,8 @@ ethers-contract-derive = { workspace = true, optional = true }
|
||||||
ethers-derive-eip712 = { workspace = true, optional = true }
|
ethers-derive-eip712 = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ethers-signers.workspace = true
|
|
||||||
ethers-solc.workspace = true
|
ethers-solc.workspace = true
|
||||||
|
ethers-providers = { workspace = true, features = ["ws"] }
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||||
tokio = { workspace = true, features = ["macros"] }
|
tokio = { workspace = true, features = ["macros"] }
|
||||||
|
|
|
@ -75,7 +75,6 @@ pub type Contract<M> = ContractInstance<std::sync::Arc<M>, M>;
|
||||||
/// };
|
/// };
|
||||||
/// use ethers_contract::Contract;
|
/// use ethers_contract::Contract;
|
||||||
/// use ethers_providers::{Provider, Http};
|
/// use ethers_providers::{Provider, Http};
|
||||||
/// use ethers_signers::Wallet;
|
|
||||||
/// use std::{convert::TryFrom, sync::Arc};
|
/// use std::{convert::TryFrom, sync::Arc};
|
||||||
///
|
///
|
||||||
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -122,7 +121,6 @@ pub type Contract<M> = ContractInstance<std::sync::Arc<M>, M>;
|
||||||
/// use ethers_core::{abi::Abi, types::Address};
|
/// use ethers_core::{abi::Abi, types::Address};
|
||||||
/// use ethers_contract::{Contract, EthEvent};
|
/// use ethers_contract::{Contract, EthEvent};
|
||||||
/// use ethers_providers::{Provider, Http, Middleware};
|
/// use ethers_providers::{Provider, Http, Middleware};
|
||||||
/// use ethers_signers::Wallet;
|
|
||||||
/// use std::{convert::TryFrom, sync::Arc};
|
/// use std::{convert::TryFrom, sync::Arc};
|
||||||
/// use ethers_core::abi::{Detokenize, Token, InvalidOutputType};
|
/// use ethers_core::abi::{Detokenize, Token, InvalidOutputType};
|
||||||
/// # // this is a fake address used just for this example
|
/// # // this is a fake address used just for this example
|
||||||
|
|
|
@ -323,7 +323,6 @@ where
|
||||||
/// use ethers_solc::Solc;
|
/// use ethers_solc::Solc;
|
||||||
/// use ethers_contract::ContractFactory;
|
/// use ethers_contract::ContractFactory;
|
||||||
/// use ethers_providers::{Provider, Http};
|
/// use ethers_providers::{Provider, Http};
|
||||||
/// use ethers_signers::Wallet;
|
|
||||||
/// use std::convert::TryFrom;
|
/// use std::convert::TryFrom;
|
||||||
///
|
///
|
||||||
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
use ethers_contract::{
|
use ethers_contract::{
|
||||||
abigen, ContractFactory, ContractInstance, EthAbiType, EthEvent, LogMeta, Multicall,
|
abigen, ContractFactory, ContractInstance, EthEvent, LogMeta, Multicall, MulticallError,
|
||||||
MulticallError, MulticallVersion,
|
MulticallVersion,
|
||||||
};
|
};
|
||||||
use ethers_core::{
|
use ethers_core::{
|
||||||
abi::{encode, AbiEncode, Token, Tokenizable},
|
abi::{encode, AbiEncode, Token, Tokenizable},
|
||||||
types::{
|
types::{Address, BlockId, Bytes, Filter, ValueOrArray, H160, H256, U256},
|
||||||
transaction::eip712::Eip712, Address, BlockId, Bytes, Filter, ValueOrArray, H160, H256,
|
|
||||||
I256, U256,
|
|
||||||
},
|
|
||||||
utils::{keccak256, Anvil},
|
utils::{keccak256, Anvil},
|
||||||
};
|
};
|
||||||
use ethers_providers::{Http, Middleware, MiddlewareError, Provider, StreamExt};
|
use ethers_providers::{Http, Middleware, MiddlewareError, Provider, StreamExt};
|
||||||
use ethers_signers::{LocalWallet, Signer};
|
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -330,7 +326,6 @@ async fn call_past_hash_test() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[cfg(feature = "abigen")]
|
|
||||||
async fn watch_events() {
|
async fn watch_events() {
|
||||||
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
|
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
|
||||||
let anvil = Anvil::new().spawn();
|
let anvil = Anvil::new().spawn();
|
||||||
|
@ -784,146 +779,3 @@ async fn multicall_aggregate() {
|
||||||
assert_eq!(bytes[..4], keccak256("CustomErrorWithData(string)")[..4]);
|
assert_eq!(bytes[..4], keccak256("CustomErrorWithData(string)")[..4]);
|
||||||
assert_eq!(bytes[4..], encode(&[Token::String("Data".to_string())]));
|
assert_eq!(bytes[4..], encode(&[Token::String("Data".to_string())]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
#[cfg(feature = "eip712")]
|
|
||||||
async fn test_derive_eip712() {
|
|
||||||
use ethers_derive_eip712::*;
|
|
||||||
|
|
||||||
// Generate Contract ABI Bindings
|
|
||||||
abigen!(
|
|
||||||
DeriveEip712Test,
|
|
||||||
"./ethers-contract/tests/solidity-contracts/derive_eip712_abi.json",
|
|
||||||
event_derives(serde::Deserialize, serde::Serialize)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create derived structs
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eip712, EthAbiType)]
|
|
||||||
#[eip712(
|
|
||||||
name = "Eip712Test",
|
|
||||||
version = "1",
|
|
||||||
chain_id = 1,
|
|
||||||
verifying_contract = "0x0000000000000000000000000000000000000001",
|
|
||||||
salt = "eip712-test-75F0CCte"
|
|
||||||
)]
|
|
||||||
struct FooBar {
|
|
||||||
foo: I256,
|
|
||||||
bar: U256,
|
|
||||||
fizz: Bytes,
|
|
||||||
buzz: [u8; 32],
|
|
||||||
far: String,
|
|
||||||
out: Address,
|
|
||||||
}
|
|
||||||
|
|
||||||
// get ABI and bytecode for the DeriveEip712Test contract
|
|
||||||
let (abi, bytecode) = compile_contract("DeriveEip712Test", "DeriveEip712Test.sol");
|
|
||||||
|
|
||||||
// launch the network & connect to it
|
|
||||||
let anvil = Anvil::new().spawn();
|
|
||||||
let from = anvil.addresses()[0];
|
|
||||||
let provider = Provider::try_from(anvil.endpoint())
|
|
||||||
.unwrap()
|
|
||||||
.with_sender(from)
|
|
||||||
.interval(std::time::Duration::from_millis(10));
|
|
||||||
let client = Arc::new(provider);
|
|
||||||
|
|
||||||
let wallet: LocalWallet = anvil.keys()[0].clone().into();
|
|
||||||
|
|
||||||
let factory = ContractFactory::new(abi.clone(), bytecode.clone(), client.clone());
|
|
||||||
|
|
||||||
let contract = factory
|
|
||||||
.deploy(())
|
|
||||||
.expect("failed to deploy DeriveEip712Test contract")
|
|
||||||
.legacy()
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.expect("failed to instantiate factory for DeriveEip712 contract");
|
|
||||||
|
|
||||||
let addr = contract.address();
|
|
||||||
|
|
||||||
let contract = DeriveEip712Test::new(addr, client.clone());
|
|
||||||
|
|
||||||
let foo_bar = FooBar {
|
|
||||||
foo: I256::from(10u64),
|
|
||||||
bar: U256::from(20u64),
|
|
||||||
fizz: b"fizz".into(),
|
|
||||||
buzz: keccak256("buzz"),
|
|
||||||
far: String::from("space"),
|
|
||||||
out: Address::from([0; 20]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let derived_foo_bar = derive_eip_712_test::FooBar {
|
|
||||||
foo: foo_bar.foo,
|
|
||||||
bar: foo_bar.bar,
|
|
||||||
fizz: foo_bar.fizz.clone(),
|
|
||||||
buzz: foo_bar.buzz,
|
|
||||||
far: foo_bar.far.clone(),
|
|
||||||
out: foo_bar.out,
|
|
||||||
};
|
|
||||||
|
|
||||||
let sig = wallet.sign_typed_data(&foo_bar).await.expect("failed to sign typed data");
|
|
||||||
|
|
||||||
let r = <[u8; 32]>::try_from(sig.r)
|
|
||||||
.expect("failed to parse 'r' value from signature into [u8; 32]");
|
|
||||||
let s = <[u8; 32]>::try_from(sig.s)
|
|
||||||
.expect("failed to parse 's' value from signature into [u8; 32]");
|
|
||||||
let v = u8::try_from(sig.v).expect("failed to parse 'v' value from signature into u8");
|
|
||||||
|
|
||||||
let domain_separator = contract
|
|
||||||
.domain_separator()
|
|
||||||
.call()
|
|
||||||
.await
|
|
||||||
.expect("failed to retrieve domain_separator from contract");
|
|
||||||
let type_hash =
|
|
||||||
contract.type_hash().call().await.expect("failed to retrieve type_hash from contract");
|
|
||||||
let struct_hash = contract
|
|
||||||
.struct_hash(derived_foo_bar.clone())
|
|
||||||
.call()
|
|
||||||
.await
|
|
||||||
.expect("failed to retrieve struct_hash from contract");
|
|
||||||
let encoded = contract
|
|
||||||
.encode_eip_712(derived_foo_bar.clone())
|
|
||||||
.call()
|
|
||||||
.await
|
|
||||||
.expect("failed to retrieve eip712 encoded hash from contract");
|
|
||||||
let verify = contract
|
|
||||||
.verify_foo_bar(wallet.address(), derived_foo_bar, r, s, v)
|
|
||||||
.call()
|
|
||||||
.await
|
|
||||||
.expect("failed to verify signed typed data eip712 payload");
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
domain_separator,
|
|
||||||
foo_bar
|
|
||||||
.domain()
|
|
||||||
.expect("failed to return domain_separator from Eip712 implemented struct")
|
|
||||||
.separator(),
|
|
||||||
"domain separator does not match contract domain separator!"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
type_hash,
|
|
||||||
FooBar::type_hash().expect("failed to return type_hash from Eip712 implemented struct"),
|
|
||||||
"type hash does not match contract struct type hash!"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
struct_hash,
|
|
||||||
foo_bar
|
|
||||||
.clone()
|
|
||||||
.struct_hash()
|
|
||||||
.expect("failed to return struct_hash from Eip712 implemented struct"),
|
|
||||||
"struct hash does not match contract struct hash!"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
encoded,
|
|
||||||
foo_bar
|
|
||||||
.encode_eip712()
|
|
||||||
.expect("failed to return domain_separator from Eip712 implemented struct"),
|
|
||||||
"Encoded value does not match!"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(verify, "typed data signature failed!");
|
|
||||||
}
|
|
||||||
|
|
|
@ -659,6 +659,7 @@ pub trait ArtifactOutput {
|
||||||
if let Ok(stripped) = rel_candidate.strip_prefix(artifacts_folder) {
|
if let Ok(stripped) = rel_candidate.strip_prefix(artifacts_folder) {
|
||||||
rel_candidate = stripped.to_path_buf();
|
rel_candidate = stripped.to_path_buf();
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::redundant_clone)] // false positive
|
||||||
let mut candidate = rel_candidate.clone();
|
let mut candidate = rel_candidate.clone();
|
||||||
let contract_file = contract_file.as_ref();
|
let contract_file = contract_file.as_ref();
|
||||||
let mut current_parent = contract_file.parent();
|
let mut current_parent = contract_file.parent();
|
||||||
|
|
|
@ -26,14 +26,7 @@ all-features = true
|
||||||
[features]
|
[features]
|
||||||
default = ["abigen", "rustls"]
|
default = ["abigen", "rustls"]
|
||||||
|
|
||||||
celo = [
|
celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo", "ethers-contract/celo", "ethers-middleware/celo", "legacy"]
|
||||||
"ethers-core/celo",
|
|
||||||
"ethers-providers/celo",
|
|
||||||
"ethers-signers/celo",
|
|
||||||
"ethers-contract/celo",
|
|
||||||
"ethers-middleware/celo",
|
|
||||||
"legacy",
|
|
||||||
]
|
|
||||||
|
|
||||||
legacy = ["ethers-core/legacy", "ethers-contract/legacy"]
|
legacy = ["ethers-core/legacy", "ethers-contract/legacy"]
|
||||||
|
|
||||||
|
@ -43,20 +36,8 @@ eip712 = ["ethers-contract/eip712", "ethers-core/eip712"]
|
||||||
## providers
|
## providers
|
||||||
ws = ["ethers-providers/ws"]
|
ws = ["ethers-providers/ws"]
|
||||||
ipc = ["ethers-providers/ipc"]
|
ipc = ["ethers-providers/ipc"]
|
||||||
rustls = [
|
rustls = ["ethers-middleware/rustls", "ethers-providers/rustls", "ethers-etherscan/rustls", "ethers-contract/rustls", "ethers-solc/rustls"]
|
||||||
"ethers-middleware/rustls",
|
openssl = ["ethers-middleware/openssl", "ethers-providers/openssl", "ethers-etherscan/openssl", "ethers-contract/openssl", "ethers-solc/openssl"]
|
||||||
"ethers-providers/rustls",
|
|
||||||
"ethers-etherscan/rustls",
|
|
||||||
"ethers-contract/rustls",
|
|
||||||
"ethers-solc/rustls",
|
|
||||||
]
|
|
||||||
openssl = [
|
|
||||||
"ethers-middleware/openssl",
|
|
||||||
"ethers-providers/openssl",
|
|
||||||
"ethers-etherscan/openssl",
|
|
||||||
"ethers-contract/openssl",
|
|
||||||
"ethers-solc/openssl",
|
|
||||||
]
|
|
||||||
dev-rpc = ["ethers-providers/dev-rpc"]
|
dev-rpc = ["ethers-providers/dev-rpc"]
|
||||||
## signers
|
## signers
|
||||||
ledger = ["ethers-signers/ledger"]
|
ledger = ["ethers-signers/ledger"]
|
||||||
|
@ -67,9 +48,8 @@ abigen = ["ethers-contract/abigen"]
|
||||||
### abigen without reqwest
|
### abigen without reqwest
|
||||||
abigen-offline = ["ethers-contract/abigen-offline"]
|
abigen-offline = ["ethers-contract/abigen-offline"]
|
||||||
## solc
|
## solc
|
||||||
ethers-solc = ["dep:ethers-solc", "ethers-etherscan/ethers-solc"]
|
solc-full = ["ethers-solc/full"]
|
||||||
solc-full = ["ethers-solc?/full"]
|
solc-tests = ["ethers-solc/tests"]
|
||||||
solc-tests = ["ethers-solc?/tests"]
|
|
||||||
|
|
||||||
# Deprecated
|
# Deprecated
|
||||||
solc-sha2-asm = []
|
solc-sha2-asm = []
|
||||||
|
@ -78,12 +58,14 @@ solc-sha2-asm = []
|
||||||
ethers-addressbook.workspace = true
|
ethers-addressbook.workspace = true
|
||||||
ethers-contract.workspace = true
|
ethers-contract.workspace = true
|
||||||
ethers-core.workspace = true
|
ethers-core.workspace = true
|
||||||
ethers-etherscan.workspace = true
|
ethers-etherscan = { workspace = true, features = ["ethers-solc"] }
|
||||||
ethers-middleware.workspace = true
|
ethers-middleware.workspace = true
|
||||||
ethers-providers.workspace = true
|
ethers-providers.workspace = true
|
||||||
ethers-signers.workspace = true
|
ethers-signers.workspace = true
|
||||||
|
ethers-solc = { workspace = true }
|
||||||
ethers-solc = { workspace = true, optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
serde.workspace = true
|
||||||
tokio = { workspace = true, features = ["macros", "rt"] }
|
tokio = { workspace = true, features = ["macros", "rt"] }
|
||||||
|
ethers-contract = { workspace = true, features = ["eip712"] }
|
||||||
|
ethers-providers = { workspace = true, features = ["rustls"] } # allow https connections
|
||||||
|
|
|
@ -98,7 +98,6 @@ pub use ethers_providers as providers;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use ethers_signers as signers;
|
pub use ethers_signers as signers;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
#[cfg(feature = "ethers-solc")]
|
|
||||||
pub use ethers_solc as solc;
|
pub use ethers_solc as solc;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
|
@ -121,7 +120,6 @@ pub mod prelude {
|
||||||
|
|
||||||
pub use super::signers::*;
|
pub use super::signers::*;
|
||||||
|
|
||||||
#[cfg(feature = "ethers-solc")]
|
|
||||||
pub use super::solc::*;
|
pub use super::solc::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::simple_storage::SimpleStorage;
|
|
||||||
use ethers::prelude::*;
|
use ethers::prelude::*;
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
ethers::contract::abigen!(SimpleStorage, "../testdata/SimpleStorage.json");
|
||||||
|
|
||||||
static CELO_TESTNET_URL: &str = "https://alfajores-forno.celo-testnet.org";
|
static CELO_TESTNET_URL: &str = "https://alfajores-forno.celo-testnet.org";
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
|
@ -0,0 +1,157 @@
|
||||||
|
use ethers::{
|
||||||
|
contract::{abigen, ContractFactory, Eip712, EthAbiType},
|
||||||
|
core::{
|
||||||
|
types::{transaction::eip712::Eip712, Address, Bytes, I256, U256},
|
||||||
|
utils::{keccak256, Anvil},
|
||||||
|
},
|
||||||
|
providers::Provider,
|
||||||
|
signers::LocalWallet,
|
||||||
|
solc::Solc,
|
||||||
|
};
|
||||||
|
use std::{path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_derive_eip712() {
|
||||||
|
// Generate Contract ABI Bindings
|
||||||
|
abigen!(
|
||||||
|
DeriveEip712Test,
|
||||||
|
"./ethers-contract/tests/solidity-contracts/derive_eip712_abi.json",
|
||||||
|
event_derives(serde::Deserialize, serde::Serialize)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create derived structs
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eip712, EthAbiType)]
|
||||||
|
#[eip712(
|
||||||
|
name = "Eip712Test",
|
||||||
|
version = "1",
|
||||||
|
chain_id = 1,
|
||||||
|
verifying_contract = "0x0000000000000000000000000000000000000001",
|
||||||
|
salt = "eip712-test-75F0CCte"
|
||||||
|
)]
|
||||||
|
struct FooBar {
|
||||||
|
foo: I256,
|
||||||
|
bar: U256,
|
||||||
|
fizz: Bytes,
|
||||||
|
buzz: [u8; 32],
|
||||||
|
far: String,
|
||||||
|
out: Address,
|
||||||
|
}
|
||||||
|
|
||||||
|
// get ABI and bytecode for the DeriveEip712Test contract
|
||||||
|
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests");
|
||||||
|
let result = Solc::default().compile_source(path).unwrap();
|
||||||
|
let (abi, bytecode, _) = result
|
||||||
|
.find("DeriveEip712Test")
|
||||||
|
.expect("failed to get DeriveEip712Test contract")
|
||||||
|
.into_parts_or_default();
|
||||||
|
|
||||||
|
// launch the network & connect to it
|
||||||
|
let anvil = Anvil::new().spawn();
|
||||||
|
let from = anvil.addresses()[0];
|
||||||
|
let provider = Provider::try_from(anvil.endpoint())
|
||||||
|
.unwrap()
|
||||||
|
.with_sender(from)
|
||||||
|
.interval(std::time::Duration::from_millis(10));
|
||||||
|
let client = Arc::new(provider);
|
||||||
|
|
||||||
|
let factory = ContractFactory::new(abi.clone(), bytecode.clone(), client.clone());
|
||||||
|
|
||||||
|
let contract = factory
|
||||||
|
.deploy(())
|
||||||
|
.expect("failed to deploy DeriveEip712Test contract")
|
||||||
|
.legacy()
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.expect("failed to instantiate factory for DeriveEip712 contract");
|
||||||
|
|
||||||
|
let addr = contract.address();
|
||||||
|
|
||||||
|
let contract = DeriveEip712Test::new(addr, client.clone());
|
||||||
|
|
||||||
|
let foo_bar = FooBar {
|
||||||
|
foo: I256::from(10u64),
|
||||||
|
bar: U256::from(20u64),
|
||||||
|
fizz: b"fizz".into(),
|
||||||
|
buzz: keccak256("buzz"),
|
||||||
|
far: String::from("space"),
|
||||||
|
out: Address::from([0; 20]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let derived_foo_bar = derive_eip_712_test::FooBar {
|
||||||
|
foo: foo_bar.foo,
|
||||||
|
bar: foo_bar.bar,
|
||||||
|
fizz: foo_bar.fizz.clone(),
|
||||||
|
buzz: foo_bar.buzz,
|
||||||
|
far: foo_bar.far.clone(),
|
||||||
|
out: foo_bar.out,
|
||||||
|
};
|
||||||
|
|
||||||
|
use ethers::signers::Signer;
|
||||||
|
|
||||||
|
let wallet: LocalWallet = anvil.keys()[0].clone().into();
|
||||||
|
let sig = wallet.sign_typed_data(&foo_bar).await.expect("failed to sign typed data");
|
||||||
|
|
||||||
|
let r = <[u8; 32]>::try_from(sig.r)
|
||||||
|
.expect("failed to parse 'r' value from signature into [u8; 32]");
|
||||||
|
let s = <[u8; 32]>::try_from(sig.s)
|
||||||
|
.expect("failed to parse 's' value from signature into [u8; 32]");
|
||||||
|
let v = u8::try_from(sig.v).expect("failed to parse 'v' value from signature into u8");
|
||||||
|
|
||||||
|
let domain_separator = contract
|
||||||
|
.domain_separator()
|
||||||
|
.call()
|
||||||
|
.await
|
||||||
|
.expect("failed to retrieve domain_separator from contract");
|
||||||
|
let type_hash =
|
||||||
|
contract.type_hash().call().await.expect("failed to retrieve type_hash from contract");
|
||||||
|
let struct_hash = contract
|
||||||
|
.struct_hash(derived_foo_bar.clone())
|
||||||
|
.call()
|
||||||
|
.await
|
||||||
|
.expect("failed to retrieve struct_hash from contract");
|
||||||
|
let encoded = contract
|
||||||
|
.encode_eip_712(derived_foo_bar.clone())
|
||||||
|
.call()
|
||||||
|
.await
|
||||||
|
.expect("failed to retrieve eip712 encoded hash from contract");
|
||||||
|
let verify = contract
|
||||||
|
.verify_foo_bar(wallet.address(), derived_foo_bar, r, s, v)
|
||||||
|
.call()
|
||||||
|
.await
|
||||||
|
.expect("failed to verify signed typed data eip712 payload");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
domain_separator,
|
||||||
|
foo_bar
|
||||||
|
.domain()
|
||||||
|
.expect("failed to return domain_separator from Eip712 implemented struct")
|
||||||
|
.separator(),
|
||||||
|
"domain separator does not match contract domain separator!"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
type_hash,
|
||||||
|
FooBar::type_hash().expect("failed to return type_hash from Eip712 implemented struct"),
|
||||||
|
"type hash does not match contract struct type hash!"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
struct_hash,
|
||||||
|
foo_bar
|
||||||
|
.clone()
|
||||||
|
.struct_hash()
|
||||||
|
.expect("failed to return struct_hash from Eip712 implemented struct"),
|
||||||
|
"struct hash does not match contract struct hash!"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
encoded,
|
||||||
|
foo_bar
|
||||||
|
.encode_eip712()
|
||||||
|
.expect("failed to return domain_separator from Eip712 implemented struct"),
|
||||||
|
"Encoded value does not match!"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(verify, "typed data signature failed!");
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
//! Ethers live tests.
|
|
||||||
//!
|
|
||||||
//! If a feature or external binary is added, like Solc, please also update
|
|
||||||
//! `.github/workflows/ci.yml` at `job.live-test`.
|
|
||||||
|
|
||||||
#![cfg(not(target_arch = "wasm32"))]
|
|
||||||
|
|
||||||
#[cfg(feature = "celo")]
|
|
||||||
mod celo;
|
|
||||||
|
|
||||||
pub(crate) mod simple_storage {
|
|
||||||
ethers::contract::abigen!(SimpleStorage, "../testdata/SimpleStorage.json");
|
|
||||||
}
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
//! Ethers integration tests.
|
||||||
|
#![cfg(not(target_arch = "wasm32"))]
|
||||||
|
|
||||||
|
#[cfg(feature = "celo")]
|
||||||
|
mod celo;
|
||||||
|
|
||||||
|
mod eip712;
|
|
@ -13,7 +13,7 @@ default = ["legacy"]
|
||||||
legacy = ["ethers/legacy"]
|
legacy = ["ethers/legacy"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ethers = { workspace = true, features = ["abigen", "ethers-solc", "rustls", "ws"] }
|
ethers = { workspace = true, features = ["abigen", "rustls", "ws"] }
|
||||||
|
|
||||||
tokio = { workspace = true, features = ["macros"] }
|
tokio = { workspace = true, features = ["macros"] }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue