Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There is no way to detect which compiler version produced a contract binary #529

Closed
jzu opened this issue May 1, 2016 · 12 comments
Closed

Comments

@jzu
Copy link

jzu commented May 1, 2016

...or, how can I trust the runtime bytecode?

For instance, a few years from now, I want to use a contract which has been written today, but first I want to make sure it will execute as expected, so I re-build the source and compare the binaries. However, if the compiler is not the same as the one which has been originally used, it is likely the output will be different. So I have to know which version has been used but there's currently no way do discover this information.

I could ask the developer, but said developer can be out of reach at a critical moment, or even permanently. Or, I could collect all versions (and maybe forks) of the Solidity compiler, try them all to have a chance to get a matching binary, but that's a clumsy workaround at best. There are too many cases where I cannot trust the code, and this pretty much defeats the whole purpose of smart contracts in a "trustless" environment.

There should be some kind of tag in the runtime bytecode, giving the information needed to build the same bytecode from the same source. In the meantime, a workaround would be to use a dedicated variable, which would be recommended for best practices, and users would have to learn to only use contracts where this information is available... A built-in solution would solve the problem once and for all.

@jzu
Copy link
Author

jzu commented May 1, 2016

@tayvano
Copy link

tayvano commented May 3, 2016

I'm adding a +1 to this.

One of the major selling points of "code on the blockchain" is the ability for anyone to verify the source and validity of the bytecode. Without some sort of indicator with the version of the compiler, or some sort of information, it is impossible for a person to verify.

Many, many people were attempting to verify the recent DAO contract and even with the developers (compilers) giving all the information about how they compiled it, it still took far too long and far too many hoops to verify it.

Without some way of being able to tell the compiler version using just the outputted bytecode, you cannot advertise a contract as verifiable, only immutable. And immutable but unverifiable is not a good enough for a contract that may hold millions of ETH.

@VoR0220
Copy link
Member

VoR0220 commented May 3, 2016

hmmmm....so you're asking for the compiler version to be pushed into the ABI? I'm just trying to understand what it is you're asking. It would add additional costs to input the Compiler version into the actual live chain. However, if you're asking whether or not you could get the output of the bytecode and have inside of the combined-json the version of the compiler...I think that ought to be doable. But the ABI modifications...that would be a bit harder of a sell and you would have to convince the ABI folks of this as well.

@tayvano
Copy link

tayvano commented May 3, 2016

So here is the desired outcome. I have no idea what the solution is:

  1. I (the end user) want to send my hard-earned ETH to a contract that says it will do XYZ.
  2. I read the source code posted and think it looks great.
  3. Now, I just have to verify that the source actually compiles to the bytecode. Ideally, I could detect what compiler was used from the bytecode on the blockchain, use that compiler to compile the source, and diff it. Or, I could use a service like https://etherscan.io/verifyContract to do so. Regardless, I need to know the compiler and whether or not it is optimized and if I don't have that information for whatever reason, I'm SOL (without writing a script to brute-force every compiler version available).

@axic
Copy link
Member

axic commented May 3, 2016

Some ideas:

  1. Have a version string in an unreachable code piece in a fixed location of the bytecode. A good candidate would be the end of the bytecode, i.e. nominate the last 32 bytes.

  2. Have a method call for querying the compiler version, e.g. something obscure like __$compilerVersion() would return it as a string (easier to use as a user) or bytes32 (smaller code size). Technically this would mean an extra case in the ABI dispatcher always added by the compiler. This option adds at least 40 bytes of extra code to every binary.

  3. Have a method / constant variable within Solidity which will insert the version as a string into the output. Then anyone can write a way to use, i.e. write a getVersion() method as mentioned in 2) with the exception that it is completely up to the developer to decide.

Perhaps option 2) makes more sense if:

  • it is an agreed upon method name, so that Solidity, Serpent and others can implement it
  • it is an optional method and it can be turned on/off by developer when writing a contract

Not every contract needs to be verifiable or at least not every developer might have that need.

@jzu
Copy link
Author

jzu commented May 3, 2016

Thanks for your answer, much appreciated!

@chriseth
Copy link
Contributor

chriseth commented May 4, 2016

Storing the used compiler version in the bytecode will not help, because there is some information that is even more important than the compiler version that is also missing in the bytecode: The actual source code.

There is a project that will provide metadata for contracts deployed on the blockchain, which include the source code, the compiler version and the compiler options (there is some flexibility in the optimizer, so that is also needed).

At the current point in time, it might seem like a good idea to store the compiler version in the bytecode, but I think this will just not scale and we need a proper contract metadata registry.

@LefterisJP
Copy link
Contributor

@chriseth I like the idea of having a contract metadata registry.

Is such a project developed by anyone at the moment?

@VoR0220
Copy link
Member

VoR0220 commented May 4, 2016

@LefterisJP Etherscrape comes to mind.

@LefterisJP
Copy link
Contributor

@VoR0220 Thanks for the hint, did not know them. It looks really interesting. Still the project seems to be at its infancy at the moment.

The end goal would be to have a standard registry for this metadata and be able to add new contracts or edit existing ones. By looking at their website a bit I could find no way to do such a thing. They seem to have all these data, mined in some way by exploring the blockchain in an automated way.

@jzu
Copy link
Author

jzu commented May 7, 2016

What about a package including source + bytecode + compile-time metadata + comment, stored on BitTorrent, indexed by a hash found in the runtime bytecode (or computed from the bytecode itself)? Building the package and seeding it would be part of the deployment procedure.

@chriseth
Copy link
Contributor

chriseth commented Aug 5, 2016

We will work on that is part of authenticated binaries.

@chriseth chriseth closed this as completed Aug 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants