Skip to content

Commit b9ff174

Browse files
committed
adding upgradability to features overview
1 parent aa9da14 commit b9ff174

File tree

14 files changed

+4495
-4
lines changed

14 files changed

+4495
-4
lines changed

.github/workflows/test-tutorials.yml

+22
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,28 @@ jobs:
4646
node build/src/main.js
4747
fi
4848
49+
test-features:
50+
runs-on: ubuntu-latest
51+
52+
strategy:
53+
matrix:
54+
node-version: [18, 20, 22]
55+
56+
steps:
57+
- name: Checkout repository
58+
uses: actions/checkout@v4
59+
60+
- name: Setup Node.js
61+
uses: actions/setup-node@v4
62+
with:
63+
node-version: ${{ matrix.node-version }}
64+
65+
- name: Install dependencies, build and test
66+
run: |
67+
cd examples/zkapps/feature-overview
68+
npm ci
69+
npm run test
70+
4971
build-tutorials:
5072
runs-on: ubuntu-latest
5173

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: Upgradability
3+
hide_title: true
4+
description: Detailed guide on upgrading zkapps by setting the verification key
5+
keywords:
6+
- permissions
7+
- zkapp development
8+
- smart contracts
9+
- mina
10+
- smart contract security
11+
- smart contract Upgradability
12+
- o1js
13+
- mina transaction
14+
- blockchain
15+
---
16+
17+
# ZkApp Upgradability
18+
19+
The Mina protocol allows for the upgrading of verification keys on-chain. This article will demonstrate some specific examples of how to upgrade a ZkApp.
20+
21+
### First: A note on Permissions
22+
23+
Please carefully review the [Permissions](/zkapps/writing-a-zkapp/feature-overview/permissions) article to understand the security model of who can upgrade a smart contract. This walkthrough of upgradability will assume that you know how Permissions work on Mina.
24+
25+
### Second: A note on Mina's execution model
26+
27+
Upgradability on other blockchains may mean that a user thinks they're using one program, but since it has been upgraded, they are actually using another program. Two programs with the same function signature may have very different behavior and result in a bad or unsafe user experience. Mina's execution model is different. On Mina, users run their own program and upload the proof to the blockchain for verification only. So what it means to upgrade a ZkApp is only to change the verification key on-chain. Proofs generated with an older prover function will not be valid, and users will need to download the new prover function to generate a valid proof.
28+
29+
## Baseline ZkApp
30+
31+
For example, let's use our standard `Add` example smart contract as the baseline ZkApp.
32+
33+
```ts
34+
import { Field, SmartContract, state, State, method } from 'o1js';
35+
36+
export class Add extends SmartContract {
37+
@state(Field) num = State<Field>();
38+
39+
init() {
40+
super.init();
41+
this.num.set(Field(1));
42+
}
43+
44+
@method async update() {
45+
const currentState = this.num.getAndRequireEquals();
46+
const newState = currentState.add(2);
47+
this.num.set(newState);
48+
}
49+
}
50+
```
51+
52+
This contract has a verification key of `"27729068461170601362912907281403262888852363473424470267835507636847418791713"`
53+
54+
## Upgraded ZkApp
55+
56+
For our upgraded contract, let's use this updated example which adds by 4 instead of by 2.
57+
58+
```ts
59+
import { Field, SmartContract, state, State, method } from 'o1js';
60+
61+
export class AddV2 extends SmartContract {
62+
@state(Field) num = State<Field>();
63+
64+
init() {
65+
super.init();
66+
this.num.set(Field(1));
67+
}
68+
69+
@method async update() {
70+
const currentState = this.num.getAndRequireEquals();
71+
const newState = currentState.add(4);
72+
this.num.set(newState);
73+
}
74+
}
75+
```
76+
77+
This contract has a verification key of `"18150279532259194644722165513074833862035641840431153413486908511595437348455"`
78+
79+
## Upgrading a ZkApp
80+
81+
Upgrading a ZkApp by signature can be done if you control the private key of a ZkApp. To do this, you need to sign a transaction that upgrades the ZkApp with that key.
82+
83+
Imagine we have already deployed the `Add` contract, and we have the private key available as `zkAppKey`
84+
85+
```ts
86+
const verificationKey = (await AddV2.compile()).verificationKey;
87+
const contractAddress = zkAppKey.toPublicKey();
88+
89+
const upgradeTx = await Mina.transaction({ sender, fee },
90+
async () => {
91+
const update = AccountUpdate.createSigned(zkApp.address);
92+
update.update.verificationKey = {
93+
isSome: Bool(true),
94+
value: verificationKey,
95+
};
96+
}
97+
);
98+
await tx.sign([senderKey, zkAppKey]).prove();
99+
await tx.send();
100+
```
101+
102+
And just like that, when the transaction is applied to the blockchain, the verification key at the ZkApp address will be updated from `"27729068461170601362912907281403262888852363473424470267835507636847418791713"` to `"18150279532259194644722165513074833862035641840431153413486908511595437348455"`!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
browser: true,
5+
node: true,
6+
jest: true,
7+
},
8+
extends: [
9+
'eslint:recommended',
10+
'plugin:@typescript-eslint/eslint-recommended',
11+
'plugin:@typescript-eslint/recommended',
12+
'plugin:o1js/recommended',
13+
],
14+
parser: '@typescript-eslint/parser',
15+
parserOptions: {
16+
ecmaVersion: 'latest',
17+
},
18+
plugins: ['@typescript-eslint', 'o1js'],
19+
rules: {
20+
'no-constant-condition': 'off',
21+
'prefer-const': 'off',
22+
},
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# NodeJS
2+
node_modules
3+
build
4+
coverage
5+
.husky
6+
7+
# Editor
8+
.vscode
9+
10+
# System
11+
.DS_Store
12+
13+
# Misc
14+
LICENSE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"trailingComma": "es5"
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"version": 1,
3+
"deployAliases": {}
4+
}

0 commit comments

Comments
 (0)