rkalis/truffle-plugin-verify

Verifying contracts with structs in external file

Closed this issue · 8 comments

Hi there!

I'm facing the issue with source code verification in case when structs are placed in a separate file (it is allowed since 0.6.0 version of Solidity compiler) and then imported where needed. In debug mode, I found out that imported structs are not added in the flattened source code. Thus, the code cannot be compiled on Etherscan side.

Hey @sobolev-igor, that is interesting. @RyuuGan, is this something that could be added to sol-merger for Solidity v0.6.0 support?

Can you send me an example of the source code, just a small reproduction

Hi! I'm really sorry I haven't answered for so long!

This is a test repo https://github.com/sobolev-igor/test where you can do
npx truffle migrate --network kovan
then
npx truffle run verify Test --network kovan --debug
and see that Bug struct is not added to the source code.

By the way, I think that currently the best way for verification is Standard-Json-Input. In this case, as I understand, you don't have to resolve imports.

Can you test that it is working now ? sol-merger@3.0.0

I updated the grammar, so it should support structs and enums and also new syntax.

Best regards

I tested this out and confirmed that the source code is merged correctly with the new sol-merger, thanks @RyuuGan!

But now I'm running into a different issue related to Etherscan. If I copy-paste the merged code into the verify web tool, it works, but if I use truffle-plugin-verify or the Etherscan API demo, it doesn't work. So it seems to me like there's a discrepancy between the online tool and the Etherscan API.

@mtbitcoin, is that something you guys can look into? The reproduction repo is included in @sobolev-igor's comment above. I tested it against the most recent version of truffle-plugin-verify, v0.3.11. This is the data that was used in the API request:

{
  "apikey": "<redacted>",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0x89307b0aC366b907Fc5A67C180C633FCad25eBE4",
  "sourceCode": "pragma solidity 0.6.4;\npragma experimental ABIEncoderV2;\n\n\nstruct Bug {\n    uint256 num;\n    string str;\n}\n\ncontract Test {\n    function foo() external view returns (Bug memory) {\n        return Bug({\n            num: 123,\n            str: \"123\"\n        });\n    }\n}",
  "codeformat": "solidity-single-file",
  "contractname": "Test",
  "compilerversion": "v0.6.4+commit.1dca32f3",
  "optimizationUsed": 1,
  "runs": 200,
  "constructorArguements": ""
}

Hey @rkalis thanks for tagging us - Cracking on it. Indeed we have implemented support for this a couple weeks back, maybe I've missed something on the API end.

Will report back.

Hey @rkalis - Sorry it took a while this week!

I've managed to get the contract verified via our sourcedemo with a little adjustment (on Ropsten: https://ropsten.etherscan.io/address/0xA714Feb4c17fC12194D01651e58d3DA4768Aecd5#code) - Bringing the ABIEncoderV2 pragma to the top so it comes before the version pragma:

pragma experimental ABIEncoderV2;
pragma solidity 0.6.4;


struct Bug {
    uint256 num;
    string str;
}

contract Test {
    function foo() external view returns (Bug memory) {
        return Bug({
            num: 123,
            str: "123"
        });
    }
}

Could I trouble you to give it another shot with this change to see if it works out, please? 🙏

It's one of those small undocumented quirks which I've been wanting to spend some time to look into for a while now - I'll pull up some time for it. In the meantime, making sure the ABIEncoderV2 comes before the version pragma should sort things out.

Sorry for the trouble! And as always thanks for the report.

Hey @Enigmatic331, thanks for the reply. I've confirmed that it works with the ABIEncoderV2 pragma on top. I'll add a note to the README about this for now and consider this issue fixed. Thanks for the great work @RyuuGan and @Enigmatic331!