fix(abigen): ensure correct ABI in `From` impl (#2036)
* fix(abigen): ensure correct ABI in `From` impl `new` creates a `Contract` with the correct ABI, but the `From` impl simply wraps the source `Contract`, which could have a completely different ABI. In effect this was an unsafe cast, and indeed was observed to trigger a "method not found (this should never happen)" panic for subsequent method lookups. Implementing `From` in terms of `new` fixes this, at the cost of an extra `Arc::clone()` (which I can't see how to eliminate without piercing the `ethers::contract::Contract` public API). * Remove unnecessary `async` from test Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
This commit is contained in:
parent
79f27e2366
commit
9e559aefeb
|
@ -150,7 +150,7 @@ impl Context {
|
||||||
/// client at the given `Address`. The contract derefs to a `ethers::Contract`
|
/// client at the given `Address`. The contract derefs to a `ethers::Contract`
|
||||||
/// object
|
/// object
|
||||||
pub fn new<T: Into<#ethers_core::types::Address>>(address: T, client: ::std::sync::Arc<M>) -> Self {
|
pub fn new<T: Into<#ethers_core::types::Address>>(address: T, client: ::std::sync::Arc<M>) -> Self {
|
||||||
#ethers_contract::Contract::new(address.into(), #abi_name.clone(), client).into()
|
Self(#ethers_contract::Contract::new(address.into(), #abi_name.clone(), client))
|
||||||
}
|
}
|
||||||
|
|
||||||
#deployment_methods
|
#deployment_methods
|
||||||
|
@ -163,7 +163,7 @@ impl Context {
|
||||||
|
|
||||||
impl<M : #ethers_providers::Middleware> From<#ethers_contract::Contract<M>> for #name<M> {
|
impl<M : #ethers_providers::Middleware> From<#ethers_contract::Contract<M>> for #name<M> {
|
||||||
fn from(contract: #ethers_contract::Contract<M>) -> Self {
|
fn from(contract: #ethers_contract::Contract<M>) -> Self {
|
||||||
Self(contract)
|
Self::new(contract.address(), contract.client())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -750,3 +750,21 @@ fn can_handle_overloaded_function_with_array() {
|
||||||
]"#,
|
]"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_uses_correct_abi() {
|
||||||
|
abigen!(
|
||||||
|
Foo, r#"[function foo()]"#;
|
||||||
|
Bar, r#"[function bar()]"#;
|
||||||
|
);
|
||||||
|
|
||||||
|
let provider = Arc::new(Provider::new(MockProvider::new()));
|
||||||
|
let foo = Foo::new(Address::default(), Arc::clone(&provider));
|
||||||
|
|
||||||
|
let contract: ðers_contract::Contract<_> = &foo;
|
||||||
|
let bar: Bar<Provider<MockProvider>> = contract.clone().into();
|
||||||
|
|
||||||
|
// Ensure that `bar` is using the `Bar` ABI internally (this method lookup will panic if `bar`
|
||||||
|
// is incorrectly using the `Foo` ABI internally).
|
||||||
|
bar.bar().call();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue