feat: adds bscscan as abi source (#1955)

This commit is contained in:
Genysys 2022-12-19 19:54:24 +04:00 committed by GitHub
parent bb4af1c134
commit 91cd6ccce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 2 deletions

View File

@ -3,7 +3,7 @@
## ethers-core ## ethers-core
### Unreleased ### Unreleased
-
- Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815) - Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815)
- `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers. - `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers.
- An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract. - An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract.

View File

@ -20,6 +20,9 @@ pub enum Source {
/// An ABI to be retrieved over HTTP(S). /// An ABI to be retrieved over HTTP(S).
Http(Url), Http(Url),
/// An address of a mainnet contract that has been verified on Bscscan.com.
Bscscan(Address),
/// An address of a mainnet contract that has been verified on Etherscan.io. /// An address of a mainnet contract that has been verified on Etherscan.io.
Etherscan(Address), Etherscan(Address),
@ -54,7 +57,12 @@ impl Source {
/// ///
/// - `etherscan:0xXX..XX` or `https://etherscan.io/address/0xXX..XX`: a address or URL of a /// - `etherscan:0xXX..XX` or `https://etherscan.io/address/0xXX..XX`: a address or URL of a
/// verified contract on Etherscan. /// verified contract on Etherscan.
/// /// - `bscscan:0xXX..XX` or `https://bscscan.io/address/0xXX..XX`: a address or URL of a
/// verified contract on Bscscan.
/// - `polygonscan:0xXX..XX` or `https://polygonscan.io/address/0xXX..XX`: a address or URL of a
/// verified contract on Polygonscan.
/// - `snowtrace:0xXX..XX` or `https://snowtrace.io/address/0xXX..XX`: a address or URL of a
/// verified contract on Snowtrace.
/// - `npm:@org/package@1.0.0/path/to/contract.json` an npmjs package with an optional version /// - `npm:@org/package@1.0.0/path/to/contract.json` an npmjs package with an optional version
/// and path (defaulting to the latest version and `index.js`). The contract ABI will be /// and path (defaulting to the latest version and `index.js`). The contract ABI will be
/// retrieved through `unpkg.io`. /// retrieved through `unpkg.io`.
@ -99,6 +107,12 @@ impl Source {
match url.scheme() { match url.scheme() {
"file" => Ok(Source::local(source)), "file" => Ok(Source::local(source)),
"http" | "https" => match url.host_str() { "http" | "https" => match url.host_str() {
Some("bscscan.com") => Source::etherscan(
url.path()
.rsplit('/')
.next()
.ok_or_else(|| eyre!("HTTP URL does not have a path"))?,
),
Some("etherscan.io") => Source::etherscan( Some("etherscan.io") => Source::etherscan(
url.path() url.path()
.rsplit('/') .rsplit('/')
@ -119,6 +133,7 @@ impl Source {
), ),
_ => Ok(Source::Http(url)), _ => Ok(Source::Http(url)),
}, },
"bscscan" => Source::bscscan(url.path()),
"etherscan" => Source::etherscan(url.path()), "etherscan" => Source::etherscan(url.path()),
"polygonscan" => Source::polygonscan(url.path()), "polygonscan" => Source::polygonscan(url.path()),
"snowtrace" => Source::snowtrace(url.path()), "snowtrace" => Source::snowtrace(url.path()),
@ -140,6 +155,16 @@ impl Source {
Ok(Source::Http(Url::parse(url.as_ref())?)) Ok(Source::Http(Url::parse(url.as_ref())?))
} }
/// Creates an Bscscan source from an address string.
pub fn bscscan<S>(address: S) -> Result<Self>
where
S: AsRef<str>,
{
let address =
util::parse_address(address).context("failed to parse address for Bscscan source")?;
Ok(Source::Bscscan(address))
}
/// Creates an Etherscan source from an address string. /// Creates an Etherscan source from an address string.
pub fn etherscan<S>(address: S) -> Result<Self> pub fn etherscan<S>(address: S) -> Result<Self>
where where
@ -187,6 +212,7 @@ impl Source {
match self { match self {
Source::Local(path) => get_local_contract(path), Source::Local(path) => get_local_contract(path),
Source::Http(_) => panic!("Http abi location are not supported for wasm"), Source::Http(_) => panic!("Http abi location are not supported for wasm"),
Source::Bscscan(_) => panic!("Bscscan abi location are not supported for wasm"),
Source::Etherscan(_) => panic!("Etherscan abi location are not supported for wasm"), Source::Etherscan(_) => panic!("Etherscan abi location are not supported for wasm"),
Source::Polygonscan(_) => panic!("Polygonscan abi location are not supported for wasm"), Source::Polygonscan(_) => panic!("Polygonscan abi location are not supported for wasm"),
Source::Snowtrace(_) => panic!("Snowtrace abi location are not supported for wasm"), Source::Snowtrace(_) => panic!("Snowtrace abi location are not supported for wasm"),
@ -197,6 +223,7 @@ impl Source {
match self { match self {
Source::Local(path) => get_local_contract(path), Source::Local(path) => get_local_contract(path),
Source::Http(url) => get_http_contract(url), Source::Http(url) => get_http_contract(url),
Source::Bscscan(address) => get_etherscan_contract(*address, "bscscan.com"),
Source::Etherscan(address) => get_etherscan_contract(*address, "etherscan.io"), Source::Etherscan(address) => get_etherscan_contract(*address, "etherscan.io"),
Source::Polygonscan(address) => get_etherscan_contract(*address, "polygonscan.com"), Source::Polygonscan(address) => get_etherscan_contract(*address, "polygonscan.com"),
Source::Snowtrace(address) => get_etherscan_contract(*address, "snowtrace.io"), Source::Snowtrace(address) => get_etherscan_contract(*address, "snowtrace.io"),
@ -261,6 +288,7 @@ fn get_etherscan_contract(address: Address, domain: &str) -> Result<String> {
// probably don't reference anything when deploying on other networks. // probably don't reference anything when deploying on other networks.
let api_key = { let api_key = {
let key_res = match domain { let key_res = match domain {
"bscscan.com" => env::var("BSCSCAN_API_KEY").ok(),
"etherscan.io" => env::var("ETHERSCAN_API_KEY").ok(), "etherscan.io" => env::var("ETHERSCAN_API_KEY").ok(),
"polygonscan.com" => env::var("POLYGONSCAN_API_KEY").ok(), "polygonscan.com" => env::var("POLYGONSCAN_API_KEY").ok(),
"snowtrace.io" => env::var("SNOWTRACE_API_KEY").ok(), "snowtrace.io" => env::var("SNOWTRACE_API_KEY").ok(),
@ -311,6 +339,10 @@ mod tests {
"https://my.domain.eth/path/to/Contract.json", "https://my.domain.eth/path/to/Contract.json",
Source::http("https://my.domain.eth/path/to/Contract.json").unwrap(), Source::http("https://my.domain.eth/path/to/Contract.json").unwrap(),
), ),
(
"bscscan:0x0001020304050607080910111213141516171819",
Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(),
),
( (
"etherscan:0x0001020304050607080910111213141516171819", "etherscan:0x0001020304050607080910111213141516171819",
Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(), Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(),
@ -323,6 +355,10 @@ mod tests {
"snowtrace:0x0001020304050607080910111213141516171819", "snowtrace:0x0001020304050607080910111213141516171819",
Source::snowtrace("0x0001020304050607080910111213141516171819").unwrap(), Source::snowtrace("0x0001020304050607080910111213141516171819").unwrap(),
), ),
(
"https://bscscan.io/address/0x0001020304050607080910111213141516171819",
Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(),
),
( (
"https://etherscan.io/address/0x0001020304050607080910111213141516171819", "https://etherscan.io/address/0x0001020304050607080910111213141516171819",
Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(), Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(),