Implementing contract upgrades

Thanks for articulating this so clearly, and for the comparison of the number of calls required with/without an enshrined slow updates tree. This post can serve as a nice reference for anyone who wishes to experiment with implementing (and benchmarking the costs of) an upgrade pattern.

An idea for another upgrade pattern, which builds upon Executing scripts in account contracts, is to write a proxy function which can verify an arbitrary proof. The contract ‘admin’ can then assert which verification keys are acceptable for modifying the state of the contract.

The upgradeable contract looks something like this (in pseudocode which looks nothing like aztec.nr - sorry!):

contract MyUpgradeableContract {
  
  const upgrade_admin: AztecAddress; // someone with the power to upgrade the vk_hash
  
  let currently_accepted_vk_hash: Field; // lazy storage declaration
  
  let x: Field; // some state variable that we'll edit, for example's sake.
  
  fn do_something_to_x(proof, public_inputs, purported_currently_accepted_vk) {
      // Validate the correctness of the vk:
      let purported_currently_accepted_vk_hash = hash(purported_currently_accepted_vk);
      assert(purported_currently_accepted_vk_hash == currently_accepted_vk_hash);
  
      // Verify the proof as correct:
      const result = verify_proof(proof, public_inputs, purported_currently_accepted_vk);
      assert(result == true);
  
      // Extract the new value of x, which has been proven to be updated in line with the currently-accepted vk
      const {new_x} = public_inputs;
      x = new_x;
  }

  fn upgrade_vk(new_vk_hash: Field) {
      assert(context.msg_sender == upgrade_admin);
      currently_accepted_vk_hash = new_vk_hash;
  }
 
}

Does this work?

I guess it’s not a very legible contract anymore. And it’s no longer making a call to a pretty contract, so in a way it’s undoing a lot of the effort we’ve gone to to making contracts feel like existing smart contract architectures…

Edit: we could probably build a library into aztec.nr that abstracts all of the ‘proof, vk, vkhash’ stuff into reading function selectors from classes, if we wanted to make it feel more familiar…

44 Likes