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

Upgradeable Smart Contracts #22

Closed
treeder opened this issue Aug 2, 2018 · 2 comments
Closed

Upgradeable Smart Contracts #22

treeder opened this issue Aug 2, 2018 · 2 comments

Comments

@treeder
Copy link
Contributor

treeder commented Aug 2, 2018

Aside from solving performance issues, GoChain also has a goal of fixing another huge problem with Ethereum and that is theft prevention. Theft on Ethereum is almost always related to bugs in smart contract code (besides gaining someone’s private key via social engineering, SMS hijacking, etc). $100’s of millions (if not billions) have been stolen in the past couple of years due to bugs in smart contracts.

One way to reduce the chance of theft by bugs is the ability to pause a contract (stop the theft) and upgrade it (fix the bug that makes the theft possible). This proposal is to enable both of those features. A nice side effect of this is that contracts can be upgraded for other reasons too, such as adding new functionality to a DApp or amending a contract which reflects real-life contracts.

Pausing a contract

The first step would typically be to pause a contract to stop someone from taking advantage of a known bug. Since this one doesn't change the contract or the data, the owner could pause a contract without the knowledge of other involved parties and this would not break trust. Also, this has to be able to happen immediately so letting a single entity be able to do this is a must.

Who can upgrade a contract?

One of the main selling points about smart contracts is that they are immutable and therefore you create a level of trust between different parties that may otherwise not trust each other. If one party can change the contract, you lose the trust. So how can we continue to have trust between parties while still allowing a contract to be upgraded? Upgrading the contract itself isn't the hard part, having a system that retains trust while allowing upgrades is the hard part.

The default upgradeability will remain the same as it is now, which means nobody can upgrade it. To enable an upgradeable contract, it must be set during the deployment of the contract.

The owner (the deployer) would set upgradeability rules on the contract during deployment which defines how a contract could be upgraded. Some example rules:

  • owner only (single voter)
  • Vote
    • The upgrader would deploy the new contract then a vote would start
    • a) by %: X% of all parties that use contract must vote “yes” for the contract to take effect
      • NOTE: This might get out of hand if there’s too many users of the contract
    • b) by specific addresses: The addresses in the list must vote “yes” for the contract to take effect

These rules would be visible to all, so a user can decide whether to interact with the contract or not. If they know the upgrade rules, they can make an informed decision.

How it would work technically

Interacting with a smart contract requires the contract address. The contract state is also stored in the Merkle Patricia Trie under that same address. One requirement is that the address stays the same so people can continue to use the same address after the upgrade.

The owner would call upgradeContract() function with the same parameters as deploying a contract plus the previous address to override.

In order to use the same address with new code, we could do one of the following (after it's been voted in):

  1. Make a new account, copy the state, then make an alias/pointer from the old account to the new one. Any incoming calls to the original contract address will be redirected to the new contract address. Downside of this is that it would double the storage space used and the old state would sit there forever. Would have to have some way to clean up old state after some time.
  2. Store the new code then change the codeHash for the existing account. This would use the same storageRoot with new code. Downside of this is that we might lose some context? Probably need to store a previousCodeHash too or something along those lines).

Once deployed, the contract becomes active again (unpaused).

Open Questions

  • What if a data migration is needed?
  • Can the owner be changed?
  • Can upgradeability be upgraded? i.e. Can 'owner-only' be upgraded to the other voting modes?
@treeder
Copy link
Contributor Author

treeder commented Mar 19, 2019

This is being implemented in the web3 tool: gochain/web3#63

@treeder
Copy link
Contributor Author

treeder commented Jun 21, 2019

Implemented in web3 tool. 💥

@treeder treeder closed this as completed Jun 21, 2019
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

1 participant