-
Notifications
You must be signed in to change notification settings - Fork 677
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
Proposal: Versioning contracts (reboot) #1098
Comments
No. Versioning as you describe it fundamentally breaks the trust model for smart contracts. It puts smart contracts under the same trust model as Web 2.0 servers, which is unacceptable. The trust model for smart contracts is that once deployed, a smart contract's code is immutable and irrevocable. Moreover, smart contract state is as immutable as the transactions and blocks that encode its state-transitions. Changing a smart contract's code or state necessarily requires a blockchain reorg. The lack of versioning is a feature, not a bug -- it is precisely what makes smart contracts a "can't-be-evil" form of distributed computing. Once you, the user, select a smart contract you want to use, no one can take it away from you. Smart contracts are not web apps, and that's intentional. The ability to publish a "newer version" of a smart contract and have all subsequent transactions automatically and implicitly interact with it (even if the user can opt out) allows the developer to be evil towards users. A "newer version" may simply steal the user's funds. A "newer version" may inflate the token or asset supply. A "newer version" can alter the semantics of existing methods, and break other smart contracts. The ability to publish a "newer version" means that a hacker who steals the developer's keys can cause harm to users as well. I cannot support adding versioning like this to Stacks v2. If the user wants to use a "newer version" of the smart contract, then the user (not the developer, and not the blockchain) must explicitly select which "version" they want to use when they craft their transactions. That said, I am open to building a versioning "convention" whereby a smart contract developer can provide guidance for users as to which smart contract instance to use, and which instances have bugs and should be avoided. But the system cannot enable developers to choose for users -- the user must always select which smart contracts they interact with. |
Ok, there is a big misunderstanding and I think we are on the same page. The chain of execution would not be dynamic, and the developer would be fully qualifying the version of the contract that have to be used ( |
As a developer pushing the following contract:
If I'm getting a notice from the analysis informing me that |
I see. This is very different than the versioning semantics offered by your example of crates.io, where the full version does not need to be specified to install a dependency, and old versions can be deleted (even if by accident). Using an example that behaves differently than the proposal is what led to the misunderstanding.
This is not a line of thinking we should encourage. This line of thinking leads to the lazy (and harmful) behavior of "always use the latest version when deploying." Attackers have already exploited this laziness in the wild many times over in software repositories like crates.io and npm by uploading a "newer" dependency that is malicious, and then having their victims' CI processes pull in the malware on the next deployment. The same kind of attack can happen to us if we have first-class versioning -- even if the tooling forces you to pick a version, the fact that developers will more-likely-than-not simply pick the latest version gives attackers the ability to get you to depend on their malware (and thus harm your users). The behavior we should be encouraging is to get smart contract authors to carry out end-to-end audits their code, including all their dependencies, before deploying it. Our system design should make it difficult for developers to avoid doing this. The absence of a versioning scheme helps encourage this behavior, because it forces developers to take a look at the particular dependencies they select.
Ours won't. But if we add versioning as a first-class name component, other tools will make selections on developers' behalves out of misguided convenience, and we won't be able to prevent it. |
As a general design principle in Clarity, developer convenience can usually be sacrificed to improve user security. This is why we went with a LISP variant that is not Turing-complete. This is why the language is interpreted (not compiled), and no other languages are supported. This is why we don't support re-entrancy or dynamic dispatch. First-class versioning is a developer convenience, but as your example illustrates, it can easily be used to hurt user security. |
Thank you for bringing this subject. IMHO, auditing code requires some special skills, and a developer (even good) is not necessarily a good auditor. Helping developers making the best decision when it comes to rely on a dependency is nothing but a security concern. Not a convenience. |
Just writing down some notes from an earlier conversation:
|
-- do you mean versioning? |
Hey @moxiegirl, I meant "vendoring" :) https://stackoverflow.com/questions/26217488/what-is-vendoring I did not know this at first, but it is apparently common practice for Solidity developers to avoid depending on already-deployed smart contracts. Instead, they are more prone to just make copies of them and deploy them themselves. |
I wanted to revisit this concept once more, having spoken with @kantai about what sorts of things miners will need to commit to when instantiating new smart contracts. With the imminent addition of the This suggests to me that all smart contracts need to have a monotonically-increasing sequence number, similar to an account nonce. The nonce would be part of the fully-qualified contract name, and would be given to In particular, we would want the protocol itself to compel miners to commit to all versions of the smart contract. To do so, miners would construct a MARF hash that cryptographically commit to:
This gives users (in particular, light clients and wallets) the ability to request the latest version of a smart contract, as well as query and walk to all prior versions of the contract, all while verifying their inclusion in the blockchain. This, I think, strikes the right balance between developers needing to ship updates to their smart contracts against the user's need to continue using whichever smart contract version(s) they want. Thoughts? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been automatically closed. Please reopen if needed. |
Reopening this issue, because I think we still need to come to an agreement here, and the stale bot is not how we want to get there 😄 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been automatically closed. Please reopen if needed. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been automatically closed. Please reopen if needed. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I’m currently working on #1078, and I’d like to re-open the debate with had about versioning :)
I think we can all agree on the fact that versioning is important, but I’ll state the obvious.
We are currently working on a version 2 of blockstack, this version 2 will itself be versioned (fixes, minor improvements, major improvements, etc). Our project is relying on a few dependencies, also versioned, and versioning plays an important role in the stability of our project.
As a developer, when I want to add a dependency to a solution, I have crates.io, where I can find libraries, I can see the different versions available, the one deprecated, etc.
We’ve been able to build great software ecosystems thanks to versioning. Versioning is as important as the identifier qualifying a solution: it’s part of the contract between a project and its dependencies, an executable and its runtime, a mobile app and its SDK, an HTTP client and its API, etc.
The only counter example I can think of is Smart contract with Solidity and we all agree on the fact that it should not set the standard of smart contracts.
Smart contracts repositories on Github are alive, they keep receiving some commits and being re-deployed.
With Clarity, we are introducing clean, human readable names.
Why not also including versioning?
If we envision that developers will end up appending a “_2”/“_v2”/“_version_2” / “_rev2” etc in the name part of the contract’s principal, why not allocating a version field in the contract principal for that?
A clean, native versioning mechanism would be beneficial for the developers, and more importantly, the end users (ex: wallet warning when a user is about to send a transaction to an outdated contract).
What's the downside of versioning contracts?
The text was updated successfully, but these errors were encountered: