wighawag / hardhat-deploy

hardhat deployment plugin
MIT License
1.19k stars 292 forks source link

Verification of libraries with linked libraries fail #253

Open tuler opened 2 years ago

tuler commented 2 years ago

Describe the bug The request to etherscan to verify libraries with linked libraries fail. Etherscan cannot resolve linked libraries from the payload the plugin is sending, following the solidity-standard-json-input format.

To Reproduce Created a project that reproduces the issue: https://github.com/tuler/hardhat-deploy-etherscan-library

The project have two libraries, Math and Util, both already deployed to goerli. Library A is already verified successfully. Library B links to library A, but verification fails, following this command:

npx hardhat --network goerli etherscan-verify --api-key <etherscan_api_key>

Expected behavior Library should verify.

versions

Additional context The hardhat etherscan plugin works well. Details in the repo README.

wighawag commented 2 years ago

Is that not an issue with etherscan ? Or do you see a way to solve it client-side ?

tuler commented 2 years ago

I agree with you that it looks like a etherscan bug. I'd dig deeper but unfortunately etherscan it not open source :-(

The fact is that @nomiclabs/hardhat-etherscan works, and it's because of the way it's building the libraries section of solidity-standard-json-input.

My example project has the following contracts: Math (library) Util (library links to Math) Greeter (links Util)

So it's Math -> Util -> Greeter

I captured all sourceCode payloads sent to etherscan by both hardhat-deploy and @nomiclabs/hardhat-etherscan and committed them.

The bottom line is that for the Util library hardhat-deploy is sending:

    "libraries": {
      "contracts/Util.sol:Util": {
        "Math": "0x155249849d1c0640DA809a8c7C4C4c9cd7b3bde3"
      }
    },

while @nomiclabs/hardhat-etherscan is sending:

  "libraries": {
    "contracts/Math.sol": {
      "Math": "0x155249849d1c0640da809a8c7c4c4c9cd7b3bde3"
    }

The documentation of solidity says:

    "libraries": {
      // The top level key is the the name of the source file where the library is used.
      "myFile.sol": {
        "MyLib": "0x123123..."
      }
    }
tuler commented 2 years ago

Maybe some experienced hardhat developer can shine some light on why this. @fvictorio

wighawag commented 2 years ago

Thanks @tuler for the detailed info.

re solidity , hardhat-deploy actually use exactly what is provided by solidity, see : https://github.com/wighawag/hardhat-deploy/blob/6080f5195ffec34691629ca7a01020c3ef81cee3/src/etherscan.ts#L308-L316

So I guess etherscan is expecting something different. Feels weird that the key would not be where the file where library is used though (What hardhat-etherscan is using) But maybe etherscan is ignoring this alltogether and the issue could be the :Util ?

tuler commented 2 years ago

But maybe etherscan is ignoring this alltogether and the issue could be the :Util ?

I tried verifying without the :Util.

    "libraries": {
-      "contracts/Util.sol:Util": {
+      "contracts/Util.sol": {
        "Math": "0x8977457936461132c9c7abD3735bA6f3B6E7ef29"
      }
    },

Still fails.

fvictorio commented 2 years ago

Hey @tuler, sorry for not responding sooner.

I took a look into this and sadly I haven't found anything too useful to share. For the time being, the only thing I can say is that the settings thing seems like an error on our side, but an error that it's not relevant for the verification. (Just a guess).

What I would do is to intercept the full JSON object that is sent to Etherscan in both scenarios, and to compare that. Your repo only seems to include the solc input. There's a chance that the problem is with hardhat-deploy not sending the libraryname1/libraryaddress1 part of the payload. Again, just guessing, but it would be useful to investigate that.

Btw, I have to say: this is a fantastic issue report and a great reproduction repo, I wish all issues were like this :smile:

tuler commented 2 years ago

@fvictorio I committed the payloads.

https://github.com/tuler/hardhat-deploy-etherscan-library/blob/master/payload/goerli/hardhat-deploy/Util.json https://github.com/tuler/hardhat-deploy-etherscan-library/blob/master/payload/goerli/hardhat-etherscan/Util.json

The difference is really how the library is specified in the sourceCode, as I said above at https://github.com/wighawag/hardhat-deploy/issues/253#issuecomment-1010307855

ps: libraryname1/libraryaddress1 is not part of payload, because this is a solidity-standard-json-input payload.

tuler commented 2 years ago

Any news about this? @fvictorio @wighawag

wighawag commented 2 years ago

@tuler I had a quick look the other day to have the libraries field setup like hardhat-etherscan does but :

It might be worth trying to give the input to solc directly and see what it says. Maybe it is an issue on etherscan and should be fixed there

tuler commented 2 years ago

@wighawag I understand, etherscan API is kind of sloppy, I would't be surprised if the problem is on their end. But communication is very hard.

One possibility I tried, but for now failed, was to create another plugin that uses both @nomiclabs/hardhat-etherscan and hardhat-deploy. I wanted to call hardhat-deploy API to read deployment information (addresses, args, library links), and then call @nomiclabs/hardhat-etherscan to do the actual verification.

But it did not work well, because @nomiclabs/hardhat-etherscan goes directly to its own API to get build artifacts, instead of going through hardhat-deploy APIs, for example to support external artifacts, which we use a lot. So it fails because it does not find artifacts, because they are external.

Maybe there is some design change to @nomiclabs/hardhat-etherscan that allow would custom artifact resolvers to hook in its internal processing. @fvictorio

tuler commented 8 months ago

I updated my example project at https://github.com/tuler/hardhat-deploy-etherscan-library and can confirm that the issue still exists.

wighawag commented 8 months ago

Thanks @tuler for this info Unfortunately, my comment above still stand : https://github.com/wighawag/hardhat-deploy/issues/253#issuecomment-1063836697

So until I know what etherscan is doing, or why hardhat is doing this workaround, I won't change the way it works for now.

it looks to me that Etherscan is doing something wrong and the extra complexity involved to make them happy is not worth it, unless I can reuse what hardhat is doing, @fvictorio ?