Abstract
Many developers flatten contracts to verify, we need support for easy multifile verification on block explorers. To do this we need the ecosystem to support.
Previously discussed indirectly: https://github.com/ethereum/solidity/issues/8989
Originally posted as issue: https://github.com/ethereum/solidity/issues/9650
Motivation
There is a community expectation that code controlling any value will be verified on block explorers.
Etherscan verify API currently only supports flattened files
from: https://etherscan.io/apis#contracts
Contracts that use "imports" will need to have the code concatenated into one file as we do not support "imports" in separate files. You can try using the Blockcat solidity-flattener or SolidityFlattery
This means that many developers flatten their contracts to verify.
Flattening with SPDX License Identifiers is now a problem as developers either need to ensure that they use a single compatible license otherwise they could be changing/removing the license of third party code that they are importing.
Etherscan web interface supports multiple files but the files have to be in a single directory and the imports changed so that the imports use a single directory.
Raising awareness of the problem so that we can solve for the ecosystem.
If we could make multifile verification easy for all developers then there would no longer be a need to flatten.
A short term workaround could be a tool that copies a contract and it's dependencies to a single directory and updates the imports to be local to the directory. This would enable use of Etherscans web based verification.
Though long term we need deploy tools to verify to block explorers and/or sourcify via APIs automagically.
Unfortunately the community will still flatten contracts until we have easy multifile verification.
Example
The following simple ERC20 token inheriting from the OpenZeppelin Contracts ERC20 implementation was deployed to Rinkeby using Truffle.
SimpleToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/**
* @title SimpleToken
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions.
*/
contract SimpleToken is ERC20 {
/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
constructor () public ERC20("Simple Token", "SIM") {
_mint(msg.sender, 1000000 * (10 ** uint256(decimals())));
}
}
To verify as multifile, the SimpleToken.sol contract along with the five imported contracts had to be placed in a single directory, copying the required contracts from node_modules/@openzeppelin/contracts
and then modifying any imports whether relative or from @openzeppelin/contracts
to be relative to a single directory.
The contract could then be verified uploading the files from the one directory:
1) Address.sol | | (6078 Bytes)
2) Context.sol | | (933 Bytes)
3) ERC20.sol | | (10765 Bytes)
4) IERC20.sol | | (2696 Bytes)
5) SafeMath.sol | | (5201 Bytes)
6) SimpleToken.sol | | (559 Bytes)
The end result is the six contracts being verified, but the contracts still had to have their imports modified, so they are not the exact same text as what was used to compile/deploy.
https://rinkeby.etherscan.io/address/0xd43C0a135F36A8D8a3961d3d56BdCccD47CBD319#code
Compare with the process of flattening (or even using a tool that connects to the API) - except for the issue of multiple SPDX License identifiers since Solidity 0.6.8
$ npx truffle-flattener ./contracts/SimpleToken.sol > ./FlatSimpleToken.sol
npx: installed 64 in 13.339s