ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
23.29k stars 5.77k forks source link

Failed to verify contract with v0.5.12+commit.7709ece9.Windows.msvc #8818

Closed FabianSchuessler closed 4 years ago

FabianSchuessler commented 4 years ago

Description

I failed to validate several contracts. I will use Dai as an example: https://etherscan.io/address/0x6b175474e89094c44da98b954eedeac495271d0f#code

Environment

Steps to Reproduce

  1. Step: Get source code from https://etherscan.io/address/0x6b175474e89094c44da98b954eedeac495271d0f#code
  2. Step: Use v0.5.12+commit.7709ece9.Windows.msvc: solc Dai.sol --bin --abi -o ./ --overwrite --optimize-runs=200
  3. Step: Use web3j-4.0.1: web3j solidity generate -a=...\Dai.abi -b=...\Dai.bin -o=... -p=...
  4. Step: Execute contract.isContractValid(): this.contractBinary.contains(code) is false in Contract.class

I tried Step 1 with https://github.com/makerdao/dss/blob/master/src/dai.sol but still failed. I tried Step 2 with https://remix.ethereum.org/#optimize=false&evmVersion=null&version=soljson-v0.5.12+commit.7709ece9.js but still failed.

Any ideas?

I succeeded in verifying WETH9, maybe it was something to do with multiple contracts in one file?

chriseth commented 4 years ago

Can you provide more details on how contract.isContractValid() operates, please? The source code provided by Etherscan in step 1 mentiones flattened source. This can never fully verify, so there has to be mechanism to exclude the metadata hash in both the on-chain code and the re-compiled code.

FabianSchuessler commented 4 years ago

L. 259 contractBinary.contains(code) is false

https://github.com/web3j/web3j/blob/master/core/src/main/java/org/web3j/tx/Contract.java#L233

chriseth commented 4 years ago

There indeed seems to be a mechanism that removes the metadata hash, but it does not seem to be correct. The hardcoded hex values in https://github.com/web3j/web3j/blob/master/core/src/main/java/org/web3j/tx/Contract.java#L253 are not the right way to do it. The metadata hash can be detected by removing the number of bytes encoded in the last two bytes - as described here: https://solidity.readthedocs.io/en/develop/metadata.html#encoding-of-the-metadata-hash-in-the-bytecode

chriseth commented 4 years ago

Created an issue on the web3j repository: https://github.com/web3j/web3j/issues/1204