63

Given the (Solidity) source code of a smart contract, is there a way to deterministically compile the code and compare it with the code on the blockchain? I want to verify that the contract does what the source code claims to do and the author hasn't tampered with it.

1

7 Answers 7

41

AFAIK the best way to do this at the moment is to compile the source code again with the exact same compiler version the author used (so this is something that needs to be disclosed) and to compare the bytecode.

So the match you should check is the compiled bytecode against the data of the contract creation tx.

2
  • Not 100%, still problematic github.com/trufflesuite/truffle-compile/issues/77
    – Ender
    Oct 19, 2020 at 9:13
  • Thank you so much! The contract was built on v5.17.0, but I chose v5.0.0 to verify the contract code, so it threw errors. Finally, I change the version to be same with built compiler v5.17.0.
    – Johnny
    Sep 8, 2021 at 8:10
22

To add to @thomas-bertani's answer, today etherchain.org released a verification tool for Ethereum contracts

Here's the text from the page:

Source code verification provides transparency for users interacting with smart contracts. By uploading the source code, Etherscan will match the compiled code with that on the blockchain. Just like contracts, a "smart contract" should provide end users with more information on what they are "digitally signing" for and give users an opportunity to audit the code to independently verify that it actually does what it is supposed to do.

4
14

Currently the workflow is quite annoying. You need to compile the contract with the same compiler version and the same setting (look out for the "optimization=true" flag).

Now please note that the resulting bytecode does NOT match with the bytecode that is stored on the address. The reason for that is that the compiled contract does contain an initialization part that is ran only once when the contract is submitted to the chain. So the byte code stored on the blockchain is the code without the initialization part.

To verify the code you have two options:

  1. Submit the compiled code to a (virtual) blockchain and than check with the getCode command the resulting code.
  2. Compare the compiled code with the payload of the transaction that created the contract.

Etherchain helps to do this process.

In principal pattern matching techniques could be applied to identify a contact even if not exactly the same compiler is used. A project that is doing this and in general linking high level contract (Serpent/Solidity) to Ethereum adresses is: Etherscrape

8

https://etherscan.io/verifyContract is a verification tool. By providing the Solidity Source Code it checks if the generated Bytecode matches to the contract Bytecode (under the given address). user should choose the same compiler and to enable or disable the optimimsation.

5

Another approach would be to decompile the bytecode and compare it with the source.

There is a tool called Porosity that does just that.

5
  • I'm fairly confident that this cannot work to any level of efficiency, especially for larger contracts. The names of the variables are not stored in the byte code, so the decompiler must create its own names. Trying to see if the decompiled code is the same as represented source would be very difficult, I would think. Aug 9, 2017 at 20:19
  • 1
    The Contract ABI contains all the variable names.
    – emx
    Aug 10, 2017 at 22:02
  • Not always. I've seen many that don't. Aug 10, 2017 at 22:03
  • Noted. This would indeed make decompilation unpractical for complex contracts.
    – emx
    Aug 10, 2017 at 22:26
  • I didn't realize the decompiler used the ABI. That clearly makes it a lot easier. Aug 10, 2017 at 23:34
2

Recommend to use the open-sourced command line tool ConsenSys just released, bytecode-verifier, respective npm package

Bytecode Verifier is a handy commandline tool for verifying locally compiled bytecode of a target Solidity contract against its actual bytecode stored in Etheruem Blockchain provided its contract address.

  • integrity/correctness of bytecode: what's actually being stored on chain is correctly compiled from particular contract, which might be helpful in case of non-trivial potential high-value holder contract deployment(e.g. MultiSig Wallet), especially the contract is deployed through a third party platform.

  • Minimimal effort, simple to use: solidity compiler envolves overtime with minor and some major changes, which complicates the verification of bytecode. (as recurring "bytecode doesn't match" questions being asked on Ethereum Stack Exchange). Bytecode Verifier has been tested against latest version all the way back to some of the oldest deployed contracts.

  • Testnet friendly: most projects launch on testnet before deploying the contract system to mainnet, this tool supports Rinkeby, Kovan and Ropsten Testnet, which constitute three active, well-maintained testnets that most ethereum developers use.

Hope it helps!

0

This is how I do it in a web3 script.

First, compile the code.

const solc = require('solc');

//contract sources
const contractPath = "../contracts/";

const input = {
  "ContractName.sol" : fs.readFileSync(contractPath + 'contractName.sol', 'utf8'),
}

let solcOutput = await solc.compile({ sources: input }, 1);

now compare byteCode

let blockCode = await web3.eth.getCode(contractAddress);
let solcCode = '0x' + (solcOutput.contracts["contractName.sol:contracName"].runtimeBytecode);}
3
  • This does not work, you are missing constructor parameters and auxdata
    – mdv
    Aug 23, 2018 at 21:50
  • How did u test it? it works for me on all of kyber network contracts. Oct 4, 2018 at 10:12
  • @mdv Do you need to have matching constructor parameters? I'm seeing conflicting responses, but my guess is no, since the constructor is designed to put values in storage, not determine the existence of functions or state vars. Oct 5, 2018 at 4:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.