gakonst / ethers-rs

Complete Ethereum & Celo library and wallet implementation in Rust. https://docs.rs/ethers
Apache License 2.0
2.5k stars 795 forks source link

`abigen!` fails with confusing error on solidity output #476

Closed petertdavies closed 3 years ago

petertdavies commented 3 years ago

Version

└── ethers v0.5.3
    ├── ethers-contract v0.5.3
    │   ├── ethers-contract-abigen v0.5.3
    │   │   ├── ethers-core v0.5.4
    │   ├── ethers-contract-derive v0.5.3
    │   │   ├── ethers-contract-abigen v0.5.3 (*)
    │   │   ├── ethers-core v0.5.4 (*)
    │   ├── ethers-core v0.5.4 (*)
    │   ├── ethers-providers v0.5.4
    │   │   ├── ethers-core v0.5.4 (*)
    ├── ethers-core v0.5.4 (*)
    ├── ethers-middleware v0.5.3
    │   ├── ethers-contract v0.5.3 (*)
    │   ├── ethers-core v0.5.4 (*)
    │   ├── ethers-providers v0.5.4 (*)
    │   ├── ethers-signers v0.5.3
    │   │   ├── ethers-core v0.5.4 (*)
    ├── ethers-providers v0.5.4 (*)
    └── ethers-signers v0.5.3 (*)

Platform

Linux 5.4.0-81-generic #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

The bug

The abigen! macro fails with the confusing error: Illegal abi `{`, when called on the output of the solidity compiler (rather than just the abi). Here is a minimal example.

use ethers::prelude::*;

abigen!(
    Foo,
    "npm:@openzeppelin/contracts@2.5.0/build/contracts/IERC20.json"
);

fn main() {
    println!("Hello, world!");
}

The reason

The output of the solidity compiler isn't just the abi in JSON format, it is a larger JSON object with an abi key containing the abi. When the abi parser attempts to parse this it fails, falling back to the human readable parser which then fails with error: Illegal abi `{`.

It would be nice if we could support both formats.

mattsse commented 3 years ago

You're probably right, I also suspect that this happens because abigen! expects the abi object as root of the json like contract_abi.json this is not the case for builds like openzeppelin: https://npm.runkit.com/@openzeppelin/contracts/build/contracts/IERC20.json?t=1632833791195 So we probably need to account for that when decoding from npm.

gakonst commented 3 years ago

Ugh I was sort of opinionated on not parsing the artifacts, but that seems inevitable given that OZ has published packages like that. We should add that.