Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

abigen is intolerant of duplicate names with different casing #571

Closed
casualjim opened this issue Nov 11, 2021 · 7 comments · Fixed by #650
Closed

abigen is intolerant of duplicate names with different casing #571

casualjim opened this issue Nov 11, 2021 · 7 comments · Fixed by #650
Labels
bug Something isn't working

Comments

@casualjim
Copy link
Contributor

Version
https://github.com/gakonst/ethers-rs#906c504f

Platform
linux

Description
Abigen is intolerant of identifiers that have the same name but differ in casing.

For example the names index and INDEX both appear in the sOHM contract: 0x04f2694c8fcee23e8fd0dfea1d4f5bb8c352111f

I tried this code:

Abigen::new(
    "StakedOHM",
    "https://etherscan.io/address/0x04f2694c8fcee23e8fd0dfea1d4f5bb8c352111f",
  )
  .unwrap()
  .generate()
  .unwrap()
  .write_to_file("src/contracts/staked_ohm.rs")
  .unwrap();

I expected to see this happen: the generated code compiles

Instead, this happened:

error[E0201]: duplicate definitions with name `index`:
   --> src/contracts/staked_ohm.rs:153:5
    |
51  | /     pub fn index(&self) -> ethers::contract::builders::ContractCall<M, ethers::core::types::U256> {
52  | |       self
53  | |         .0
54  | |         .method_hash([45, 247, 92, 177], ())
55  | |         .expect("method not found (this should never happen)")
56  | |     }
    | |_____- previous definition of `index` here
...
153 | /     pub fn index(&self) -> ethers::contract::builders::ContractCall<M, ethers::core::types::U256> {
154 | |       self
155 | |         .0
156 | |         .method_hash([41, 134, 192, 229], ())
157 | |         .expect("method not found (this should never happen)")
158 | |     }
    | |_____^ duplicate definition
@casualjim casualjim added the bug Something isn't working label Nov 11, 2021
@mattsse
Copy link
Collaborator

mattsse commented Nov 11, 2021

Nice catch, this is similar to #548 and should be fixed with the same approach.

In the meantime, you should be able to prevent this with methods field like

abigen!(StakedOHM,
    "https://etherscan.io/address/0x04f2694c8fcee23e8fd0dfea1d4f5bb8c352111f",
    methods {
        INDEX() as alias_for_this_function_name;
    }
);

Or in your case, since you use the builder use the Abigen::add_method_alias function

@gakonst
Copy link
Owner

gakonst commented Dec 5, 2021

@casualjim could you please check that the issue is no longer present in master?

@casualjim
Copy link
Contributor Author

There is progress: different error, but still an issue:

error[E0428]: the name `IndexCall` is defined multiple times
 --> src/contracts/ethereum/mod.rs:3:3
  |
3 | /   abigen!(
4 | |     StakedOHM,
5 | |     "./abi/staked_ohm.json",
6 | |     event_derives(serde::Deserialize, serde::Serialize)
7 | |   );
  | |    ^
  | |    |
  | |____`IndexCall` redefined here
  |      previous definition of the type `IndexCall` here
  |
  = note: `IndexCall` must be defined only once in the type namespace of this module
  = note: this error originates in the macro `abigen` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0428]: the name `Index` is defined multiple times
 --> src/contracts/ethereum/mod.rs:3:3
  |
3 | /   abigen!(
4 | |     StakedOHM,
5 | |     "./abi/staked_ohm.json",
6 | |     event_derives(serde::Deserialize, serde::Serialize)
7 | |   );
  | |    ^
  | |    |
  | |____`Index` redefined here
  |      previous definition of the type `Index` here
  |
  = note: `Index` must be defined only once in the type namespace of this enum
  = note: this error originates in the macro `abigen` (in Nightly builds, run with -Z macro-backtrace for more info)

@mattsse
Copy link
Collaborator

mattsse commented Dec 6, 2021

@casualjim
hmm, could not reproduce with master, as

    abigen!(
        StakedOHM,
        "etherscan:0x04f2694c8fcee23e8fd0dfea1d4f5bb8c352111f"
    );

compiles and generates

fn index()
fn INDEX()

did you update with cargo update -p ethers?

@gakonst
Copy link
Owner

gakonst commented Dec 6, 2021

@casualjim what's the exact ABI you're using?

@casualjim
Copy link
Contributor Author

I did update to master, I verified the commit hashes after running cargo update

I think maybe some local cache needed to be invalidated.

It works now! And it appears that the etherscan stuff now also works again.

@casualjim
Copy link
Contributor Author

@casualjim what's the exact ABI you're using?

I used a downloaded version, because when I was trying this there was an issue with downloading from etherscan through ethers.

I used a json structure like this:

[
  {
    "network": "ethereum",
    "symbol": "sOHM",
    "typeName": "StakedOHM",
    "filename": "staked_ohm",
    "address": "0x04f2694c8fcee23e8fd0dfea1d4f5bb8c352111f"
  },
]

in combination with this download script:

set -eu -o pipefail

declare -A explorers=( ["ethereum"]="etherscan.io" ["polygon"]="polygonscan.com" ["avalanche"]="snowtrace.io" )
declare -A apikeys=( ["ethereum"]="$ETHERSCAN_API_KEY" ["polygon"]="$POLYGONSCAN_API_KEY" ["avalanche"]="$SNOWTRACE_API_KEY" )

download::abi() {
  local explorer
  local filename
  local address
  local network

  network="$(jq -r .network <<< "$1")"
  explorer="${explorers[$network]}"
  address="$(jq -r .address <<< "$1")"
  filename="$(jq -r .filename <<< "$1")"

  >&2 echo "downloading $(jq -r .typeName <<< "$1") $(jq -r .network <<< "$1") ABI"

  url="https://api.${explorer}/api?"
  url="${url}module=contract&action=getabi"
  url="${url}&address=${address}"
  url="${url}&apikey=${apikeys[$network]}"
  curl -LSs "${url}" | jq -r .result | jq > "abi/${filename}.json"
}

main() {
  readarray -t contracts < <(jq -c '.[]' ./contractdeps.json)
  for item in "${contracts[@]}"; do
    download::abi "$item"
  done
}

main "$@"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants