From b3881ab8d77070396b27a8cae0e4cd29cb15bae4 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Sat, 13 Apr 2024 14:45:27 -0400 Subject: [PATCH 01/11] implement TestAccount util and refactor examples --- src/examples/chaining-tx-methods.ts | 6 +- src/examples/commonjs.cjs | 28 +- src/examples/nullifier.ts | 24 +- src/examples/simple-zkapp.js | 12 +- src/examples/simple-zkapp.ts | 38 ++- src/examples/simple-zkapp.web.ts | 19 +- src/examples/zkapps/composability.ts | 49 ++-- .../zkapps/dex/happy-path-with-actions.ts | 23 +- .../zkapps/dex/happy-path-with-proofs.ts | 23 +- src/examples/zkapps/dex/run.ts | 46 ++- src/examples/zkapps/dex/upgradability.ts | 84 +++--- src/examples/zkapps/hashing/run.ts | 24 +- src/examples/zkapps/hello-world/run.ts | 90 +++--- src/examples/zkapps/local-events-zkapp.ts | 31 +- .../zkapps/merkle-tree/merkle-zkapp.ts | 18 +- .../zkapps/reducer/actions-as-merkle-list.ts | 19 +- src/examples/zkapps/reducer/map.ts | 23 +- .../zkapps/reducer/reducer-composite.ts | 27 +- .../zkapps/set-local-preconditions-zkapp.ts | 39 +-- src/examples/zkapps/simple-zkapp-payment.ts | 53 ++-- .../zkapps/simple-zkapp-with-proof.ts | 26 +- src/examples/zkapps/sudoku/index.ts | 8 +- src/examples/zkapps/token-with-proofs.ts | 26 +- src/examples/zkapps/voting/demo.ts | 21 +- .../zkapps/voting/deploy-contracts.ts | 24 +- src/examples/zkapps/zkapp-self-update.ts | 32 +-- .../mina/account-update-layout.unit-test.ts | 19 +- src/lib/mina/account-update.unit-test.ts | 2 +- src/lib/mina/local-blockchain.ts | 33 ++- src/lib/mina/mina.ts | 3 +- src/lib/mina/precondition.test.ts | 35 ++- src/lib/mina/token.test.ts | 265 +++++++++--------- .../mina/token/token-contract.unit-test.ts | 23 +- .../on-chain-state-mgmt-zkapp-ui.js | 22 +- 34 files changed, 565 insertions(+), 650 deletions(-) diff --git a/src/examples/chaining-tx-methods.ts b/src/examples/chaining-tx-methods.ts index abdb604d3d..13345b8f3a 100644 --- a/src/examples/chaining-tx-methods.ts +++ b/src/examples/chaining-tx-methods.ts @@ -30,7 +30,7 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0]; +let [sender] = Local.testAccounts; // the zkapp account let zkappKey = PrivateKey.random(); @@ -45,7 +45,7 @@ await Mina.transaction(sender, async () => { senderUpdate.send({ to: zkappAddress, amount: initialBalance }); await zkapp.deploy(); }) - .sign([senderKey, zkappKey]) + .sign([sender.key, zkappKey]) .send() .wait(); @@ -54,7 +54,7 @@ console.log('initial state: ' + zkapp.x.get()); console.log('increment'); const incrementTx = Mina.transaction(sender, async () => { await zkapp.increment(); -}).sign([senderKey]); +}).sign([sender.key]); await incrementTx.then((v) => v.prove()); await incrementTx.send().wait(); diff --git a/src/examples/commonjs.cjs b/src/examples/commonjs.cjs index 4974390e33..86feaea09c 100644 --- a/src/examples/commonjs.cjs +++ b/src/examples/commonjs.cjs @@ -12,7 +12,7 @@ let { declareMethods, } = require('o1js'); -class SimpleZkapp extends SmartContract { +class Contract extends SmartContract { constructor(address) { super(address); this.x = State(); @@ -33,39 +33,37 @@ class SimpleZkapp extends SmartContract { this.x.set(x.add(y)); } } -declareState(SimpleZkapp, { x: Field }); -declareMethods(SimpleZkapp, { update: [Field] }); +declareState(Contract, { x: Field }); +declareMethods(Contract, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let contractAccount = new Mina.TestAccount(PrivateKey.random()); +let contract = new Contract(contractAccount); let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAddress); main(); async function main() { console.log('compile'); - await SimpleZkapp.compile(); + await Contract.compile(); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); - console.log('initial state: ' + zkapp.x.get()); + console.log('initial state: ' + contract.x.get()); console.log('update'); - tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3))); + tx = await Mina.transaction(feePayer, () => contract.update(Field(3))); await tx.prove(); - await tx.sign([feePayerKey]).send(); - console.log('final state: ' + zkapp.x.get()); + await tx.sign([feePayer.key]).send(); + console.log('final state: ' + contract.x.get()); } diff --git a/src/examples/nullifier.ts b/src/examples/nullifier.ts index 9693583dcf..7cbf3b1f1c 100644 --- a/src/examples/nullifier.ts +++ b/src/examples/nullifier.ts @@ -1,5 +1,4 @@ import { - PrivateKey, Nullifier, Field, SmartContract, @@ -7,7 +6,6 @@ import { State, method, MerkleMap, - Circuit, MerkleMapWitness, Mina, AccountUpdate, @@ -53,18 +51,16 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0]; +let [sender] = Local.testAccounts; // the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let zkappAccount = Mina.TestAccount.random(); // a special account that is allowed to pull out half of the zkapp balance, once -let privilegedKey = PrivateKey.random(); -let privilegedAddress = privilegedKey.toPublicKey(); +let privileged = Mina.TestAccount.random(); let initialBalance = 10_000_000_000; -let zkapp = new PayoutOnlyOnce(zkappAddress); +let zkapp = new PayoutOnlyOnce(zkappAccount); // a unique message let nullifierMessage = Field(5); @@ -75,14 +71,14 @@ await PayoutOnlyOnce.compile(); console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); - senderUpdate.send({ to: zkappAddress, amount: initialBalance }); + senderUpdate.send({ to: zkappAccount, amount: initialBalance }); await zkapp.deploy(); zkapp.nullifierRoot.set(NullifierTree.getRoot()); zkapp.nullifierMessage.set(nullifierMessage); }); await tx.prove(); -await tx.sign([senderKey, zkappKey]).send(); +await tx.sign([sender.key, zkappAccount.key]).send(); console.log(`zkapp balance: ${zkapp.account.balance.get().div(1e9)} MINA`); @@ -90,7 +86,7 @@ console.log('generating nullifier'); let jsonNullifier = Nullifier.createTestNullifier( [nullifierMessage], - privilegedKey + privileged.key ); console.log(jsonNullifier); @@ -100,11 +96,11 @@ tx = await Mina.transaction(sender, async () => { await zkapp.payout(Nullifier.fromJSON(jsonNullifier)); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log(`zkapp balance: ${zkapp.account.balance.get().div(1e9)} MINA`); console.log( - `user balance: ${Mina.getAccount(privilegedAddress).balance.div(1e9)} MINA` + `user balance: ${Mina.getAccount(privileged).balance.div(1e9)} MINA` ); console.log('trying second pay out'); @@ -115,7 +111,7 @@ try { }); await tx.prove(); - await tx.sign([senderKey]).send(); + await tx.sign([sender.key]).send(); } catch (error: any) { console.log( 'transaction failed, as expected! received the following error message:' diff --git a/src/examples/simple-zkapp.js b/src/examples/simple-zkapp.js index 108fd0913a..d6bbf150eb 100644 --- a/src/examples/simple-zkapp.js +++ b/src/examples/simple-zkapp.js @@ -42,14 +42,12 @@ declareMethods(SimpleZkapp, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let zkappAccount = Mina.TestAccount.random() let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAddress); +let zkapp = new SimpleZkapp(zkappAccount); console.log('compile'); await SimpleZkapp.compile(); @@ -59,12 +57,12 @@ let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); await zkapp.deploy(); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, zkappAccount.key]).send(); console.log('initial state: ' + zkapp.x.get()); console.log('update'); tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3))); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('final state: ' + zkapp.x.get()); diff --git a/src/examples/simple-zkapp.ts b/src/examples/simple-zkapp.ts index 4589ab2a6c..da8d793b0e 100644 --- a/src/examples/simple-zkapp.ts +++ b/src/examples/simple-zkapp.ts @@ -50,7 +50,7 @@ class SimpleZkapp extends SmartContract { // check that caller is the privileged account let callerAddress = caller.toPublicKey(); - callerAddress.assertEquals(privilegedAddress); + callerAddress.assertEquals(privileged); // assert that the caller account is new - this way, payout can only happen once let callerAccountUpdate = AccountUpdate.create(callerAddress); @@ -73,21 +73,19 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0]; +let [sender, payout] = Local.testAccounts; // the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let zkappAccount = Mina.TestAccount.random(); // a special account that is allowed to pull out half of the zkapp balance, once -let privilegedKey = PrivateKey.fromBase58( - 'EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep' +let privileged = new Mina.TestAccount( + PrivateKey.fromBase58('EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep') ); -let privilegedAddress = privilegedKey.toPublicKey(); let initialBalance = 10_000_000_000; let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAddress); +let zkapp = new SimpleZkapp(zkappAccount); if (doProofs) { console.log('compile'); @@ -101,16 +99,16 @@ if (doProofs) { console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); - senderUpdate.send({ to: zkappAddress, amount: initialBalance }); + senderUpdate.send({ to: zkappAccount, amount: initialBalance }); zkapp.deploy(); }); await tx.prove(); -await tx.sign([senderKey, zkappKey]).send(); +await tx.sign([sender.key, zkappAccount.key]).send(); console.log('initial state: ' + zkapp.x.get()); console.log(`initial balance: ${zkapp.account.balance.get().div(1e9)} MINA`); -let account = Mina.getAccount(zkappAddress); +let account = Mina.getAccount(zkappAccount); console.log('account state is proved:', account.zkapp?.provedState.toBoolean()); console.log('update'); @@ -118,23 +116,23 @@ tx = await Mina.transaction(sender, async () => { await zkapp.update(Field(3)); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); // pay more into the zkapp -- this doesn't need a proof console.log('receive'); tx = await Mina.transaction(sender, async () => { let payerAccountUpdate = AccountUpdate.createSigned(sender); - payerAccountUpdate.send({ to: zkappAddress, amount: UInt64.from(8e9) }); + payerAccountUpdate.send({ to: zkappAccount, amount: UInt64.from(8e9) }); }); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log('payout'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); - await zkapp.payout(privilegedKey); + await zkapp.payout(privileged.key); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); sender; console.log('final state: ' + zkapp.x.get()); @@ -142,11 +140,11 @@ console.log(`final balance: ${zkapp.account.balance.get().div(1e9)} MINA`); console.log('try to payout a second time..'); tx = await Mina.transaction(sender, async () => { - await zkapp.payout(privilegedKey); + await zkapp.payout(privileged.key); }); try { await tx.prove(); - await tx.sign([senderKey]).send(); + await tx.sign([sender.key]).send(); } catch (err: any) { console.log('Transaction failed with error', err.message); } @@ -154,10 +152,10 @@ try { console.log('try to payout to a different account..'); try { tx = await Mina.transaction(sender, async () => { - await zkapp.payout(Local.testAccounts[2].privateKey); + await zkapp.payout(payout.key); }); await tx.prove(); - await tx.sign([senderKey]).send(); + await tx.sign([sender.key]).send(); } catch (err: any) { console.log('Transaction failed with error', err.message); } diff --git a/src/examples/simple-zkapp.web.ts b/src/examples/simple-zkapp.web.ts index 2007df4d90..c4a8c10974 100644 --- a/src/examples/simple-zkapp.web.ts +++ b/src/examples/simple-zkapp.web.ts @@ -46,7 +46,7 @@ class SimpleZkapp extends SmartContract { // check that caller is the privileged account let callerAddress = caller.toPublicKey(); - callerAddress.assertEquals(privilegedAddress); + callerAddress.assertEquals(privileged); // assert that the caller account is new - this way, payout can only happen once let callerAccountUpdate = AccountUpdate.create(callerAddress); @@ -67,17 +67,16 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0]; +let [sender] = Local.testAccounts; // the zkapp account let zkappKey = PrivateKey.random(); let zkappAddress = zkappKey.toPublicKey(); // a special account that is allowed to pull out half of the zkapp balance, once -let privilegedKey = PrivateKey.fromBase58( - 'EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep' +let privileged = new Mina.TestAccount( + PrivateKey.fromBase58('EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep') ); -let privilegedAddress = privilegedKey.toPublicKey(); let initialBalance = 10_000_000_000; let initialState = Field(1); @@ -95,7 +94,7 @@ let tx = await Mina.transaction(sender, async () => { await zkapp.deploy(); }); await tx.prove(); -await tx.sign([senderKey, zkappKey]).send(); +await tx.sign([sender.key, zkappKey]).send(); console.log('initial state: ' + zkapp.x.get()); console.log(`initial balance: ${zkapp.account.balance.get().div(1e9)} MINA`); @@ -108,7 +107,7 @@ tx = await Mina.transaction(sender, async () => { await zkapp.update(Field(3)); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); // pay more into the zkapp -- this doesn't need a proof console.log('receive'); @@ -116,15 +115,15 @@ tx = await Mina.transaction(sender, async () => { let payerAccountUpdate = AccountUpdate.createSigned(sender); payerAccountUpdate.send({ to: zkappAddress, amount: UInt64.from(8e9) }); }); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log('payout'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); - await zkapp.payout(privilegedKey); + await zkapp.payout(privileged.key); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log('final state: ' + zkapp.x.get()); console.log(`final balance: ${zkapp.account.balance.get().div(1e9)} MINA`); diff --git a/src/examples/zkapps/composability.ts b/src/examples/zkapps/composability.ts index 81867b8e6d..dffac43b83 100644 --- a/src/examples/zkapps/composability.ts +++ b/src/examples/zkapps/composability.ts @@ -6,7 +6,6 @@ import { method, Mina, AccountUpdate, - PrivateKey, SmartContract, state, State, @@ -31,7 +30,7 @@ class Adder extends SmartContract { // compute result let sum = x.add(y); // call the other contract to increment - let incrementer = new Incrementer(incrementerAddress); + let incrementer = new Incrementer(incrementerAccount); return await incrementer.increment(sum); } } @@ -43,7 +42,7 @@ class Caller extends SmartContract { @method async callAddAndEmit(x: Field, y: Field) { - let adder = new Adder(adderAddress); + let adder = new Adder(adderAccount); let sum = await adder.addPlus1(x, y); this.emitEvent('sum', sum); this.sum.set(sum); @@ -57,23 +56,14 @@ ComposabilityProfiler.start('Composability test flow'); let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts; -// the first contract's address -let incrementerKey = PrivateKey.random(); -let incrementerAddress = incrementerKey.toPublicKey(); -// the second contract's address -let adderKey = PrivateKey.random(); -let adderAddress = adderKey.toPublicKey(); -// the third contract's address -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); - -let zkapp = new Caller(zkappAddress); -let adderZkapp = new Adder(adderAddress); -let incrementerZkapp = new Incrementer(incrementerAddress); +let incrementerAccount = Mina.TestAccount.random(); +let incrementer = new Incrementer(incrementerAccount); +let adderAccount = Mina.TestAccount.random(); +let adder = new Adder(adderAccount); +let callerAccount = Mina.TestAccount.random(); +let caller = new Caller(callerAccount); if (doProofs) { console.log('compile (incrementer)'); @@ -87,22 +77,29 @@ if (doProofs) { console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer, 3); - await zkapp.deploy(); - await adderZkapp.deploy(); - await incrementerZkapp.deploy(); + await caller.deploy(); + await adder.deploy(); + await incrementer.deploy(); }); -await tx.sign([feePayerKey, zkappKey, adderKey, incrementerKey]).send(); +await tx + .sign([ + feePayer.key, + callerAccount.key, + adderAccount.key, + incrementerAccount.key, + ]) + .send(); console.log('call interaction'); tx = await Mina.transaction(feePayer, async () => { // we just call one contract here, nothing special to do - await zkapp.callAddAndEmit(Field(5), Field(6)); + await caller.callAddAndEmit(Field(5), Field(6)); }); console.log('proving (3 proofs.. can take a bit!)'); await tx.prove(); console.log(tx.toPretty()); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); // should hopefully be 12 since we added 5 + 6 + 1 -console.log('state: ' + zkapp.sum.get()); +console.log('state: ' + caller.sum.get()); ComposabilityProfiler.stop().store(); diff --git a/src/examples/zkapps/dex/happy-path-with-actions.ts b/src/examples/zkapps/dex/happy-path-with-actions.ts index 7b186e641d..d40761790d 100644 --- a/src/examples/zkapps/dex/happy-path-with-actions.ts +++ b/src/examples/zkapps/dex/happy-path-with-actions.ts @@ -19,8 +19,7 @@ let Local = Mina.LocalBlockchain({ enforceTransactionLimits: true, }); Mina.setActiveInstance(Local); -let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] = - Local.testAccounts; +let [feePayer] = Local.testAccounts; let tx, balances, oldBalances; if (proofsEnabled) { @@ -42,25 +41,25 @@ let dexTokenHolderX = new DexTokenHolder(addresses.dex, tokenIds.X); let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y); tic('deploy & init token contracts'); -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { await tokenX.deploy(); await tokenY.deploy(); // pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves const accountFee = Mina.getNetworkConstants().accountCreationFee; - let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2); + let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 2); feePayerUpdate.send({ to: tokenX.self, amount: accountFee }); feePayerUpdate.send({ to: tokenY.self, amount: accountFee }); }); await tx.prove(); -await tx.sign([feePayerKey, keys.tokenX, keys.tokenY]).send(); +await tx.sign([feePayer.key, keys.tokenX, keys.tokenY]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); tic('deploy dex contracts'); -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts - AccountUpdate.createSigned(feePayerAddress).balance.subInPlace( + AccountUpdate.createSigned(feePayer).balance.subInPlace( Mina.getNetworkConstants().accountCreationFee.mul(3) ); await dex.deploy(); @@ -70,21 +69,21 @@ tx = await Mina.transaction(feePayerAddress, async () => { await tokenY.approveAccountUpdate(dexTokenHolderY.self); }); await tx.prove(); -await tx.sign([feePayerKey, keys.dex]).send(); +await tx.sign([feePayer.key, keys.dex]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); tic('transfer tokens to user'); let USER_DX = 1_000n; -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 user accounts - let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 3); - feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees + let au = AccountUpdate.fundNewAccount(feePayer, 3); + au.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees await tokenX.transfer(addresses.tokenX, addresses.user, UInt64.from(USER_DX)); await tokenY.transfer(addresses.tokenY, addresses.user, UInt64.from(USER_DX)); }); await tx.prove(); -await tx.sign([feePayerKey, keys.tokenX, keys.tokenY]).send(); +await tx.sign([feePayer.key, keys.tokenX, keys.tokenY]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); diff --git a/src/examples/zkapps/dex/happy-path-with-proofs.ts b/src/examples/zkapps/dex/happy-path-with-proofs.ts index 09395d9801..99361e59e8 100644 --- a/src/examples/zkapps/dex/happy-path-with-proofs.ts +++ b/src/examples/zkapps/dex/happy-path-with-proofs.ts @@ -15,8 +15,7 @@ let Local = Mina.LocalBlockchain({ enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); -let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] = - Local.testAccounts; +let [feePayer] = Local.testAccounts; let tx, balances, oldBalances; let { Dex, DexTokenHolder, getTokenBalances } = createDex(); @@ -44,25 +43,25 @@ let dexTokenHolderX = new DexTokenHolder(addresses.dex, tokenIds.X); let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y); tic('deploy & init token contracts'); -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { await tokenX.deploy(); await tokenY.deploy(); // pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves const accountFee = Mina.getNetworkConstants().accountCreationFee; - let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2); + let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 2); feePayerUpdate.send({ to: tokenX.self, amount: accountFee }); feePayerUpdate.send({ to: tokenY.self, amount: accountFee }); }); await tx.prove(); -await tx.sign([feePayerKey, keys.tokenX, keys.tokenY]).send(); +await tx.sign([feePayer.key, keys.tokenX, keys.tokenY]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); tic('deploy dex contracts'); -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts - AccountUpdate.createSigned(feePayerAddress).balance.subInPlace( + AccountUpdate.createSigned(feePayer).balance.subInPlace( Mina.getNetworkConstants().accountCreationFee.mul(3) ); await dex.deploy(); @@ -72,21 +71,21 @@ tx = await Mina.transaction(feePayerAddress, async () => { await tokenY.approveAccountUpdate(dexTokenHolderY.self); }); await tx.prove(); -await tx.sign([feePayerKey, keys.dex]).send(); +await tx.sign([feePayer.key, keys.dex]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); tic('transfer tokens to user'); let USER_DX = 1_000n; -tx = await Mina.transaction(feePayerAddress, async () => { +tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 user accounts - let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 3); - feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees + let au = AccountUpdate.fundNewAccount(feePayer, 3); + au.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees await tokenX.transfer(addresses.tokenX, addresses.user, UInt64.from(USER_DX)); await tokenY.transfer(addresses.tokenY, addresses.user, UInt64.from(USER_DX)); }); await tx.prove(); -await tx.sign([feePayerKey, keys.tokenX, keys.tokenY]).send(); +await tx.sign([feePayer.key, keys.tokenX, keys.tokenY]).send(); toc(); console.log('account updates length', tx.transaction.accountUpdates.length); [oldBalances, balances] = [balances, getTokenBalances()]; diff --git a/src/examples/zkapps/dex/run.ts b/src/examples/zkapps/dex/run.ts index 2b1c6d6a07..81e39dee3c 100644 --- a/src/examples/zkapps/dex/run.ts +++ b/src/examples/zkapps/dex/run.ts @@ -9,12 +9,11 @@ let Local = Mina.LocalBlockchain({ enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); -let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] = - Local.testAccounts; +let [feePayer] = Local.testAccounts; let tx, balances, oldBalances; console.log('-------------------------------------------------'); -console.log('FEE PAYER\t', feePayerAddress.toBase58()); +console.log('FEE PAYER\t', feePayer.toBase58()); console.log('TOKEN X ADDRESS\t', addresses.tokenX.toBase58()); console.log('TOKEN Y ADDRESS\t', addresses.tokenY.toBase58()); console.log('DEX ADDRESS\t', addresses.dex.toBase58()); @@ -38,8 +37,7 @@ Local = Mina.LocalBlockchain({ enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); -[{ privateKey: feePayerKey }] = Local.testAccounts; -feePayerAddress = feePayerKey.toPublicKey(); +feePayer = Local.testAccounts[0]; await main({ withVesting: true }); @@ -75,18 +73,18 @@ async function main({ withVesting }: { withVesting: boolean }) { let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y); console.log('deploy & init token contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { await tokenX.deploy(); await tokenY.deploy(); // pay fees for creating 2 token contract accounts, and fund them so each can create 1 account themselves const accountFee = Mina.getNetworkConstants().accountCreationFee; - let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2); + let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 2); feePayerUpdate.send({ to: tokenX.self, amount: accountFee.mul(2) }); feePayerUpdate.send({ to: tokenY.self, amount: accountFee.mul(2) }); }); await tx.prove(); - tx.sign([feePayerKey, keys.tokenX, keys.tokenY]); + tx.sign([feePayer.key, keys.tokenX, keys.tokenY]); await tx.send(); balances = getTokenBalances(); console.log( @@ -96,9 +94,9 @@ async function main({ withVesting }: { withVesting: boolean }) { ); console.log('deploy dex contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts - AccountUpdate.fundNewAccount(feePayerAddress, 3); + AccountUpdate.fundNewAccount(feePayer, 3); await dex.deploy(); await dexTokenHolderX.deploy(); await tokenX.approveAccountUpdate(dexTokenHolderX.self); @@ -106,29 +104,29 @@ async function main({ withVesting }: { withVesting: boolean }) { await tokenY.approveAccountUpdate(dexTokenHolderY.self); }); await tx.prove(); - tx.sign([feePayerKey, keys.dex]); + tx.sign([feePayer.key, keys.dex]); await tx.send(); console.log('transfer tokens to user'); tx = await Mina.transaction( { - sender: feePayerAddress, + sender: feePayer, fee: Mina.getNetworkConstants().accountCreationFee.mul(1), }, async () => { - let feePayer = AccountUpdate.fundNewAccount(feePayerAddress, 4); - feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees - feePayer.send({ to: addresses.user2, amount: 20e9 }); + let au = AccountUpdate.fundNewAccount(feePayer, 4); + au.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees + au.send({ to: addresses.user2, amount: 20e9 }); // transfer to fee payer so they can provide initial liquidity - await tokenX.transfer(addresses.tokenX, feePayerAddress, 10_000); - await tokenY.transfer(addresses.tokenY, feePayerAddress, 10_000); + await tokenX.transfer(addresses.tokenX, feePayer, 10_000); + await tokenY.transfer(addresses.tokenY, feePayer, 10_000); // mint tokens to the user (this is additional to the tokens minted at the beginning, so we can overflow the balance await tokenX.init2(); await tokenY.init2(); } ); await tx.prove(); - tx.sign([feePayerKey, keys.tokenX, keys.tokenY]); + tx.sign([feePayer.key, keys.tokenX, keys.tokenY]); await tx.send(); [oldBalances, balances] = [balances, getTokenBalances()]; console.log('User tokens (X, Y):', balances.user.X, balances.user.Y); @@ -138,16 +136,16 @@ async function main({ withVesting }: { withVesting: boolean }) { console.log('supply liquidity -- base'); tx = await Mina.transaction( { - sender: feePayerAddress, + sender: feePayer, fee: Mina.getNetworkConstants().accountCreationFee, }, async () => { - AccountUpdate.fundNewAccount(feePayerAddress); + AccountUpdate.fundNewAccount(feePayer); await dex.supplyLiquidityBase(UInt64.from(10_000), UInt64.from(10_000)); } ); await tx.prove(); - tx.sign([feePayerKey]); + tx.sign([feePayer.key]); await tx.send(); [oldBalances, balances] = [balances, getTokenBalances()]; console.log('DEX liquidity (X, Y):', balances.dex.X, balances.dex.Y); @@ -269,8 +267,8 @@ async function main({ withVesting }: { withVesting: boolean }) { * => a targeted test with explicitly constructed account updates might be the better strategy to test overflow */ console.log('prepare supplying overflowing liquidity'); - tx = await Mina.transaction(feePayerAddress, async () => { - AccountUpdate.fundNewAccount(feePayerAddress); + tx = await Mina.transaction(feePayer, async () => { + AccountUpdate.fundNewAccount(feePayer); await tokenY.transfer( addresses.tokenY, addresses.tokenX, @@ -278,7 +276,7 @@ async function main({ withVesting }: { withVesting: boolean }) { ); }); await tx.prove(); - await tx.sign([feePayerKey, keys.tokenY]).send(); + await tx.sign([feePayer.key, keys.tokenY]).send(); console.log('supply overflowing liquidity'); await expect(async () => { tx = await Mina.transaction(addresses.tokenX, async () => { diff --git a/src/examples/zkapps/dex/upgradability.ts b/src/examples/zkapps/dex/upgradability.ts index 72835d073d..2789437037 100644 --- a/src/examples/zkapps/dex/upgradability.ts +++ b/src/examples/zkapps/dex/upgradability.ts @@ -30,8 +30,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); - let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] = - Local.testAccounts; + let [feePayer] = Local.testAccounts; let tx, balances; let options = withVesting ? { lockedLiquiditySlots: 2 } : undefined; @@ -56,18 +55,18 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y); console.log('deploy & init token contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { await tokenX.deploy(); await tokenY.deploy(); // pay fees for creating 2 token contract accounts, and fund them so each can create 2 accounts themselves const accountFee = Mina.getNetworkConstants().accountCreationFee; - let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2); + let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 2); feePayerUpdate.send({ to: tokenX.self, amount: accountFee.mul(2) }); feePayerUpdate.send({ to: tokenY.self, amount: accountFee.mul(2) }); }); await tx.prove(); - tx.sign([feePayerKey, keys.tokenX, keys.tokenY]); + tx.sign([feePayer.key, keys.tokenX, keys.tokenY]); await tx.send(); balances = getTokenBalances(); console.log( @@ -91,9 +90,9 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { */ console.log('deploy dex contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts - AccountUpdate.fundNewAccount(feePayerAddress, 3); + AccountUpdate.fundNewAccount(feePayer, 3); await dex.deploy(); await dexTokenHolderX.deploy(); await tokenX.approveAccountUpdate(dexTokenHolderX.self); @@ -109,13 +108,13 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { dexAccount.requireSignature(); }); await tx.prove(); - tx.sign([feePayerKey, keys.dex]); + tx.sign([feePayer.key, keys.dex]); await tx.send(); console.log( 'trying to change delegate (setDelegate=impossible, should fail)' ); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // setting the delegate field to something, although permissions forbid it let dexAccount = AccountUpdate.create(addresses.dex); dexAccount.account.delegate.set(PrivateKey.random().toPublicKey()); @@ -123,13 +122,13 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { }); await tx.prove(); - await expect(tx.sign([feePayerKey, keys.dex]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key, keys.dex]).send()).rejects.toThrow( /Cannot update field 'delegate'/ ); console.log('changing delegate permission back to normal'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { let dexAccount = AccountUpdate.create(addresses.dex); dexAccount.account.permissions.set({ ...Permissions.initial(), @@ -138,18 +137,18 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { dexAccount.requireSignature(); }); await tx.prove(); - await tx.sign([feePayerKey, keys.dex]).send(); + await tx.sign([feePayer.key, keys.dex]).send(); console.log('changing delegate field to a new address'); let newDelegate = PrivateKey.random().toPublicKey(); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { let dexAccount = AccountUpdate.create(addresses.dex); dexAccount.account.delegate.set(newDelegate); dexAccount.requireSignature(); }); await tx.prove(); - await tx.sign([feePayerKey, keys.dex]).send(); + await tx.sign([feePayer.key, keys.dex]).send(); Mina.getAccount(addresses.dex).delegate?.assertEquals(newDelegate); @@ -170,7 +169,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { 'changing permission to impossible and then trying to change delegate field - in one transaction' ); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // changing the permission to impossible and then trying to change the delegate field let permissionUpdate = AccountUpdate.create(addresses.dex); @@ -185,7 +184,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { fieldUpdate.requireSignature(); }); await tx.prove(); - await expect(tx.sign([feePayerKey, keys.dex]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key, keys.dex]).send()).rejects.toThrow( /Cannot update field 'delegate'/ ); @@ -206,7 +205,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { console.log('creating multiple valid account updates in one transaction'); newDelegate = PrivateKey.random().toPublicKey(); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // changing field let fieldUpdate = AccountUpdate.create(addresses.dex); fieldUpdate.account.delegate.set(newDelegate); @@ -221,7 +220,7 @@ async function atomicActionsTest({ withVesting }: { withVesting: boolean }) { permissionUpdate2.requireSignature(); }); await tx.prove(); - await tx.sign([feePayerKey, keys.dex]).send(); + await tx.sign([feePayer.key, keys.dex]).send(); Mina.getAccount(addresses.dex).delegate?.assertEquals(newDelegate); DexProfiler.stop().store(); @@ -235,8 +234,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); - let [{ privateKey: feePayerKey, publicKey: feePayerAddress }] = - Local.testAccounts; + let [feePayer] = Local.testAccounts; let tx, balances, oldBalances; let options = withVesting ? { lockedLiquiditySlots: 2 } : undefined; @@ -267,18 +265,18 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { let dexTokenHolderY = new DexTokenHolder(addresses.dex, tokenIds.Y); console.log('deploy & init token contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { await tokenX.deploy(); await tokenY.deploy(); // pay fees for creating 2 token contract accounts, and fund them so each can create 2 accounts themselves const accountFee = Mina.getNetworkConstants().accountCreationFee; - let feePayerUpdate = AccountUpdate.fundNewAccount(feePayerAddress, 2); + let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 2); feePayerUpdate.send({ to: tokenX.self, amount: accountFee.mul(2) }); feePayerUpdate.send({ to: tokenY.self, amount: accountFee.mul(2) }); }); await tx.prove(); - tx.sign([feePayerKey, keys.tokenX, keys.tokenY]); + tx.sign([feePayer.key, keys.tokenX, keys.tokenY]); await tx.send(); balances = getTokenBalances(); console.log( @@ -306,9 +304,9 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { console.log('deploy dex contracts...'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts - AccountUpdate.fundNewAccount(feePayerAddress, 3); + AccountUpdate.fundNewAccount(feePayer, 3); await dex.deploy(); await dexTokenHolderX.deploy(); await tokenX.approveAccountUpdate(dexTokenHolderX.self); @@ -316,32 +314,32 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { await tokenY.approveAccountUpdate(dexTokenHolderY.self); }); await tx.prove(); - tx.sign([feePayerKey, keys.dex]); + tx.sign([feePayer.key, keys.dex]); await tx.send(); console.log('transfer tokens to user'); tx = await Mina.transaction( { - sender: feePayerAddress, + sender: feePayer, fee: Mina.getNetworkConstants().accountCreationFee.mul(1), }, async () => { - let feePayer = AccountUpdate.createSigned(feePayerAddress); - feePayer.balance.subInPlace( + let au = AccountUpdate.createSigned(feePayer); + au.balance.subInPlace( Mina.getNetworkConstants().accountCreationFee.mul(4) ); - feePayer.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees - feePayer.send({ to: addresses.user2, amount: 20e9 }); + au.send({ to: addresses.user, amount: 20e9 }); // give users MINA to pay fees + au.send({ to: addresses.user2, amount: 20e9 }); // transfer to fee payer so they can provide initial liquidity - await tokenX.transfer(addresses.tokenX, feePayerAddress, 10_000); - await tokenY.transfer(addresses.tokenY, feePayerAddress, 10_000); + await tokenX.transfer(addresses.tokenX, feePayer, 10_000); + await tokenY.transfer(addresses.tokenY, feePayer, 10_000); // mint tokens to the user (this is additional to the tokens minted at the beginning, so we can overflow the balance await tokenX.init2(); await tokenY.init2(); } ); await tx.prove(); - tx.sign([feePayerKey, keys.tokenX, keys.tokenY]); + tx.sign([feePayer.key, keys.tokenX, keys.tokenY]); await tx.send(); [oldBalances, balances] = [balances, getTokenBalances()]; console.log('User tokens (X, Y):', balances.user.X, balances.user.Y); @@ -366,7 +364,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { tokenIds.Y ); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { await modifiedDex.deploy(); await modifiedDexTokenHolderX.deploy(); await tokenX.approveAccountUpdate(modifiedDexTokenHolderX.self); @@ -374,7 +372,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { await tokenY.approveAccountUpdate(modifiedDexTokenHolderY.self); }); await tx.prove(); - tx.sign([feePayerKey, keys.dex]); + tx.sign([feePayer.key, keys.dex]); await tx.send(); // Making sure that both token holder accounts have been updated with the new modified verification key @@ -394,11 +392,11 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { console.log('supply liquidity -- base'); tx = await Mina.transaction( { - sender: feePayerAddress, + sender: feePayer, fee: Mina.getNetworkConstants().accountCreationFee.mul(1), }, async () => { - AccountUpdate.fundNewAccount(feePayerAddress); + AccountUpdate.fundNewAccount(feePayer); await modifiedDex.supplyLiquidityBase( UInt64.from(10_000), UInt64.from(10_000) @@ -406,7 +404,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { } ); await tx.prove(); - tx.sign([feePayerKey]); + tx.sign([feePayer.key]); await tx.send(); [oldBalances, balances] = [balances, getTokenBalances()]; console.log('DEX liquidity (X, Y):', balances.dex.X, balances.dex.Y); @@ -443,7 +441,7 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { console.log('changing upgrade permissions to impossible'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { // pay fees for creating 3 dex accounts let update = AccountUpdate.createSigned(addresses.dex); update.account.permissions.set({ @@ -455,16 +453,16 @@ async function upgradeabilityTests({ withVesting }: { withVesting: boolean }) { }); }); await tx.prove(); - tx.sign([feePayerKey, keys.dex]); + tx.sign([feePayer.key, keys.dex]); await tx.send(); console.log('trying to upgrade contract - should fail'); - tx = await Mina.transaction(feePayerAddress, async () => { + tx = await Mina.transaction(feePayer, async () => { await modifiedDex.deploy(); // cannot deploy new VK because its forbidden }); await tx.prove(); - await expect(tx.sign([feePayerKey, keys.dex]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key, keys.dex]).send()).rejects.toThrow( /Cannot update field 'verificationKey'/ ); diff --git a/src/examples/zkapps/hashing/run.ts b/src/examples/zkapps/hashing/run.ts index ac25f6868b..b164c3d41f 100644 --- a/src/examples/zkapps/hashing/run.ts +++ b/src/examples/zkapps/hashing/run.ts @@ -13,7 +13,7 @@ if (proofsEnabled) { } // test accounts that pays all the fees, and puts additional funds into the zkapp -const feePayer = Local.testAccounts[0]; +const [feePayer] = Local.testAccounts; // zkapp account const zkAppPrivateKey = PrivateKey.random(); @@ -24,11 +24,11 @@ const zkAppInstance = new HashStorage(zkAppAddress); const hashData = Bytes.from(Array.from({ length: 32 }, (_, i) => i)); console.log('Deploying Hash Example....'); -txn = await Mina.transaction(feePayer.publicKey, async () => { - AccountUpdate.fundNewAccount(feePayer.publicKey); +txn = await Mina.transaction(feePayer, async () => { + AccountUpdate.fundNewAccount(feePayer); await zkAppInstance.deploy(); }); -await txn.sign([feePayer.privateKey, zkAppPrivateKey]).send(); +await txn.sign([feePayer.key, zkAppPrivateKey]).send(); const initialState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); @@ -37,37 +37,37 @@ let currentState; console.log('Initial State', initialState); console.log(`Updating commitment from ${initialState} using SHA256 ...`); -txn = await Mina.transaction(feePayer.publicKey, async () => { +txn = await Mina.transaction(feePayer, async () => { await zkAppInstance.SHA256(hashData); }); await txn.prove(); -await txn.sign([feePayer.privateKey]).send(); +await txn.sign([feePayer.key]).send(); currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using SHA384 ...`); -txn = await Mina.transaction(feePayer.publicKey, async () => { +txn = await Mina.transaction(feePayer, async () => { await zkAppInstance.SHA384(hashData); }); await txn.prove(); -await txn.sign([feePayer.privateKey]).send(); +await txn.sign([feePayer.key]).send(); currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using SHA512 ...`); -txn = await Mina.transaction(feePayer.publicKey, async () => { +txn = await Mina.transaction(feePayer, async () => { await zkAppInstance.SHA512(hashData); }); await txn.prove(); -await txn.sign([feePayer.privateKey]).send(); +await txn.sign([feePayer.key]).send(); currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using Keccak256...`); -txn = await Mina.transaction(feePayer.publicKey, async () => { +txn = await Mina.transaction(feePayer, async () => { await zkAppInstance.Keccak256(hashData); }); await txn.prove(); -await txn.sign([feePayer.privateKey]).send(); +await txn.sign([feePayer.key]).send(); currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); diff --git a/src/examples/zkapps/hello-world/run.ts b/src/examples/zkapps/hello-world/run.ts index 929a5da800..49eab51489 100644 --- a/src/examples/zkapps/hello-world/run.ts +++ b/src/examples/zkapps/hello-world/run.ts @@ -11,26 +11,22 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); // test accounts that pays all the fees, and puts additional funds into the zkapp -const feePayer1 = Local.testAccounts[0]; -const feePayer2 = Local.testAccounts[1]; -const feePayer3 = Local.testAccounts[2]; -const feePayer4 = Local.testAccounts[3]; +const [feePayer1, feePayer2, feePayer3, feePayer4] = Local.testAccounts; // zkapp account -const zkAppPrivateKey = PrivateKey.random(); -const zkAppAddress = zkAppPrivateKey.toPublicKey(); -const zkAppInstance = new HelloWorld(zkAppAddress); +const zkAppAccount = Mina.TestAccount.random(); +const zkApp = new HelloWorld(zkAppAccount); console.log('Deploying Hello World ....'); -txn = await Mina.transaction(feePayer1.publicKey, async () => { - AccountUpdate.fundNewAccount(feePayer1.publicKey); - await zkAppInstance.deploy(); +txn = await Mina.transaction(feePayer1, async () => { + AccountUpdate.fundNewAccount(feePayer1); + await zkApp.deploy(); }); -await txn.sign([feePayer1.privateKey, zkAppPrivateKey]).send(); +await txn.sign([feePayer1.key, zkAppAccount.key]).send(); const initialState = - Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); let currentState; @@ -41,13 +37,13 @@ console.log( `Updating state from ${initialState} to 4 with Admin Private Key ...` ); -txn = await Mina.transaction(feePayer1.publicKey, async () => { - await zkAppInstance.update(Field(4), adminPrivateKey); +txn = await Mina.transaction(feePayer1, async () => { + await zkApp.update(Field(4), adminPrivateKey); }); await txn.prove(); -await txn.sign([feePayer1.privateKey]).send(); +await txn.sign([feePayer1.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); if (currentState !== '4') { throw Error( @@ -66,11 +62,11 @@ console.log( let correctlyFails = false; try { - txn = await Mina.transaction(feePayer1.publicKey, async () => { - await zkAppInstance.update(Field(16), wrongAdminPrivateKey); + txn = await Mina.transaction(feePayer1, async () => { + await zkApp.update(Field(16), wrongAdminPrivateKey); }); await txn.prove(); - await txn.sign([feePayer1.privateKey]).send(); + await txn.sign([feePayer1.key]).send(); } catch (err: any) { handleError(err, 'Account_delegate_precondition_unsatisfied'); } @@ -87,11 +83,11 @@ try { `Attempting to update state from ${currentState} to the value that fails precondition of 30 ...` ); - txn = await Mina.transaction(feePayer1.publicKey, async () => { - await zkAppInstance.update(Field(30), adminPrivateKey); + txn = await Mina.transaction(feePayer1, async () => { + await zkApp.update(Field(30), adminPrivateKey); }); await txn.prove(); - await txn.sign([feePayer1.privateKey]).send(); + await txn.sign([feePayer1.key]).send(); } catch (err: any) { handleError(err, 'assertEquals'); } @@ -111,14 +107,11 @@ try { ); // expected to fail and current state stays at 4 - txn = await Mina.transaction( - { sender: feePayer1.publicKey, fee: '10' }, - async () => { - await zkAppInstance.update(Field(256), adminPrivateKey); - } - ); + txn = await Mina.transaction({ sender: feePayer1, fee: '10' }, async () => { + await zkApp.update(Field(256), adminPrivateKey); + }); await txn.prove(); - await txn.sign([feePayer1.privateKey]).send(); + await txn.sign([feePayer1.key]).send(); } catch (err: any) { handleError(err, 'assertEquals'); } @@ -130,16 +123,13 @@ if (!correctlyFails) { } // expected to succeed and update state to 16 -txn2 = await Mina.transaction( - { sender: feePayer2.publicKey, fee: '2' }, - async () => { - await zkAppInstance.update(Field(16), adminPrivateKey); - } -); +txn2 = await Mina.transaction({ sender: feePayer2, fee: '2' }, async () => { + await zkApp.update(Field(16), adminPrivateKey); +}); await txn2.prove(); -await txn2.sign([feePayer2.privateKey]).send(); +await txn2.sign([feePayer2.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); if (currentState !== '16') { throw Error( @@ -150,16 +140,13 @@ if (currentState !== '16') { console.log(`Update successful. Current state is ${currentState}.`); // expected to succeed and update state to 256 -txn3 = await Mina.transaction( - { sender: feePayer3.publicKey, fee: '1' }, - async () => { - await zkAppInstance.update(Field(256), adminPrivateKey); - } -); +txn3 = await Mina.transaction({ sender: feePayer3, fee: '1' }, async () => { + await zkApp.update(Field(256), adminPrivateKey); +}); await txn3.prove(); -await txn3.sign([feePayer3.privateKey]).send(); +await txn3.sign([feePayer3.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); if (currentState !== '256') { throw Error( @@ -173,14 +160,11 @@ correctlyFails = false; try { // expected to fail and current state remains 256 - txn4 = await Mina.transaction( - { sender: feePayer4.publicKey, fee: '1' }, - async () => { - await zkAppInstance.update(Field(16), adminPrivateKey); - } - ); + txn4 = await Mina.transaction({ sender: feePayer4, fee: '1' }, async () => { + await zkApp.update(Field(16), adminPrivateKey); + }); await txn4.prove(); - await txn4.sign([feePayer4.privateKey]).send(); + await txn4.sign([feePayer4.key]).send(); } catch (err: any) { handleError(err, 'assertEquals'); } @@ -198,7 +182,7 @@ if (!correctlyFails) { */ function handleError(error: any, errorMessage: string) { - currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); if (error.message.includes(errorMessage)) { correctlyFails = true; diff --git a/src/examples/zkapps/local-events-zkapp.ts b/src/examples/zkapps/local-events-zkapp.ts index e3daf2b574..a5daf85d34 100644 --- a/src/examples/zkapps/local-events-zkapp.ts +++ b/src/examples/zkapps/local-events-zkapp.ts @@ -16,7 +16,7 @@ const doProofs = false; class Event extends Struct({ pub: PublicKey, value: Field }) {} -class SimpleZkapp extends SmartContract { +class Contract extends SmartContract { @state(Field) x = State(); events = { @@ -45,51 +45,48 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts; -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let contractAccount = Mina.TestAccount.random(); +let contract = new Contract(contractAccount); let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAddress); if (doProofs) { console.log('compile'); - await SimpleZkapp.compile(); + await Contract.compile(); } console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); console.log('call update'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.update(Field(1)); + await contract.update(Field(1)); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('call update'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.update(Field(2)); + await contract.update(Field(2)); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('---- emitted events: ----'); // fetches all events from zkapp starting block height 0 -let events = await zkapp.fetchEvents(UInt32.from(0)); +let events = await contract.fetchEvents(UInt32.from(0)); console.log(events); console.log('---- emitted events: ----'); // fetches all events from zkapp starting block height 0 and ending at block height 10 -events = await zkapp.fetchEvents(UInt32.from(0), UInt32.from(10)); +events = await contract.fetchEvents(UInt32.from(0), UInt32.from(10)); console.log(events); console.log('---- emitted events: ----'); // fetches all events -events = await zkapp.fetchEvents(); +events = await contract.fetchEvents(); console.log(events); diff --git a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts index c1adc8e17a..91996d9992 100644 --- a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts +++ b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts @@ -20,7 +20,6 @@ import { Mina, method, UInt32, - PrivateKey, AccountUpdate, MerkleTree, MerkleWitness, @@ -96,12 +95,9 @@ let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); let initialBalance = 10_000_000_000; -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +let [feePayer] = Local.testAccounts; -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let zkappAccount = Mina.TestAccount.random(); // this map serves as our off-chain in-memory storage let Accounts: Map = new Map( @@ -109,7 +105,7 @@ let Accounts: Map = new Map( return [ name as Names, new Account({ - publicKey: Local.testAccounts[index].publicKey, + publicKey: Local.testAccounts[index + 1], // `+ 1` is to avoid reusing the account aliased as `feePayer` points: UInt32.from(0), }), ]; @@ -128,20 +124,20 @@ Tree.setLeaf(3n, Accounts.get('Olivia')!.hash()); // now that we got our accounts set up, we need the commitment to deploy our contract! initialCommitment = Tree.getRoot(); -let leaderboardZkApp = new Leaderboard(zkappAddress); +let leaderboardZkApp = new Leaderboard(zkappAccount); console.log('Deploying leaderboard..'); if (doProofs) { await Leaderboard.compile(); } let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer).send({ - to: zkappAddress, + to: zkappAccount, amount: initialBalance, }); await leaderboardZkApp.deploy(); }); await tx.prove(); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, zkappAccount.key]).send(); console.log('Initial points: ' + Accounts.get('Bob')?.points); @@ -159,7 +155,7 @@ async function makeGuess(name: Names, index: bigint, guess: number) { await leaderboardZkApp.guessPreimage(Field(guess), account, witness); }); await tx.prove(); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappAccount.key]).send(); // if the transaction was successful, we can update our off-chain storage as well account.points = account.points.add(1); diff --git a/src/examples/zkapps/reducer/actions-as-merkle-list.ts b/src/examples/zkapps/reducer/actions-as-merkle-list.ts index 16ce8ea29c..558cbcc253 100644 --- a/src/examples/zkapps/reducer/actions-as-merkle-list.ts +++ b/src/examples/zkapps/reducer/actions-as-merkle-list.ts @@ -105,14 +105,9 @@ class ActionsContract extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); -let [ - { publicKey: sender, privateKey: senderKey }, - { publicKey: zkappAddress, privateKey: zkappKey }, - { publicKey: otherAddress }, - { publicKey: anotherAddress }, -] = Local.testAccounts; +let [sender, zkappAccount, otherAddress, anotherAddress] = Local.testAccounts; -let zkapp = new ActionsContract(zkappAddress); +let zkapp = new ActionsContract(zkappAccount); // deploy the contract @@ -122,19 +117,19 @@ console.log( (await ActionsContract.analyzeMethods()).assertContainsAddress.rows ); let deployTx = await Mina.transaction(sender, async () => zkapp.deploy()); -await deployTx.sign([senderKey, zkappKey]).send(); +await deployTx.sign([sender.key, zkappAccount.key]).send(); // push some actions let dispatchTx = await Mina.transaction(sender, async () => { await zkapp.postAddress(otherAddress); - await zkapp.postAddress(zkappAddress); + await zkapp.postAddress(zkappAccount); await zkapp.postTwoAddresses(anotherAddress, sender); await zkapp.postAddress(anotherAddress); - await zkapp.postTwoAddresses(zkappAddress, otherAddress); + await zkapp.postTwoAddresses(zkappAccount, otherAddress); }); await dispatchTx.prove(); -await dispatchTx.sign([senderKey]).send(); +await dispatchTx.sign([sender.key]).send(); assert(zkapp.reducer.getActions().length === 5); @@ -145,4 +140,4 @@ let containsTx = await Mina.transaction(sender, () => zkapp.assertContainsAddress(sender) ); await containsTx.prove(); -await containsTx.sign([senderKey]).send(); +await containsTx.sign([sender.key]).send(); diff --git a/src/examples/zkapps/reducer/map.ts b/src/examples/zkapps/reducer/map.ts index 70d7561ca5..2855dc1715 100644 --- a/src/examples/zkapps/reducer/map.ts +++ b/src/examples/zkapps/reducer/map.ts @@ -94,14 +94,11 @@ console.log(`method size for a "mapping" contract with ${k} entries`); console.log('get rows:', cs['get'].rows); console.log('set rows:', cs['set'].rows); -// a test account that pays all the fees -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +let [feePayer] = Local.testAccounts; // the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); -let zkapp = new StorageContract(zkappAddress); +let zkappAccount = Mina.TestAccount.random(); +let zkapp = new StorageContract(zkappAccount); await StorageContract.compile(); @@ -109,7 +106,7 @@ let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); await zkapp.deploy(); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, zkappAccount.key]).send(); console.log('deployed'); @@ -136,7 +133,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.set(key, value); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); key = map[1].key; value = map[1].value; @@ -146,7 +143,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.set(key, value); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); key = map[2].key; value = map[2].value; @@ -156,7 +153,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.set(key, value); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); key = map[0].key; value = map[0].value; @@ -167,7 +164,7 @@ tx = await Mina.transaction(feePayer, async () => { result = await zkapp.get(key); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); assert(result !== undefined); console.log('found correct match?', result.isSome.toBoolean()); @@ -181,7 +178,7 @@ tx = await Mina.transaction(feePayer, async () => { result = await zkapp.get(key); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('found correct match?', result.isSome.toBoolean()); console.log('matches expected value?', result.value.equals(value).toBoolean()); @@ -191,6 +188,6 @@ tx = await Mina.transaction(feePayer, async () => { result = await zkapp.get(PrivateKey.random().toPublicKey()); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('should be isSome(false)', result.isSome.toBoolean()); diff --git a/src/examples/zkapps/reducer/reducer-composite.ts b/src/examples/zkapps/reducer/reducer-composite.ts index b299d20e6e..7410a4aded 100644 --- a/src/examples/zkapps/reducer/reducer-composite.ts +++ b/src/examples/zkapps/reducer/reducer-composite.ts @@ -76,16 +76,13 @@ const initialCounter = Field(0); let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +let [feePayer] = Local.testAccounts; // the zkapp account -let zkappKey = PrivateKey.fromBase58( - 'EKEQc95PPQZnMY9d9p1vq1MWLeDJKtvKj4V75UDG3rjnf32BerWD' +let zkappAccount = new Mina.TestAccount( + PrivateKey.fromBase58('EKEQc95PPQZnMY9d9p1vq1MWLeDJKtvKj4V75UDG3rjnf32BerWD') ); -let zkappAddress = zkappKey.toPublicKey(); -let zkapp = new CounterZkapp(zkappAddress); +let zkapp = new CounterZkapp(zkappAccount); if (doProofs) { console.log('compile'); await CounterZkapp.compile(); @@ -98,7 +95,7 @@ let tx = await Mina.transaction(feePayer, async () => { zkapp.counter.set(initialCounter); zkapp.actionState.set(Reducer.initialActionState); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, zkappAccount.key]).send(); console.log('applying actions..'); @@ -108,21 +105,21 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.incrementCounter(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('action 2'); tx = await Mina.transaction(feePayer, async () => { await zkapp.incrementCounter(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('action 3'); tx = await Mina.transaction(feePayer, async () => { await zkapp.incrementCounter(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('rolling up pending actions..'); @@ -132,7 +129,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.rollupIncrements(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('state after rollup: ' + zkapp.counter.get()); assert.deepEqual(zkapp.counter.get().toString(), '3'); @@ -144,14 +141,14 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.dispatchData(Field.random()); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('action 5'); tx = await Mina.transaction(feePayer, async () => { await zkapp.incrementCounter(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('rolling up pending actions..'); @@ -161,7 +158,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.rollupIncrements(); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); console.log('state after rollup: ' + zkapp.counter.get()); assert.equal(zkapp.counter.get().toString(), '4'); diff --git a/src/examples/zkapps/set-local-preconditions-zkapp.ts b/src/examples/zkapps/set-local-preconditions-zkapp.ts index ba43b82cdc..b5451f2d5d 100644 --- a/src/examples/zkapps/set-local-preconditions-zkapp.ts +++ b/src/examples/zkapps/set-local-preconditions-zkapp.ts @@ -6,18 +6,11 @@ Changing preconditions might be useful for integration tests, when you want to t For example, you only want your smart contract to initiate a pay out when the `blockchainLength` is at a special height. (lock up period) */ -import { - method, - PrivateKey, - SmartContract, - Mina, - AccountUpdate, - UInt32, -} from 'o1js'; +import { method, SmartContract, Mina, AccountUpdate, UInt32 } from 'o1js'; const doProofs = false; -class SimpleZkapp extends SmartContract { +class Contract extends SmartContract { @method async blockheightEquals(y: UInt32) { let length = this.network.blockchainLength.get(); this.network.blockchainLength.requireEquals(length); @@ -29,57 +22,53 @@ class SimpleZkapp extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts; -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let contractAccount = Mina.TestAccount.random(); -let zkapp = new SimpleZkapp(zkappAddress); +let contract = new Contract(contractAccount); if (doProofs) { console.log('compile'); - await SimpleZkapp.compile(); + await Contract.compile(); } console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); let blockHeight: UInt32 = UInt32.zero; console.log('assert block height 0'); tx = await Mina.transaction(feePayer, async () => { // block height starts at 0 - await zkapp.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockheightEquals(UInt32.from(blockHeight)); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); blockHeight = UInt32.from(500); Local.setBlockchainLength(blockHeight); console.log('assert block height 500'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockheightEquals(UInt32.from(blockHeight)); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); blockHeight = UInt32.from(300); Local.setBlockchainLength(UInt32.from(5)); console.log('invalid block height precondition'); try { tx = await Mina.transaction(feePayer, async () => { - await zkapp.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockheightEquals(UInt32.from(blockHeight)); }); await tx.prove(); - await tx.sign([feePayerKey]).send(); + await tx.sign([feePayer.key]).send(); } catch (error) { console.log( `Expected to fail! block height is ${Local.getNetworkState().blockchainLength.toString()}, but trying to assert ${blockHeight.toString()}` diff --git a/src/examples/zkapps/simple-zkapp-payment.ts b/src/examples/zkapps/simple-zkapp-payment.ts index 90d54fdd6a..1c50fac6ea 100644 --- a/src/examples/zkapps/simple-zkapp-payment.ts +++ b/src/examples/zkapps/simple-zkapp-payment.ts @@ -2,13 +2,12 @@ import { method, Mina, AccountUpdate, - PrivateKey, SmartContract, UInt64, Permissions, } from 'o1js'; -class SendMINAExample extends SmartContract { +class Contract extends SmartContract { init() { super.init(); this.account.permissions.set({ @@ -31,72 +30,58 @@ class SendMINAExample extends SmartContract { } let proofsEnabled = false; -if (proofsEnabled) await SendMINAExample.compile(); +if (proofsEnabled) await Contract.compile(); let Local = Mina.LocalBlockchain({ proofsEnabled }); Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; - -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); - -let account1Key = PrivateKey.random(); -let account1Address = account1Key.toPublicKey(); - -let account2Key = PrivateKey.random(); -let account2Address = account2Key.toPublicKey(); +const [feePayer] = Local.testAccounts; +const [contractAccount, account1, account2] = Mina.TestAccount.random(3); function printBalances() { console.log( - `zkApp balance: ${Mina.getBalance(zkappAddress).div(1e9)} MINA` - ); - console.log( - `account1 balance: ${Mina.getBalance(account1Address).div(1e9)} MINA` - ); - console.log( - `account2 balance: ${Mina.getBalance(account2Address).div(1e9)} MINA\n` + `zkApp balance: ${Mina.getBalance(contractAccount).div(1e9)} MINA` ); + console.log(`account1 balance: ${Mina.getBalance(account1).div(1e9)} MINA`); + console.log(`account2 balance: ${Mina.getBalance(account2).div(1e9)} MINA\n`); } -let zkapp = new SendMINAExample(zkappAddress); +let zkapp = new Contract(contractAccount); let tx; console.log('deploy and fund user accounts'); tx = await Mina.transaction(feePayer, async () => { let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 3); - feePayerUpdate.send({ to: account1Address, amount: 2e9 }); - feePayerUpdate.send({ to: account2Address, amount: 0 }); // just touch account #2, so it's created + feePayerUpdate.send({ to: account1, amount: 2e9 }); + feePayerUpdate.send({ to: account2, amount: 0 }); // just touch account #2, so it's created await zkapp.deploy(); }); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); printBalances(); console.log('---------- deposit MINA into zkApp (with proof) ----------'); -tx = await Mina.transaction(account1Address, async () => { +tx = await Mina.transaction(account1, async () => { await zkapp.deposit(UInt64.from(1e9)); }); await tx.prove(); -await tx.sign([account1Key]).send(); +await tx.sign([account1.key]).send(); printBalances(); console.log('---------- send MINA from zkApp (with proof) ----------'); -tx = await Mina.transaction(account1Address, async () => { +tx = await Mina.transaction(account1, async () => { await zkapp.withdraw(UInt64.from(1e9)); }); await tx.prove(); -await tx.sign([account1Key]).send(); +await tx.sign([account1.key]).send(); printBalances(); console.log( '---------- send MINA between accounts (with signature) ----------' ); -tx = await Mina.transaction(account1Address, async () => { - let account1Update = AccountUpdate.createSigned(account1Address); - account1Update.send({ to: account2Address, amount: 1e9 }); +tx = await Mina.transaction(account1, async () => { + let account1Update = AccountUpdate.createSigned(account1); + account1Update.send({ to: account2, amount: 1e9 }); }); -await tx.sign([account1Key]).send(); +await tx.sign([account1.key]).send(); printBalances(); diff --git a/src/examples/zkapps/simple-zkapp-with-proof.ts b/src/examples/zkapps/simple-zkapp-with-proof.ts index aa098a19ce..493c47d79d 100644 --- a/src/examples/zkapps/simple-zkapp-with-proof.ts +++ b/src/examples/zkapps/simple-zkapp-with-proof.ts @@ -3,7 +3,6 @@ import { state, State, method, - PrivateKey, SmartContract, Mina, AccountUpdate, @@ -44,17 +43,10 @@ class NotSoSimpleZkapp extends SmartContract { let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp -let feePayerKey = Local.testAccounts[0].privateKey; -let feePayer = Local.testAccounts[0].publicKey; +let [feePayer] = Local.testAccounts; -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); - -// trivial zkapp account -let zkappKey2 = PrivateKey.random(); -let zkappAddress2 = zkappKey2.toPublicKey(); +const [trivialContractAccount, notSoSimpleContractAccount] = + Mina.TestAccount.random(2); // compile and prove trivial zkapp console.log('compile (trivial zkapp)'); @@ -65,7 +57,7 @@ let { verificationKey: trivialVerificationKey } = await TrivialZkapp.compile(); console.log('prove (trivial zkapp)'); let [trivialProof] = await ( await Mina.transaction(feePayer, async () => { - await new TrivialZkapp(zkappAddress2).proveSomething(Field(1)); + await new TrivialZkapp(notSoSimpleContractAccount).proveSomething(Field(1)); }) ).prove(); @@ -78,7 +70,7 @@ trivialProof = await testJsonRoundtripAndVerify( console.log('compile'); let { verificationKey } = await NotSoSimpleZkapp.compile(); -let zkapp = new NotSoSimpleZkapp(zkappAddress); +let zkapp = new NotSoSimpleZkapp(trivialContractAccount); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { @@ -86,14 +78,14 @@ let tx = await Mina.transaction(feePayer, async () => { await zkapp.deploy(); }); await tx.prove(); -await tx.sign([feePayerKey, zkappKey]).send(); +await tx.sign([feePayer.key, trivialContractAccount.key]).send(); console.log('initialize'); tx = await Mina.transaction(feePayer, async () => { await zkapp.initialize(trivialProof!); }); let [proof] = await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); proof = await testJsonRoundtripAndVerify( NotSoSimpleZkapp.Proof(), @@ -108,7 +100,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.update(Field(3), proof!, trivialProof!); }); [proof] = await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); proof = await testJsonRoundtripAndVerify( NotSoSimpleZkapp.Proof(), @@ -123,7 +115,7 @@ tx = await Mina.transaction(feePayer, async () => { await zkapp.update(Field(3), proof!, trivialProof!); }); [proof] = await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); proof = await testJsonRoundtripAndVerify( NotSoSimpleZkapp.Proof(), diff --git a/src/examples/zkapps/sudoku/index.ts b/src/examples/zkapps/sudoku/index.ts index 859762fa63..93373b36c9 100644 --- a/src/examples/zkapps/sudoku/index.ts +++ b/src/examples/zkapps/sudoku/index.ts @@ -6,7 +6,7 @@ import { AccountUpdate, Mina, PrivateKey } from 'o1js'; const Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -const { publicKey: account, privateKey: accountKey } = Local.testAccounts[0]; +const [account] = Local.testAccounts; const sudoku = generateSudoku(0.5); const zkAppPrivateKey = PrivateKey.random(); const zkAppAddress = zkAppPrivateKey.toPublicKey(); @@ -34,7 +34,7 @@ await tx.prove(); * (but `deploy()` changes some of those permissions to "proof" and adds the verification key that enables proofs. * that's why we don't need `tx.sign()` for the later transactions.) */ -await tx.sign([zkAppPrivateKey, accountKey]).send(); +await tx.sign([zkAppPrivateKey, account.key]).send(); console.log('Is the sudoku solved?', zkApp.isSolved.get().toBoolean()); @@ -51,7 +51,7 @@ try { await zkApp.submitSolution(Sudoku.from(sudoku), Sudoku.from(noSolution)); }); await tx.prove(); - await tx.sign([accountKey]).send(); + await tx.sign([account.key]).send(); } catch { console.log('There was an error submitting the solution, as expected'); } @@ -63,5 +63,5 @@ tx = await Mina.transaction(account, async () => { await zkApp.submitSolution(Sudoku.from(sudoku), Sudoku.from(solution!)); }); await tx.prove(); -await tx.sign([accountKey]).send(); +await tx.sign([account.key]).send(); console.log('Is the sudoku solved?', zkApp.isSolved.get().toBoolean()); diff --git a/src/examples/zkapps/token-with-proofs.ts b/src/examples/zkapps/token-with-proofs.ts index 37e0a3437f..e00744b629 100644 --- a/src/examples/zkapps/token-with-proofs.ts +++ b/src/examples/zkapps/token-with-proofs.ts @@ -2,7 +2,6 @@ import { method, Mina, AccountUpdate, - PrivateKey, SmartContract, PublicKey, TokenId, @@ -42,20 +41,11 @@ class ZkAppC extends SmartContract { let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -let [ - { publicKey: sender, privateKey: senderKey }, - { publicKey: tokenAccount1 }, -] = Local.testAccounts; +let [sender, tokenAccount1] = Local.testAccounts; let initialBalance = 10_000_000; -let tokenZkAppKey = PrivateKey.random(); -let tokenZkAppAddress = tokenZkAppKey.toPublicKey(); - -let zkAppCKey = PrivateKey.random(); -let zkAppCAddress = zkAppCKey.toPublicKey(); - -let zkAppBKey = PrivateKey.random(); -let zkAppBAddress = zkAppBKey.toPublicKey(); +const [tokenZkAppAddress, zkAppCAddress, zkAppBAddress] = + Mina.TestAccount.random(3); let tokenZkApp = new Token(tokenZkAppAddress); let tokenId = tokenZkApp.deriveTokenId(); @@ -86,7 +76,7 @@ tx = await Mina.transaction(sender, async () => { amount: initialBalance, }); }); -await tx.sign([senderKey, tokenZkAppKey]).send(); +await tx.sign([sender.key, tokenZkAppAddress.key]).send(); console.log('deploy zkAppB and zkAppC'); tx = await Mina.transaction(sender, async () => { @@ -97,14 +87,14 @@ tx = await Mina.transaction(sender, async () => { }); console.log('deploy zkAppB and zkAppC (proof)'); await tx.prove(); -await tx.sign([senderKey, zkAppBKey, zkAppCKey]).send(); +await tx.sign([sender.key, zkAppBAddress.key, zkAppCAddress.key]).send(); console.log('mint token to zkAppB'); tx = await Mina.transaction(sender, async () => { await tokenZkApp.mint(zkAppBAddress); }); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log('approve send from zkAppB'); tx = await Mina.transaction(sender, async () => { @@ -115,7 +105,7 @@ tx = await Mina.transaction(sender, async () => { }); console.log('approve send (proof)'); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log( `zkAppC's balance for tokenId: ${TokenId.toBase58(tokenId)}`, @@ -133,7 +123,7 @@ tx = await Mina.transaction(sender, async () => { }); console.log('approve send (proof)'); await tx.prove(); -await tx.sign([senderKey]).send(); +await tx.sign([sender.key]).send(); console.log( `tokenAccount1's balance for tokenId: ${TokenId.toBase58(tokenId)}`, diff --git a/src/examples/zkapps/voting/demo.ts b/src/examples/zkapps/voting/demo.ts index 1d2a77248d..81b105c63a 100644 --- a/src/examples/zkapps/voting/demo.ts +++ b/src/examples/zkapps/voting/demo.ts @@ -16,8 +16,7 @@ let Local = Mina.LocalBlockchain({ }); Mina.setActiveInstance(Local); -let feePayer = Local.testAccounts[0].publicKey; -let feePayerKey = Local.testAccounts[0].privateKey; +let [feePayer] = Local.testAccounts; let tx; @@ -75,7 +74,7 @@ tx = await Mina.transaction(feePayer, async () => { contracts.voterContract.committedMembers.set(voterStore.getRoot()); contracts.voterContract.accumulatedMembers.set(Reducer.initialActionState); }); -await tx.sign([feePayerKey, votingKey, candidateKey, voterKey]).send(); +await tx.sign([feePayer.key, votingKey, candidateKey, voterKey]).send(); let m: Member = Member.empty(); // lets register three voters @@ -95,7 +94,7 @@ tx = await Mina.transaction(feePayer, async () => { contracts.voting.voterRegistration(m); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); // lets register three voters tx = await Mina.transaction(feePayer, async () => { @@ -114,7 +113,7 @@ tx = await Mina.transaction(feePayer, async () => { contracts.voting.voterRegistration(m); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); // lets register three voters tx = await Mina.transaction(feePayer, async () => { @@ -133,7 +132,7 @@ tx = await Mina.transaction(feePayer, async () => { contracts.voting.voterRegistration(m); }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); /* since the voting contract calls the voter membership contract via invoking voterRegister, @@ -167,7 +166,7 @@ tx = await Mina.transaction(feePayer, async () => { }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); tx = await Mina.transaction(feePayer, async () => { // creating and registering 1 new candidate @@ -186,7 +185,7 @@ tx = await Mina.transaction(feePayer, async () => { }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); /* since the voting contact calls the candidate membership contract via invoking candidateRegister, @@ -228,7 +227,7 @@ tx = await Mina.transaction(feePayer, async () => { }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); for (let a of candidateStore.values()) { console.log(a.publicKey.toBase58()); @@ -263,7 +262,7 @@ tx = await Mina.transaction(feePayer, async () => { }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); // after the transaction went through, we have to update our off chain store as well vote(0n); @@ -282,7 +281,7 @@ tx = await Mina.transaction(feePayer, async () => { }); await tx.prove(); -await tx.sign([feePayerKey]).send(); +await tx.sign([feePayer.key]).send(); // vote dispatches a new sequence events, so we should have one diff --git a/src/examples/zkapps/voting/deploy-contracts.ts b/src/examples/zkapps/voting/deploy-contracts.ts index e14546ba50..3effe7b6e2 100644 --- a/src/examples/zkapps/voting/deploy-contracts.ts +++ b/src/examples/zkapps/voting/deploy-contracts.ts @@ -58,8 +58,7 @@ export async function deployContracts( }); Mina.setActiveInstance(Local); - let feePayerKey = Local.testAccounts[0].privateKey; - let feePayer = Local.testAccounts[0].publicKey; + let [feePayer] = Local.testAccounts; let { voterContract, candidateContract, voting } = contracts; console.log('deploying set of 3 contracts'); @@ -79,7 +78,12 @@ export async function deployContracts( voterContract.accumulatedMembers.set(Reducer.initialActionState); }); await tx - .sign([feePayerKey, params.votingKey, params.candidateKey, params.voterKey]) + .sign([ + feePayer.key, + params.votingKey, + params.candidateKey, + params.voterKey, + ]) .send(); console.log('successfully deployed contracts'); @@ -87,7 +91,7 @@ export async function deployContracts( voterContract, candidateContract, voting, - feePayer: feePayerKey, + feePayer: feePayer.key, Local, }; } @@ -124,8 +128,7 @@ export async function deployInvalidContracts( }); Mina.setActiveInstance(Local); - let feePayerKey = Local.testAccounts[0].privateKey; - let feePayer = Local.testAccounts[0].publicKey; + let [feePayer] = Local.testAccounts; let { voterContract, candidateContract, voting } = contracts; console.log('deploying set of 3 contracts'); @@ -155,7 +158,12 @@ export async function deployInvalidContracts( voterContract = invalidVoterContract as Membership_; }); await tx - .sign([feePayerKey, params.votingKey, params.candidateKey, params.voterKey]) + .sign([ + feePayer.key, + params.votingKey, + params.candidateKey, + params.voterKey, + ]) .send(); console.log('successfully deployed contracts'); @@ -163,7 +171,7 @@ export async function deployInvalidContracts( voterContract, candidateContract, voting, - feePayer: feePayerKey, + feePayer: feePayer.key, Local, }; } diff --git a/src/examples/zkapps/zkapp-self-update.ts b/src/examples/zkapps/zkapp-self-update.ts index e7d03c347a..dc0a6bd752 100644 --- a/src/examples/zkapps/zkapp-self-update.ts +++ b/src/examples/zkapps/zkapp-self-update.ts @@ -6,14 +6,13 @@ import { VerificationKey, method, Permissions, - PrivateKey, Mina, AccountUpdate, Provable, TransactionVersion, } from 'o1js'; -class Foo extends SmartContract { +class Contract extends SmartContract { init() { super.init(); this.account.permissions.set({ @@ -41,39 +40,38 @@ class Bar extends SmartContract { const Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); -const zkAppPrivateKey = PrivateKey.random(); -const zkAppAddress = zkAppPrivateKey.toPublicKey(); -const zkApp = new Foo(zkAppAddress); +const contractAccount = Mina.TestAccount.random(); +const contract = new Contract(contractAccount); -const { privateKey: deployerKey, publicKey: deployerAccount } = - Local.testAccounts[0]; +const [deployer] = Local.testAccounts; // deploy first verification key -await Foo.compile(); +await Contract.compile(); -const tx = await Mina.transaction(deployerAccount, async () => { - AccountUpdate.fundNewAccount(deployerAccount); - await zkApp.deploy(); +const tx = await Mina.transaction(deployer, async () => { + AccountUpdate.fundNewAccount(deployer); + await contract.deploy(); }); await tx.prove(); -await tx.sign([deployerKey, zkAppPrivateKey]).send(); +await tx.sign([deployer.key, contractAccount.key]).send(); -const fooVerificationKey = Mina.getAccount(zkAppAddress).zkapp?.verificationKey; +const fooVerificationKey = + Mina.getAccount(contractAccount).zkapp?.verificationKey; Provable.log('original verification key', fooVerificationKey); // update verification key const { verificationKey: barVerificationKey } = await Bar.compile(); -const tx2 = await Mina.transaction(deployerAccount, async () => { - await zkApp.replaceVerificationKey(barVerificationKey); +const tx2 = await Mina.transaction(deployer, async () => { + await contract.replaceVerificationKey(barVerificationKey); }); await tx2.prove(); -await tx2.sign([deployerKey]).send(); +await tx2.sign([deployer.key]).send(); const updatedVerificationKey = - Mina.getAccount(zkAppAddress).zkapp?.verificationKey; + Mina.getAccount(contractAccount).zkapp?.verificationKey; // should be different from Foo Provable.log('updated verification key', updatedVerificationKey); diff --git a/src/lib/mina/account-update-layout.unit-test.ts b/src/lib/mina/account-update-layout.unit-test.ts index 2cce42f4b7..2c58c6db47 100644 --- a/src/lib/mina/account-update-layout.unit-test.ts +++ b/src/lib/mina/account-update-layout.unit-test.ts @@ -29,30 +29,27 @@ class NestedCall extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); -let [ - { publicKey: sender, privateKey: senderKey }, - { publicKey: zkappAddress, privateKey: zkappKey }, -] = Local.testAccounts; +let [sender, zkappAccount] = Local.testAccounts; await NestedCall.compile(); -let zkapp = new NestedCall(zkappAddress); +let zkapp = new NestedCall(zkappAccount); // deploy zkapp await (await Mina.transaction(sender, () => zkapp.deploy())) - .sign([zkappKey, senderKey]) + .sign([zkappAccount.key, sender.key]) .send(); // deposit call -let balanceBefore = Mina.getBalance(zkappAddress); +let balanceBefore = Mina.getBalance(zkappAccount); let depositTx = await Mina.transaction(sender, () => zkapp.deposit()); console.log(depositTx.toPretty()); await depositTx.prove(); -await depositTx.sign([senderKey]).send(); +await depositTx.sign([sender.key]).send(); -Mina.getBalance(zkappAddress).assertEquals(balanceBefore.add(1)); +Mina.getBalance(zkappAccount).assertEquals(balanceBefore.add(1)); // deposit call using tree @@ -61,6 +58,6 @@ balanceBefore = balanceBefore.add(1); depositTx = await Mina.transaction(sender, () => zkapp.depositUsingTree()); console.log(depositTx.toPretty()); await depositTx.prove(); -await depositTx.sign([senderKey]).send(); +await depositTx.sign([sender.key]).send(); -Mina.getBalance(zkappAddress).assertEquals(balanceBefore.add(1)); +Mina.getBalance(zkappAccount).assertEquals(balanceBefore.add(1)); diff --git a/src/lib/mina/account-update.unit-test.ts b/src/lib/mina/account-update.unit-test.ts index 7f44a5dace..602f365289 100644 --- a/src/lib/mina/account-update.unit-test.ts +++ b/src/lib/mina/account-update.unit-test.ts @@ -110,7 +110,7 @@ function createAccountUpdate() { let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); - const feePayer = Local.testAccounts[0].publicKey; + const [feePayer] = Local.testAccounts; let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 0d600332b5..a4487f7db7 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -13,6 +13,7 @@ import { Actions, } from './account-update.js'; import { NetworkId } from '../../mina-signer/src/types.js'; +import { TupleN } from '../util/types.js'; import { Types, TypesBigint } from '../../bindings/mina-transaction/types.js'; import { invalidTransactionError } from './errors.js'; import { @@ -39,7 +40,23 @@ import { verifyAccountUpdate, } from './transaction-validation.js'; -export { LocalBlockchain }; +export { LocalBlockchain, TestAccount }; + +class TestAccount extends PublicKey { + static random( + count: N = 1 as never + ): N extends 1 ? TestAccount : TupleN { + if (count === 1) return new this(PrivateKey.random()) as never; + return Array.from( + { length: count as number }, + () => new this(PrivateKey.random()) + ) as never; + } + + constructor(readonly key: PrivateKey) { + super(key.toPublicKey()); + } +} /** * A mock Mina blockchain running locally and useful for testing. */ @@ -59,18 +76,14 @@ function LocalBlockchain({ ledger.addAccount(Ml.fromPublicKey(publicKey), balance); } - let testAccounts: { - publicKey: PublicKey; - privateKey: PrivateKey; - }[] = []; + let testAccounts = [] as never as TupleN; - for (let i = 0; i < 10; ++i) { + for (let i = 0; i < 100; ++i) { let MINA = 10n ** 9n; const largeValue = 1000n * MINA; - const k = PrivateKey.random(); - const pk = k.toPublicKey(); - addAccount(pk, largeValue.toString()); - testAccounts.push({ privateKey: k, publicKey: pk }); + const testAccount = new TestAccount(PrivateKey.random()); + addAccount(testAccount, largeValue.toString()); + testAccounts.push(testAccount); } const events: Record = {}; diff --git a/src/lib/mina/mina.ts b/src/lib/mina/mina.ts index 285bf7e181..8977c32c60 100644 --- a/src/lib/mina/mina.ts +++ b/src/lib/mina/mina.ts @@ -50,7 +50,7 @@ import { defaultNetworkState, filterGroups, } from './transaction-validation.js'; -import { LocalBlockchain } from './local-blockchain.js'; +import { LocalBlockchain, TestAccount } from './local-blockchain.js'; export { LocalBlockchain, @@ -62,6 +62,7 @@ export { type RejectedTransaction, type PendingTransactionStatus, type PendingTransactionPromise, + TestAccount, activeInstance, setActiveInstance, transaction, diff --git a/src/lib/mina/precondition.test.ts b/src/lib/mina/precondition.test.ts index 34b441629c..09525bb378 100644 --- a/src/lib/mina/precondition.test.ts +++ b/src/lib/mina/precondition.test.ts @@ -18,27 +18,24 @@ class MyContract extends SmartContract { } let zkappKey: PrivateKey; -let zkappAddress: PublicKey; +let zkappAddress: Mina.TestAccount; let zkapp: MyContract; -let feePayer: PublicKey; -let feePayerKey: PrivateKey; +let feePayer: Mina.TestAccount; beforeAll(async () => { // set up local blockchain, create zkapp keys, deploy the contract let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); - feePayerKey = Local.testAccounts[0].privateKey; - feePayer = Local.testAccounts[0].publicKey; + [feePayer] = Local.testAccounts; - zkappKey = PrivateKey.random(); - zkappAddress = zkappKey.toPublicKey(); + zkappAddress = Mina.TestAccount.random(); zkapp = new MyContract(zkappAddress); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); await zkapp.deploy(); }); - tx.sign([feePayerKey, zkappKey]).send(); + tx.sign([feePayer.key, zkappKey]).send(); }); describe('preconditions', () => { @@ -67,7 +64,7 @@ describe('preconditions', () => { } AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappKey]).send(); // check that tx was applied, by checking nonce was incremented expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); @@ -94,7 +91,7 @@ describe('preconditions', () => { zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappKey]).send(); // check that tx was applied, by checking nonce was incremented expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); @@ -109,7 +106,7 @@ describe('preconditions', () => { zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappKey]).send(); expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); @@ -123,7 +120,7 @@ describe('preconditions', () => { zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappKey]).send(); // check that tx was applied, by checking nonce was incremented expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); @@ -150,7 +147,7 @@ describe('preconditions', () => { zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey, zkappKey]).send(); + await tx.sign([feePayer.key, zkappKey]).send(); // check that tx was applied, by checking nonce was incremented expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); }); @@ -163,7 +160,7 @@ describe('preconditions', () => { precondition().requireEquals(p.add(1) as any); AccountUpdate.attachToTransaction(zkapp.self); }); - await tx.sign([feePayerKey]).send(); + await tx.sign([feePayer.key]).send(); }).rejects.toThrow(/unsatisfied/); } }); @@ -175,7 +172,7 @@ describe('preconditions', () => { precondition().requireEquals(p.not()); AccountUpdate.attachToTransaction(zkapp.self); }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /unsatisfied/ ); } @@ -187,7 +184,7 @@ describe('preconditions', () => { zkapp.account.delegate.requireEquals(publicKey); AccountUpdate.attachToTransaction(zkapp.self); }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow(/unsatisfied/); + await expect(tx.sign([feePayer.key]).send()).rejects.toThrow(/unsatisfied/); }); it('unsatisfied requireBetween should be rejected', async () => { @@ -197,7 +194,7 @@ describe('preconditions', () => { precondition().requireBetween(p.add(20), p.add(30)); AccountUpdate.attachToTransaction(zkapp.self); }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /unsatisfied/ ); } @@ -208,7 +205,7 @@ describe('preconditions', () => { zkapp.currentSlot.requireBetween(UInt32.from(20), UInt32.from(30)); AccountUpdate.attachToTransaction(zkapp.self); }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow(/unsatisfied/); + await expect(tx.sign([feePayer.key]).send()).rejects.toThrow(/unsatisfied/); }); // TODO: is this a gotcha that should be addressed? @@ -220,7 +217,7 @@ describe('preconditions', () => { zkapp.requireSignature(); AccountUpdate.attachToTransaction(zkapp.self); }); - expect(() => tx.sign([zkappKey, feePayerKey]).send()).toThrow(); + expect(() => tx.sign([zkappKey, feePayer.key]).send()).toThrow(); }); }); diff --git a/src/lib/mina/token.test.ts b/src/lib/mina/token.test.ts index eafa963a35..3bfa15f76e 100644 --- a/src/lib/mina/token.test.ts +++ b/src/lib/mina/token.test.ts @@ -5,7 +5,6 @@ import { Bool, SmartContract, Mina, - PrivateKey, AccountUpdate, method, PublicKey, @@ -102,13 +101,13 @@ class TokenContract extends TokenContractBase { } } -class ZkAppB extends SmartContract { +class ContractB extends SmartContract { @method async approveSend(amount: UInt64) { this.balance.subInPlace(amount); } } -class ZkAppC extends SmartContract { +class ContractC extends SmartContract { @method async approveSend(amount: UInt64) { this.balance.subInPlace(amount); } @@ -120,20 +119,17 @@ class ZkAppC extends SmartContract { } } -let feePayerKey: PrivateKey; -let feePayer: PublicKey; -let tokenZkappKey: PrivateKey; -let tokenZkappAddress: PublicKey; -let tokenZkapp: TokenContract; +let feePayer: Mina.TestAccount; + +let tokenContractAccount: Mina.TestAccount; +let tokenContract: TokenContract; let tokenId: Field; -let zkAppBKey: PrivateKey; -let zkAppBAddress: PublicKey; -let zkAppB: ZkAppB; +let contractBAccount: Mina.TestAccount; +let contractB: ContractB; -let zkAppCKey: PrivateKey; -let zkAppCAddress: PublicKey; -let zkAppC: ZkAppC; +let contractCAccount: Mina.TestAccount; +let contractC: ContractC; function setupAccounts() { let Local = Mina.LocalBlockchain({ @@ -141,56 +137,57 @@ function setupAccounts() { enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); - feePayerKey = Local.testAccounts[0].privateKey; - feePayer = Local.testAccounts[0].publicKey; - - tokenZkappKey = PrivateKey.random(); - tokenZkappAddress = tokenZkappKey.toPublicKey(); - - tokenZkapp = new TokenContract(tokenZkappAddress); - tokenId = tokenZkapp.deriveTokenId(); - - zkAppBKey = Local.testAccounts[1].privateKey; - zkAppBAddress = zkAppBKey.toPublicKey(); - zkAppB = new ZkAppB(zkAppBAddress, tokenId); - - zkAppCKey = Local.testAccounts[2].privateKey; - zkAppCAddress = zkAppCKey.toPublicKey(); - zkAppC = new ZkAppC(zkAppCAddress, tokenId); + [feePayer, contractBAccount, contractCAccount] = Local.testAccounts; + tokenContractAccount = Mina.TestAccount.random(); + tokenContract = new TokenContract(tokenContractAccount); + tokenId = tokenContract.deriveTokenId(); + contractB = new ContractB(contractBAccount, tokenId); + contractC = new ContractC(contractCAccount, tokenId); return Local; } async function setupLocal() { setupAccounts(); let tx = await Mina.transaction(feePayer, async () => { - await tokenZkapp.deploy(); + await tokenContract.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer); feePayerUpdate.send({ - to: tokenZkapp.self, + to: tokenContract.self, amount: Mina.getNetworkConstants().accountCreationFee, }); }); - tx.sign([tokenZkappKey, feePayerKey]); + tx.sign([tokenContractAccount.key, feePayer.key]); await tx.send(); } async function setupLocalProofs() { let Local = setupAccounts(); - zkAppC = new ZkAppC(zkAppCAddress, tokenId); + contractC = new ContractC(contractCAccount, tokenId); // don't use proofs for the setup, takes too long to do this every time Local.setProofsEnabled(false); let tx = await Mina.transaction({ sender: feePayer }, async () => { - await tokenZkapp.deploy(); + await tokenContract.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 3); feePayerUpdate.send({ - to: tokenZkapp.self, + to: tokenContract.self, amount: Mina.getNetworkConstants().accountCreationFee, }); - await tokenZkapp.deployZkapp(zkAppBAddress, ZkAppB._verificationKey!); - await tokenZkapp.deployZkapp(zkAppCAddress, ZkAppC._verificationKey!); + await tokenContract.deployZkapp( + contractBAccount, + ContractB._verificationKey! + ); + await tokenContract.deployZkapp( + contractCAccount, + ContractC._verificationKey! + ); }); await tx.prove(); - tx.sign([tokenZkappKey, zkAppBKey, zkAppCKey, feePayerKey]); + tx.sign([ + tokenContractAccount.key, + contractBAccount.key, + contractCAccount.key, + feePayer.key, + ]); await tx.send(); Local.setProofsEnabled(true); } @@ -198,8 +195,8 @@ async function setupLocalProofs() { describe('Token', () => { beforeAll(async () => { await TokenContract.compile(); - await ZkAppB.compile(); - await ZkAppC.compile(); + await ContractB.compile(); + await ContractC.compile(); }); describe('Signature Authorization', () => { @@ -218,23 +215,23 @@ describe('Token', () => { }); test('correct token id can be derived with an existing token owner', () => { - expect(tokenId).toEqual(TokenId.derive(tokenZkappAddress)); + expect(tokenId).toEqual(TokenId.derive(tokenContractAccount)); }); test('deployed token contract exists in the ledger', () => { - expect(Mina.getAccount(tokenZkappAddress, tokenId)).toBeDefined(); + expect(Mina.getAccount(tokenContractAccount, tokenId)).toBeDefined(); }); test('setting a valid token symbol on a token contract', async () => { await ( await Mina.transaction({ sender: feePayer }, async () => { - let tokenZkapp = AccountUpdate.createSigned(tokenZkappAddress); + let tokenZkapp = AccountUpdate.createSigned(tokenContractAccount); tokenZkapp.account.tokenSymbol.set(tokenSymbol); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); - const symbol = Mina.getAccount(tokenZkappAddress).tokenSymbol; + const symbol = Mina.getAccount(tokenContractAccount).tokenSymbol; expect(tokenSymbol).toBeDefined(); expect(symbol).toEqual(tokenSymbol); }); @@ -256,22 +253,25 @@ describe('Token', () => { await ( await Mina.transaction({ sender: feePayer }, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(100_000n); }); test('minting should fail if overflow occurs ', async () => { await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000_000_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint( + contractBAccount, + UInt64.from(100_000_000_000) + ); + tokenContract.requireSignature(); }).catch((e) => { expect(e).toBeDefined(); }); @@ -293,22 +293,22 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); await ( await Mina.transaction(feePayer, async () => { - await tokenZkapp.burn(zkAppBAddress, UInt64.from(10_000)); - tokenZkapp.requireSignature(); + await tokenContract.burn(contractBAccount, UInt64.from(10_000)); + tokenContract.requireSignature(); }) ) - .sign([zkAppBKey, feePayerKey, tokenZkappKey]) + .sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]) .send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(90_000n); }); @@ -316,18 +316,18 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(1_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(1_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - await tokenZkapp.burn(zkAppBAddress, UInt64.from(10_000)); - tokenZkapp.requireSignature(); + await tokenContract.burn(contractBAccount, UInt64.from(10_000)); + tokenContract.requireSignature(); }) - ).sign([zkAppBKey, feePayerKey, tokenZkappKey]); + ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); await expect(tx.send()).rejects.toThrow(); }); }); @@ -348,29 +348,34 @@ describe('Token', () => { test('change the balance of a token account after sending', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }); - await tx.sign([feePayerKey, tokenZkappKey]).send(); + await tx.sign([feePayer.key, tokenContractAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenZkapp.internal.send({ - from: zkAppBAddress, - to: zkAppCAddress, + tokenContract.internal.send({ + from: contractBAccount, + to: contractCAccount, amount: UInt64.from(10_000), }); - AccountUpdate.attachToTransaction(tokenZkapp.self); - tokenZkapp.requireSignature(); + AccountUpdate.attachToTransaction(tokenContract.self); + tokenContract.requireSignature(); }); - tx.sign([zkAppBKey, zkAppCKey, feePayerKey, tokenZkappKey]); + tx.sign([ + contractBAccount.key, + contractCAccount.key, + feePayer.key, + tokenContractAccount.key, + ]); await tx.send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(90_000n); expect( - Mina.getBalance(zkAppCAddress, tokenId).value.toBigInt() + Mina.getBalance(contractCAccount, tokenId).value.toBigInt() ).toEqual(10_000n); }); @@ -378,23 +383,23 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenZkapp.internal.send({ - from: zkAppBAddress, - to: zkAppCAddress, + tokenContract.internal.send({ + from: contractBAccount, + to: contractCAccount, amount: UInt64.from(10_000), }); - AccountUpdate.attachToTransaction(tokenZkapp.self); - tokenZkapp.requireSignature(); + AccountUpdate.attachToTransaction(tokenContract.self); + tokenContract.requireSignature(); }) - ).sign([zkAppBKey, feePayerKey, tokenZkappKey]); + ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); await expect(tx.send()).rejects.toThrow(); }); @@ -403,23 +408,23 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenZkapp.internal.send({ - from: zkAppBAddress, - to: zkAppCAddress, + tokenContract.internal.send({ + from: contractBAccount, + to: contractCAccount, amount: UInt64.from(100_000), }); - AccountUpdate.attachToTransaction(tokenZkapp.self); - tokenZkapp.requireSignature(); + AccountUpdate.attachToTransaction(tokenContract.self); + tokenContract.requireSignature(); }) - ).sign([zkAppBKey, feePayerKey, tokenZkappKey]); + ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); await expect(tx.send()).rejects.toThrow(); }); }); @@ -441,12 +446,12 @@ describe('Token', () => { }); test('should successfully deploy a token account under a zkApp', async () => { - expect(Mina.getAccount(zkAppBAddress, tokenId)).toBeDefined(); - expect(Mina.getAccount(zkAppBAddress, tokenId).tokenId).toEqual( + expect(Mina.getAccount(contractBAccount, tokenId)).toBeDefined(); + expect(Mina.getAccount(contractBAccount, tokenId).tokenId).toEqual( tokenId ); - expect(Mina.getAccount(zkAppCAddress, tokenId)).toBeDefined(); - expect(Mina.getAccount(zkAppCAddress, tokenId).tokenId).toEqual( + expect(Mina.getAccount(contractCAccount, tokenId)).toBeDefined(); + expect(Mina.getAccount(contractCAccount, tokenId).tokenId).toEqual( tokenId ); }); @@ -466,13 +471,13 @@ describe('Token', () => { test('token contract can successfully mint and updates the balances in the ledger (proof)', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); }); await tx.prove(); - tx.sign([tokenZkappKey, feePayerKey]); + tx.sign([tokenContractAccount.key, feePayer.key]); await tx.send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(100_000n); }); }); @@ -491,18 +496,18 @@ describe('Token', () => { test('token contract can successfully burn and updates the balances in the ledger (proof)', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }); - await tx.sign([feePayerKey, tokenZkappKey]).send(); + await tx.sign([feePayer.key, tokenContractAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { - await tokenZkapp.burn(zkAppBAddress, UInt64.from(10_000)); + await tokenContract.burn(contractBAccount, UInt64.from(10_000)); }); await tx.prove(); - tx.sign([zkAppBKey, feePayerKey]); + tx.sign([contractBAccount.key, feePayer.key]); await tx.send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(90_000n); }); }); @@ -522,51 +527,51 @@ describe('Token', () => { test('should approve and the balance of a token account after sending', async () => { let tx = await Mina.transaction(feePayer, async () => { - await tokenZkapp.mint(zkAppBAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }); await tx.prove(); - await tx.sign([feePayerKey, tokenZkappKey]).send(); + await tx.sign([feePayer.key, tokenContractAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { - await zkAppB.approveSend(UInt64.from(10_000)); + await contractB.approveSend(UInt64.from(10_000)); - await tokenZkapp.approveTransfer( - zkAppBAddress, - zkAppCAddress, + await tokenContract.approveTransfer( + contractBAccount, + contractCAccount, UInt64.from(10_000), - zkAppB.self + contractB.self ); }); await tx.prove(); - await tx.sign([feePayerKey]).send(); + await tx.sign([feePayer.key]).send(); expect( - Mina.getBalance(zkAppBAddress, tokenId).value.toBigInt() + Mina.getBalance(contractBAccount, tokenId).value.toBigInt() ).toEqual(90_000n); expect( - Mina.getBalance(zkAppCAddress, tokenId).value.toBigInt() + Mina.getBalance(contractCAccount, tokenId).value.toBigInt() ).toEqual(10_000n); }); test('should fail to approve with an incorrect layout', async () => { await ( await Mina.transaction(feePayer, async () => { - await tokenZkapp.mint(zkAppCAddress, UInt64.from(100_000)); - tokenZkapp.requireSignature(); + await tokenContract.mint(contractCAccount, UInt64.from(100_000)); + tokenContract.requireSignature(); }) ) - .sign([feePayerKey, tokenZkappKey]) + .sign([feePayer.key, tokenContractAccount.key]) .send(); await expect(() => Mina.transaction(feePayer, async () => { - await zkAppC.approveIncorrectLayout(UInt64.from(10_000)); - await tokenZkapp.approveTransfer( - zkAppBAddress, - zkAppCAddress, + await contractC.approveIncorrectLayout(UInt64.from(10_000)); + await tokenContract.approveTransfer( + contractBAccount, + contractCAccount, UInt64.from(10_000), - zkAppC.self + contractC.self ); }) ).rejects.toThrow(); @@ -575,13 +580,13 @@ describe('Token', () => { test('should reject tx if user bypasses the token contract by using an empty account update', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenZkapp.internal.mint({ - address: zkAppBAddress, + tokenContract.internal.mint({ + address: contractBAccount, amount: UInt64.from(100_000), }); - AccountUpdate.attachToTransaction(tokenZkapp.self); + AccountUpdate.attachToTransaction(tokenContract.self); }); - await expect(tx.sign([feePayerKey]).send()).rejects.toThrow( + await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /Update_not_permitted_access/ ); }); diff --git a/src/lib/mina/token/token-contract.unit-test.ts b/src/lib/mina/token/token-contract.unit-test.ts index def7ecd3c7..28db84f220 100644 --- a/src/lib/mina/token/token-contract.unit-test.ts +++ b/src/lib/mina/token/token-contract.unit-test.ts @@ -35,10 +35,7 @@ class ExampleTokenContract extends TokenContract { let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); -let [ - { publicKey: sender, privateKey: senderKey }, - { publicKey: otherAddress, privateKey: otherKey }, -] = Local.testAccounts; +let [sender, other] = Local.testAccounts; let { publicKey: tokenAddress, privateKey: tokenKey } = PrivateKey.randomKeypair(); @@ -51,7 +48,7 @@ let deployTx = await Mina.transaction(sender, async () => { await token.deploy(); }); await deployTx.prove(); -await deployTx.sign([tokenKey, senderKey]).send(); +await deployTx.sign([tokenKey, sender.key]).send(); assert( Mina.getAccount(tokenAddress).zkapp?.verificationKey !== undefined, @@ -61,22 +58,22 @@ assert( // can transfer tokens between two accounts let transferTx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); - await token.transfer(tokenAddress, otherAddress, UInt64.one); + await token.transfer(tokenAddress, other, UInt64.one); }); await transferTx.prove(); -await transferTx.sign([tokenKey, senderKey]).send(); +await transferTx.sign([tokenKey, sender.key]).send(); -Mina.getBalance(otherAddress, tokenId).assertEquals(UInt64.one); +Mina.getBalance(other, tokenId).assertEquals(UInt64.one); // fails to approve a deep account update tree with correct token permissions, but a non-zero balance sum -let update1 = AccountUpdate.create(otherAddress); +let update1 = AccountUpdate.create(other); update1.body.mayUseToken = AccountUpdate.MayUseToken.ParentsOwnToken; -let update2 = AccountUpdate.create(otherAddress); +let update2 = AccountUpdate.create(other); update2.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent; update2.body.callDepth = 1; -let update3 = AccountUpdate.create(otherAddress, tokenId); +let update3 = AccountUpdate.create(other, tokenId); update3.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent; update3.balanceChange = Int64.one; update3.body.callDepth = 2; @@ -89,7 +86,7 @@ await assert.rejects( ); // succeeds to approve deep account update tree with zero balance sum -let update4 = AccountUpdate.createSigned(otherAddress, tokenId); +let update4 = AccountUpdate.createSigned(other, tokenId); update4.body.mayUseToken = AccountUpdate.MayUseToken.InheritFromParent; update4.balanceChange = Int64.minusOne; update4.body.callDepth = 2; @@ -103,4 +100,4 @@ forest = AccountUpdateForest.fromFlatArray([ let approveTx = await Mina.transaction(sender, () => token.approveBase(forest)); await approveTx.prove(); -await approveTx.sign([senderKey, otherKey]).send(); +await approveTx.sign([sender.key, other.key]).send(); diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index e6942519a5..41e2a219ac 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -20,12 +20,10 @@ logEvents( let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); // Test account that pays all the fees -const feePayerKey = Local.testAccounts[0].privateKey; -const feePayer = Local.testAccounts[0].publicKey; +const [feePayer] = Local.testAccounts // zkApp account -const zkAppPrivateKey = PrivateKey.random(); -const zkAppAddress = zkAppPrivateKey.toPublicKey(); -const zkAppInstance = new HelloWorld(zkAppAddress); +const zkAppAccount = Mina.TestAccount.random() +const zkApp = new HelloWorld(zkAppAccount); let verificationKey = null; deployButton.addEventListener('click', async () => { @@ -39,12 +37,12 @@ deployButton.addEventListener('click', async () => { if (!eventsContainer.innerHTML.includes('zkApp Deployed successfully')) { AccountUpdate.fundNewAccount(feePayer); } - await zkAppInstance.deploy(); + await zkApp.deploy(); }); - await deploymentTransaction.sign([feePayerKey, zkAppPrivateKey]).send(); + await deploymentTransaction.sign([feePayer.key, zkAppAccount.key]).send(); const initialState = - Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); zkAppStateContainer.innerHTML = initialState; logEvents(`Initial zkApp State: ${initialState}`, eventsContainer); logEvents('zkApp Deployed successfully!', eventsContainer); @@ -70,13 +68,13 @@ updateButton.addEventListener('click', async (event) => { try { const currentState = - Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); logEvents( `Updating zkApp State from ${currentState} to ${zkAppStateValue.value} with Admin Private Key and using form data: ${formData}...`, eventsContainer ); const transaction = await Mina.transaction(feePayer, async () => { - await zkAppInstance.update( + await zkApp.update( Field(parseInt(zkAppStateValue.value)), adminPrivateKey ); @@ -89,10 +87,10 @@ updateButton.addEventListener('click', async (event) => { if (!isVerified) throw Error('Proof verification failed'); } - await transaction.sign([feePayerKey]).send(); + await transaction.sign([feePayer.key]).send(); const newState = - Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); zkAppStateContainer.innerHTML = newState; logEvents( `zkApp State successfully updated to: ${newState}!`, From ecc2250ecab69e904b836428c0e45e72ceb68346 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Sun, 14 Apr 2024 09:47:40 -0400 Subject: [PATCH 02/11] abide by proposed convention --- src/examples/commonjs.cjs | 2 +- src/examples/nullifier.ts | 30 ++++++----- src/examples/simple-zkapp.js | 23 ++++---- src/examples/simple-zkapp.web.ts | 42 +++++++-------- src/examples/zkapps/hashing/run.ts | 27 +++++----- src/examples/zkapps/hello-world/run.ts | 33 ++++++------ .../zkapps/merkle-tree/merkle-zkapp.ts | 16 +++--- .../zkapps/reducer/actions-as-merkle-list.ts | 29 +++++----- src/examples/zkapps/reducer/map.ts | 28 +++++----- .../zkapps/reducer/reducer-composite.ts | 44 +++++++-------- src/examples/zkapps/token-with-proofs.ts | 54 +++++++++---------- .../mina/account-update-layout.unit-test.ts | 20 ++++--- src/lib/mina/local-blockchain.ts | 2 +- 13 files changed, 173 insertions(+), 177 deletions(-) diff --git a/src/examples/commonjs.cjs b/src/examples/commonjs.cjs index 86feaea09c..7dc7cbd107 100644 --- a/src/examples/commonjs.cjs +++ b/src/examples/commonjs.cjs @@ -41,7 +41,7 @@ Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts -let contractAccount = new Mina.TestAccount(PrivateKey.random()); +let contractAccount = new Mina.random(); let contract = new Contract(contractAccount); let initialState = Field(1); diff --git a/src/examples/nullifier.ts b/src/examples/nullifier.ts index 7cbf3b1f1c..66fb852a46 100644 --- a/src/examples/nullifier.ts +++ b/src/examples/nullifier.ts @@ -50,17 +50,17 @@ const NullifierTree = new MerkleMap(); let Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp +// a test account that pays all the fees, and puts additional funds into the contract let [sender] = Local.testAccounts; -// the zkapp account -let zkappAccount = Mina.TestAccount.random(); +// the contract account +let contractAccount = Mina.TestAccount.random(); -// a special account that is allowed to pull out half of the zkapp balance, once +// a special account that is allowed to pull out half of the contract balance, once let privileged = Mina.TestAccount.random(); let initialBalance = 10_000_000_000; -let zkapp = new PayoutOnlyOnce(zkappAccount); +let contract = new PayoutOnlyOnce(contractAccount); // a unique message let nullifierMessage = Field(5); @@ -71,16 +71,18 @@ await PayoutOnlyOnce.compile(); console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); - senderUpdate.send({ to: zkappAccount, amount: initialBalance }); - await zkapp.deploy(); + senderUpdate.send({ to: contractAccount, amount: initialBalance }); + await contract.deploy(); - zkapp.nullifierRoot.set(NullifierTree.getRoot()); - zkapp.nullifierMessage.set(nullifierMessage); + contract.nullifierRoot.set(NullifierTree.getRoot()); + contract.nullifierMessage.set(nullifierMessage); }); await tx.prove(); -await tx.sign([sender.key, zkappAccount.key]).send(); +await tx.sign([sender.key, contractAccount.key]).send(); -console.log(`zkapp balance: ${zkapp.account.balance.get().div(1e9)} MINA`); +console.log( + `contract balance: ${contract.account.balance.get().div(1e9)} MINA` +); console.log('generating nullifier'); @@ -93,12 +95,12 @@ console.log(jsonNullifier); console.log('pay out'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); - await zkapp.payout(Nullifier.fromJSON(jsonNullifier)); + await contract.payout(Nullifier.fromJSON(jsonNullifier)); }); await tx.prove(); await tx.sign([sender.key]).send(); -console.log(`zkapp balance: ${zkapp.account.balance.get().div(1e9)} MINA`); +console.log(`zkapp balance: ${contract.account.balance.get().div(1e9)} MINA`); console.log( `user balance: ${Mina.getAccount(privileged).balance.div(1e9)} MINA` ); @@ -107,7 +109,7 @@ console.log('trying second pay out'); try { tx = await Mina.transaction(sender, async () => { - await zkapp.payout(Nullifier.fromJSON(jsonNullifier)); + await contract.payout(Nullifier.fromJSON(jsonNullifier)); }); await tx.prove(); diff --git a/src/examples/simple-zkapp.js b/src/examples/simple-zkapp.js index d6bbf150eb..be292d959d 100644 --- a/src/examples/simple-zkapp.js +++ b/src/examples/simple-zkapp.js @@ -6,7 +6,6 @@ import { Field, State, - PrivateKey, SmartContract, Mina, AccountUpdate, @@ -14,7 +13,7 @@ import { declareMethods, } from 'o1js'; -class SimpleZkapp extends SmartContract { +class Contract extends SmartContract { constructor(address) { super(address); this.x = State(); @@ -36,33 +35,33 @@ class SimpleZkapp extends SmartContract { this.x.set(x.add(y)); } } -declareState(SimpleZkapp, { x: Field }); -declareMethods(SimpleZkapp, { update: [Field] }); +declareState(Contract, { x: Field }); +declareMethods(Contract, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts -let zkappAccount = Mina.TestAccount.random() +let contractAccount = Mina.TestAccount.random() let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAccount); +let contract = new Contract(contractAccount); console.log('compile'); -await SimpleZkapp.compile(); +await Contract.compile(); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); -await tx.sign([feePayer.key, zkappAccount.key]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); -console.log('initial state: ' + zkapp.x.get()); +console.log('initial state: ' + contract.x.get()); console.log('update'); -tx = await Mina.transaction(feePayer, () => zkapp.update(Field(3))); +tx = await Mina.transaction(feePayer, () => contract.update(Field(3))); await tx.prove(); await tx.sign([feePayer.key]).send(); -console.log('final state: ' + zkapp.x.get()); +console.log('final state: ' + contract.x.get()); diff --git a/src/examples/simple-zkapp.web.ts b/src/examples/simple-zkapp.web.ts index c4a8c10974..1d7b8d7ba9 100644 --- a/src/examples/simple-zkapp.web.ts +++ b/src/examples/simple-zkapp.web.ts @@ -16,7 +16,7 @@ const doProofs = true; const beforeGenesis = UInt64.from(Date.now()); -class SimpleZkapp extends SmartContract { +class Contract extends SmartContract { @state(Field) x = State(); events = { update: Field, payout: UInt64, payoutReceiver: PublicKey }; @@ -38,7 +38,7 @@ class SimpleZkapp extends SmartContract { } /** - * This method allows a certain privileged account to claim half of the zkapp balance, but only once + * This method allows a certain privileged account to claim half of the contract balance, but only once * @param caller the privileged account */ @method async payout(caller: PrivateKey) { @@ -51,7 +51,7 @@ class SimpleZkapp extends SmartContract { // assert that the caller account is new - this way, payout can only happen once let callerAccountUpdate = AccountUpdate.create(callerAddress); callerAccountUpdate.account.isNew.requireEquals(Bool(true)); - // pay out half of the zkapp balance to the caller + // pay out half of the contract balance to the caller let balance = this.account.balance.get(); this.account.balance.requireEquals(balance); let halfBalance = balance.div(2); @@ -66,64 +66,62 @@ class SimpleZkapp extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: doProofs }); Mina.setActiveInstance(Local); -// a test account that pays all the fees, and puts additional funds into the zkapp +// a test account that pays all the fees, and puts additional funds into the contract let [sender] = Local.testAccounts; -// the zkapp account -let zkappKey = PrivateKey.random(); -let zkappAddress = zkappKey.toPublicKey(); +let contractAccount = Mina.TestAccount.random(); -// a special account that is allowed to pull out half of the zkapp balance, once +// a special account that is allowed to pull out half of the contract balance, once let privileged = new Mina.TestAccount( PrivateKey.fromBase58('EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep') ); let initialBalance = 10_000_000_000; let initialState = Field(1); -let zkapp = new SimpleZkapp(zkappAddress); +let contract = new Contract(contractAccount); if (doProofs) { console.log('compile'); - await SimpleZkapp.compile(); + await Contract.compile(); } console.log('deploy'); let tx = await Mina.transaction(sender, async () => { let senderUpdate = AccountUpdate.fundNewAccount(sender); - senderUpdate.send({ to: zkappAddress, amount: initialBalance }); - await zkapp.deploy(); + senderUpdate.send({ to: contractAccount, amount: initialBalance }); + await contract.deploy(); }); await tx.prove(); -await tx.sign([sender.key, zkappKey]).send(); +await tx.sign([sender.key, contractAccount.key]).send(); -console.log('initial state: ' + zkapp.x.get()); -console.log(`initial balance: ${zkapp.account.balance.get().div(1e9)} MINA`); +console.log('initial state: ' + contract.x.get()); +console.log(`initial balance: ${contract.account.balance.get().div(1e9)} MINA`); -let account = Mina.getAccount(zkappAddress); +let account = Mina.getAccount(contractAccount); console.log('account state is proved:', account.zkapp?.provedState.toBoolean()); console.log('update'); tx = await Mina.transaction(sender, async () => { - await zkapp.update(Field(3)); + await contract.update(Field(3)); }); await tx.prove(); await tx.sign([sender.key]).send(); -// pay more into the zkapp -- this doesn't need a proof +// pay more into the contract -- this doesn't need a proof console.log('receive'); tx = await Mina.transaction(sender, async () => { let payerAccountUpdate = AccountUpdate.createSigned(sender); - payerAccountUpdate.send({ to: zkappAddress, amount: UInt64.from(8e9) }); + payerAccountUpdate.send({ to: contractAccount, amount: UInt64.from(8e9) }); }); await tx.sign([sender.key]).send(); console.log('payout'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); - await zkapp.payout(privileged.key); + await contract.payout(privileged.key); }); await tx.prove(); await tx.sign([sender.key]).send(); -console.log('final state: ' + zkapp.x.get()); -console.log(`final balance: ${zkapp.account.balance.get().div(1e9)} MINA`); +console.log('final state: ' + contract.x.get()); +console.log(`final balance: ${contract.account.balance.get().div(1e9)} MINA`); diff --git a/src/examples/zkapps/hashing/run.ts b/src/examples/zkapps/hashing/run.ts index b164c3d41f..cbc7d7c876 100644 --- a/src/examples/zkapps/hashing/run.ts +++ b/src/examples/zkapps/hashing/run.ts @@ -16,9 +16,8 @@ if (proofsEnabled) { const [feePayer] = Local.testAccounts; // zkapp account -const zkAppPrivateKey = PrivateKey.random(); -const zkAppAddress = zkAppPrivateKey.toPublicKey(); -const zkAppInstance = new HashStorage(zkAppAddress); +const contractAccount = Mina.TestAccount.random(); +const contract = new HashStorage(contractAccount); // 0, 1, 2, 3, ..., 31 const hashData = Bytes.from(Array.from({ length: 32 }, (_, i) => i)); @@ -26,48 +25,48 @@ const hashData = Bytes.from(Array.from({ length: 32 }, (_, i) => i)); console.log('Deploying Hash Example....'); txn = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkAppInstance.deploy(); + await contract.deploy(); }); -await txn.sign([feePayer.key, zkAppPrivateKey]).send(); +await txn.sign([feePayer.key, contractAccount.key]).send(); const initialState = - Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); let currentState; console.log('Initial State', initialState); console.log(`Updating commitment from ${initialState} using SHA256 ...`); txn = await Mina.transaction(feePayer, async () => { - await zkAppInstance.SHA256(hashData); + await contract.SHA256(hashData); }); await txn.prove(); await txn.sign([feePayer.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using SHA384 ...`); txn = await Mina.transaction(feePayer, async () => { - await zkAppInstance.SHA384(hashData); + await contract.SHA384(hashData); }); await txn.prove(); await txn.sign([feePayer.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using SHA512 ...`); txn = await Mina.transaction(feePayer, async () => { - await zkAppInstance.SHA512(hashData); + await contract.SHA512(hashData); }); await txn.prove(); await txn.sign([feePayer.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); console.log(`Updating commitment from ${initialState} using Keccak256...`); txn = await Mina.transaction(feePayer, async () => { - await zkAppInstance.Keccak256(hashData); + await contract.Keccak256(hashData); }); await txn.prove(); await txn.sign([feePayer.key]).send(); -currentState = Mina.getAccount(zkAppAddress).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); console.log(`Current state successfully updated to ${currentState}`); diff --git a/src/examples/zkapps/hello-world/run.ts b/src/examples/zkapps/hello-world/run.ts index 49eab51489..db86e5d193 100644 --- a/src/examples/zkapps/hello-world/run.ts +++ b/src/examples/zkapps/hello-world/run.ts @@ -14,19 +14,19 @@ Mina.setActiveInstance(Local); const [feePayer1, feePayer2, feePayer3, feePayer4] = Local.testAccounts; // zkapp account -const zkAppAccount = Mina.TestAccount.random(); -const zkApp = new HelloWorld(zkAppAccount); +const contractAccount = Mina.TestAccount.random(); +const contract = new HelloWorld(contractAccount); console.log('Deploying Hello World ....'); txn = await Mina.transaction(feePayer1, async () => { AccountUpdate.fundNewAccount(feePayer1); - await zkApp.deploy(); + await contract.deploy(); }); -await txn.sign([feePayer1.key, zkAppAccount.key]).send(); +await txn.sign([feePayer1.key, contractAccount.key]).send(); const initialState = - Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); let currentState; @@ -38,12 +38,12 @@ console.log( ); txn = await Mina.transaction(feePayer1, async () => { - await zkApp.update(Field(4), adminPrivateKey); + await contract.update(Field(4), adminPrivateKey); }); await txn.prove(); await txn.sign([feePayer1.key]).send(); -currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); if (currentState !== '4') { throw Error( @@ -63,7 +63,7 @@ let correctlyFails = false; try { txn = await Mina.transaction(feePayer1, async () => { - await zkApp.update(Field(16), wrongAdminPrivateKey); + await contract.update(Field(16), wrongAdminPrivateKey); }); await txn.prove(); await txn.sign([feePayer1.key]).send(); @@ -84,7 +84,7 @@ try { ); txn = await Mina.transaction(feePayer1, async () => { - await zkApp.update(Field(30), adminPrivateKey); + await contract.update(Field(30), adminPrivateKey); }); await txn.prove(); await txn.sign([feePayer1.key]).send(); @@ -108,7 +108,7 @@ try { // expected to fail and current state stays at 4 txn = await Mina.transaction({ sender: feePayer1, fee: '10' }, async () => { - await zkApp.update(Field(256), adminPrivateKey); + await contract.update(Field(256), adminPrivateKey); }); await txn.prove(); await txn.sign([feePayer1.key]).send(); @@ -124,12 +124,12 @@ if (!correctlyFails) { // expected to succeed and update state to 16 txn2 = await Mina.transaction({ sender: feePayer2, fee: '2' }, async () => { - await zkApp.update(Field(16), adminPrivateKey); + await contract.update(Field(16), adminPrivateKey); }); await txn2.prove(); await txn2.sign([feePayer2.key]).send(); -currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); if (currentState !== '16') { throw Error( @@ -141,12 +141,12 @@ console.log(`Update successful. Current state is ${currentState}.`); // expected to succeed and update state to 256 txn3 = await Mina.transaction({ sender: feePayer3, fee: '1' }, async () => { - await zkApp.update(Field(256), adminPrivateKey); + await contract.update(Field(256), adminPrivateKey); }); await txn3.prove(); await txn3.sign([feePayer3.key]).send(); -currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); +currentState = Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); if (currentState !== '256') { throw Error( @@ -161,7 +161,7 @@ correctlyFails = false; try { // expected to fail and current state remains 256 txn4 = await Mina.transaction({ sender: feePayer4, fee: '1' }, async () => { - await zkApp.update(Field(16), adminPrivateKey); + await contract.update(Field(16), adminPrivateKey); }); await txn4.prove(); await txn4.sign([feePayer4.key]).send(); @@ -182,7 +182,8 @@ if (!correctlyFails) { */ function handleError(error: any, errorMessage: string) { - currentState = Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); + currentState = + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); if (error.message.includes(errorMessage)) { correctlyFails = true; diff --git a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts index 91996d9992..b2dfa3f5db 100644 --- a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts +++ b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts @@ -97,7 +97,7 @@ let initialBalance = 10_000_000_000; let [feePayer] = Local.testAccounts; -let zkappAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestAccount.random(); // this map serves as our off-chain in-memory storage let Accounts: Map = new Map( @@ -124,20 +124,20 @@ Tree.setLeaf(3n, Accounts.get('Olivia')!.hash()); // now that we got our accounts set up, we need the commitment to deploy our contract! initialCommitment = Tree.getRoot(); -let leaderboardZkApp = new Leaderboard(zkappAccount); +let contract = new Leaderboard(contractAccount); console.log('Deploying leaderboard..'); if (doProofs) { await Leaderboard.compile(); } let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer).send({ - to: zkappAccount, + to: contractAccount, amount: initialBalance, }); - await leaderboardZkApp.deploy(); + await contract.deploy(); }); await tx.prove(); -await tx.sign([feePayer.key, zkappAccount.key]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); console.log('Initial points: ' + Accounts.get('Bob')?.points); @@ -152,13 +152,13 @@ async function makeGuess(name: Names, index: bigint, guess: number) { let witness = new MyMerkleWitness(w); let tx = await Mina.transaction(feePayer, async () => { - await leaderboardZkApp.guessPreimage(Field(guess), account, witness); + await contract.guessPreimage(Field(guess), account, witness); }); await tx.prove(); - await tx.sign([feePayer.key, zkappAccount.key]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); // if the transaction was successful, we can update our off-chain storage as well account.points = account.points.add(1); Tree.setLeaf(index, account.hash()); - leaderboardZkApp.commitment.get().assertEquals(Tree.getRoot()); + contract.commitment.get().assertEquals(Tree.getRoot()); } diff --git a/src/examples/zkapps/reducer/actions-as-merkle-list.ts b/src/examples/zkapps/reducer/actions-as-merkle-list.ts index 558cbcc253..eeceb20468 100644 --- a/src/examples/zkapps/reducer/actions-as-merkle-list.ts +++ b/src/examples/zkapps/reducer/actions-as-merkle-list.ts @@ -52,7 +52,7 @@ const MAX_ACTIONS_PER_UPDATE = 2; * This contract allows you to push either 1 or 2 public keys as actions, * and has a reducer-like method which checks whether a given public key is contained in those actions. */ -class ActionsContract extends SmartContract { +class Contract extends SmartContract { reducer = Reducer({ actionType: Action }); @method @@ -105,39 +105,40 @@ class ActionsContract extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); -let [sender, zkappAccount, otherAddress, anotherAddress] = Local.testAccounts; +let [sender, contractAccount, otherAddress, anotherAddress] = + Local.testAccounts; -let zkapp = new ActionsContract(zkappAccount); +let contract = new Contract(contractAccount); // deploy the contract -await ActionsContract.compile(); +await Contract.compile(); console.log( `rows for ${MAX_UPDATES_WITH_ACTIONS} updates with actions`, - (await ActionsContract.analyzeMethods()).assertContainsAddress.rows + (await Contract.analyzeMethods()).assertContainsAddress.rows ); -let deployTx = await Mina.transaction(sender, async () => zkapp.deploy()); -await deployTx.sign([sender.key, zkappAccount.key]).send(); +let deployTx = await Mina.transaction(sender, async () => contract.deploy()); +await deployTx.sign([sender.key, contractAccount.key]).send(); // push some actions let dispatchTx = await Mina.transaction(sender, async () => { - await zkapp.postAddress(otherAddress); - await zkapp.postAddress(zkappAccount); - await zkapp.postTwoAddresses(anotherAddress, sender); - await zkapp.postAddress(anotherAddress); - await zkapp.postTwoAddresses(zkappAccount, otherAddress); + await contract.postAddress(otherAddress); + await contract.postAddress(contractAccount); + await contract.postTwoAddresses(anotherAddress, sender); + await contract.postAddress(anotherAddress); + await contract.postTwoAddresses(contractAccount, otherAddress); }); await dispatchTx.prove(); await dispatchTx.sign([sender.key]).send(); -assert(zkapp.reducer.getActions().length === 5); +assert(contract.reducer.getActions().length === 5); // check if the actions contain the `sender` address Local.setProofsEnabled(true); let containsTx = await Mina.transaction(sender, () => - zkapp.assertContainsAddress(sender) + contract.assertContainsAddress(sender) ); await containsTx.prove(); await containsTx.sign([sender.key]).send(); diff --git a/src/examples/zkapps/reducer/map.ts b/src/examples/zkapps/reducer/map.ts index 2855dc1715..c185eefda3 100644 --- a/src/examples/zkapps/reducer/map.ts +++ b/src/examples/zkapps/reducer/map.ts @@ -30,9 +30,9 @@ map.set(key, value); map.get(key); // contract -await zkApp.deploy(); // ... deploy the zkapp -await zkApp.set(key, value); // ... set a key-value pair -await zkApp.get(key); // ... get a value by key +await contract.deploy(); // ... deploy the contract +await contract.set(key, value); // ... set a key-value pair +await contract.get(key); // ... get a value by key ``` */ @@ -96,17 +96,17 @@ console.log('set rows:', cs['set'].rows); let [feePayer] = Local.testAccounts; -// the zkapp account -let zkappAccount = Mina.TestAccount.random(); -let zkapp = new StorageContract(zkappAccount); +// the contract account +let contractAccount = Mina.TestAccount.random(); +let contract = new StorageContract(contractAccount); await StorageContract.compile(); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); -await tx.sign([feePayer.key, zkappAccount.key]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); console.log('deployed'); @@ -130,7 +130,7 @@ let value = map[0].value; console.log(`setting key ${key.toBase58()} with value ${value}`); tx = await Mina.transaction(feePayer, async () => { - await zkapp.set(key, value); + await contract.set(key, value); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -140,7 +140,7 @@ value = map[1].value; console.log(`setting key ${key.toBase58()} with value ${value}`); tx = await Mina.transaction(feePayer, async () => { - await zkapp.set(key, value); + await contract.set(key, value); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -150,7 +150,7 @@ value = map[2].value; console.log(`setting key ${key.toBase58()} with value ${value}`); tx = await Mina.transaction(feePayer, async () => { - await zkapp.set(key, value); + await contract.set(key, value); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -161,7 +161,7 @@ console.log(`getting key ${key.toBase58()} with value ${value}`); let result: Option | undefined; tx = await Mina.transaction(feePayer, async () => { - result = await zkapp.get(key); + result = await contract.get(key); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -175,7 +175,7 @@ value = map[1].value; console.log(`getting key ${key.toBase58()} with value ${value}`); tx = await Mina.transaction(feePayer, async () => { - result = await zkapp.get(key); + result = await contract.get(key); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -185,7 +185,7 @@ console.log('matches expected value?', result.value.equals(value).toBoolean()); console.log(`getting key invalid key`); tx = await Mina.transaction(feePayer, async () => { - result = await zkapp.get(PrivateKey.random().toPublicKey()); + result = await contract.get(PrivateKey.random().toPublicKey()); }); await tx.prove(); await tx.sign([feePayer.key]).send(); diff --git a/src/examples/zkapps/reducer/reducer-composite.ts b/src/examples/zkapps/reducer/reducer-composite.ts index 7410a4aded..975412e372 100644 --- a/src/examples/zkapps/reducer/reducer-composite.ts +++ b/src/examples/zkapps/reducer/reducer-composite.ts @@ -21,7 +21,7 @@ class MaybeIncrement extends Struct({ }) {} const INCREMENT = { isIncrement: Bool(true), otherData: Field(0) }; -class CounterZkapp extends SmartContract { +class Counter extends SmartContract { // the "reducer" field describes a type of action that we can dispatch, and reduce later reducer = Reducer({ actionType: MaybeIncrement }); @@ -78,88 +78,88 @@ Mina.setActiveInstance(Local); let [feePayer] = Local.testAccounts; -// the zkapp account -let zkappAccount = new Mina.TestAccount( +// the contract account +let contractAccount = new Mina.TestAccount( PrivateKey.fromBase58('EKEQc95PPQZnMY9d9p1vq1MWLeDJKtvKj4V75UDG3rjnf32BerWD') ); -let zkapp = new CounterZkapp(zkappAccount); +let contract = new Counter(contractAccount); if (doProofs) { console.log('compile'); - await CounterZkapp.compile(); + await Counter.compile(); } console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); - zkapp.counter.set(initialCounter); - zkapp.actionState.set(Reducer.initialActionState); + await contract.deploy(); + contract.counter.set(initialCounter); + contract.actionState.set(Reducer.initialActionState); }); -await tx.sign([feePayer.key, zkappAccount.key]).send(); +await tx.sign([feePayer.key, contractAccount.key]).send(); console.log('applying actions..'); console.log('action 1'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.incrementCounter(); + await contract.incrementCounter(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); console.log('action 2'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.incrementCounter(); + await contract.incrementCounter(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); console.log('action 3'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.incrementCounter(); + await contract.incrementCounter(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); console.log('rolling up pending actions..'); -console.log('state before: ' + zkapp.counter.get()); +console.log('state before: ' + contract.counter.get()); tx = await Mina.transaction(feePayer, async () => { - await zkapp.rollupIncrements(); + await contract.rollupIncrements(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); -console.log('state after rollup: ' + zkapp.counter.get()); -assert.deepEqual(zkapp.counter.get().toString(), '3'); +console.log('state after rollup: ' + contract.counter.get()); +assert.deepEqual(contract.counter.get().toString(), '3'); console.log('applying more actions'); console.log('action 4 (no increment)'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.dispatchData(Field.random()); + await contract.dispatchData(Field.random()); }); await tx.prove(); await tx.sign([feePayer.key]).send(); console.log('action 5'); tx = await Mina.transaction(feePayer, async () => { - await zkapp.incrementCounter(); + await contract.incrementCounter(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); console.log('rolling up pending actions..'); -console.log('state before: ' + zkapp.counter.get()); +console.log('state before: ' + contract.counter.get()); tx = await Mina.transaction(feePayer, async () => { - await zkapp.rollupIncrements(); + await contract.rollupIncrements(); }); await tx.prove(); await tx.sign([feePayer.key]).send(); -console.log('state after rollup: ' + zkapp.counter.get()); -assert.equal(zkapp.counter.get().toString(), '4'); +console.log('state after rollup: ' + contract.counter.get()); +assert.equal(contract.counter.get().toString(), '4'); ReducerProfiler.stop().store(); diff --git a/src/examples/zkapps/token-with-proofs.ts b/src/examples/zkapps/token-with-proofs.ts index e00744b629..e1ceae51c6 100644 --- a/src/examples/zkapps/token-with-proofs.ts +++ b/src/examples/zkapps/token-with-proofs.ts @@ -26,13 +26,13 @@ class Token extends TokenContract { } } -class ZkAppB extends SmartContract { +class ContractB extends SmartContract { @method async approveSend() { this.balance.subInPlace(1_000); } } -class ZkAppC extends SmartContract { +class ContractC extends SmartContract { @method async approveSend() { this.balance.subInPlace(1_000); } @@ -44,19 +44,18 @@ Mina.setActiveInstance(Local); let [sender, tokenAccount1] = Local.testAccounts; let initialBalance = 10_000_000; -const [tokenZkAppAddress, zkAppCAddress, zkAppBAddress] = - Mina.TestAccount.random(3); +const [tokenContractAccount, addressC, accountC] = Mina.TestAccount.random(3); -let tokenZkApp = new Token(tokenZkAppAddress); -let tokenId = tokenZkApp.deriveTokenId(); +let tokenContract = new Token(tokenContractAccount); +let tokenId = tokenContract.deriveTokenId(); -let zkAppB = new ZkAppB(zkAppBAddress, tokenId); -let zkAppC = new ZkAppC(zkAppCAddress, tokenId); +let contractB = new ContractB(accountC, tokenId); +let contractC = new ContractC(addressC, tokenId); let tx; -console.log('tokenZkAppAddress', tokenZkAppAddress.toBase58()); -console.log('zkAppB', zkAppBAddress.toBase58()); -console.log('zkAppC', zkAppCAddress.toBase58()); +console.log('tokenContractAccount', tokenContractAccount.toBase58()); +console.log('accountC', accountC.toBase58()); +console.log('addressC', addressC.toBase58()); console.log('receiverAddress', tokenAccount1.toBase58()); console.log('feePayer', sender.toBase58()); console.log('-------------------------------------------'); @@ -64,62 +63,61 @@ console.log('-------------------------------------------'); console.log('compile (TokenContract)'); await Token.compile(); console.log('compile (ZkAppB)'); -await ZkAppB.compile(); +await ContractB.compile(); console.log('compile (ZkAppC)'); -await ZkAppC.compile(); +await ContractC.compile(); console.log('deploy tokenZkApp'); tx = await Mina.transaction(sender, async () => { - await tokenZkApp.deploy(); + await tokenContract.deploy(); AccountUpdate.fundNewAccount(sender).send({ - to: tokenZkApp.self, + to: tokenContract.self, amount: initialBalance, }); }); -await tx.sign([sender.key, tokenZkAppAddress.key]).send(); +await tx.sign([sender.key, tokenContractAccount.key]).send(); console.log('deploy zkAppB and zkAppC'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender, 2); - await zkAppC.deploy(); - await zkAppB.deploy(); - await tokenZkApp.approveAccountUpdates([zkAppC.self, zkAppB.self]); + await contractC.deploy(); + await contractB.deploy(); + await tokenContract.approveAccountUpdates([contractC.self, contractB.self]); }); console.log('deploy zkAppB and zkAppC (proof)'); await tx.prove(); -await tx.sign([sender.key, zkAppBAddress.key, zkAppCAddress.key]).send(); +await tx.sign([sender.key, accountC.key, addressC.key]).send(); console.log('mint token to zkAppB'); tx = await Mina.transaction(sender, async () => { - await tokenZkApp.mint(zkAppBAddress); + await tokenContract.mint(accountC); }); await tx.prove(); await tx.sign([sender.key]).send(); console.log('approve send from zkAppB'); tx = await Mina.transaction(sender, async () => { - await zkAppB.approveSend(); - + await contractB.approveSend(); // we call the token contract with the self update - await tokenZkApp.transfer(zkAppB.self, zkAppCAddress, 1_000); + await tokenContract.transfer(contractB.self, addressC, 1_000); }); console.log('approve send (proof)'); await tx.prove(); await tx.sign([sender.key]).send(); console.log( - `zkAppC's balance for tokenId: ${TokenId.toBase58(tokenId)}`, - Mina.getBalance(zkAppCAddress, tokenId).value.toBigInt() + `contractC's balance for tokenId: ${TokenId.toBase58(tokenId)}`, + Mina.getBalance(addressC, tokenId).value.toBigInt() ); console.log('approve send from zkAppC'); tx = await Mina.transaction(sender, async () => { // Pay for tokenAccount1's account creation AccountUpdate.fundNewAccount(sender); - await zkAppC.approveSend(); + await contractC.approveSend(); // we call the token contract with the tree - await tokenZkApp.transfer(zkAppC.self, tokenAccount1, 1_000); + await tokenContract.transfer(contractC.self, tokenAccount1, 1_000); }); console.log('approve send (proof)'); await tx.prove(); diff --git a/src/lib/mina/account-update-layout.unit-test.ts b/src/lib/mina/account-update-layout.unit-test.ts index 2c58c6db47..8b1c90a788 100644 --- a/src/lib/mina/account-update-layout.unit-test.ts +++ b/src/lib/mina/account-update-layout.unit-test.ts @@ -29,35 +29,33 @@ class NestedCall extends SmartContract { let Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); -let [sender, zkappAccount] = Local.testAccounts; +let [sender, contractAccount] = Local.testAccounts; await NestedCall.compile(); -let zkapp = new NestedCall(zkappAccount); +let contract = new NestedCall(contractAccount); -// deploy zkapp - -await (await Mina.transaction(sender, () => zkapp.deploy())) - .sign([zkappAccount.key, sender.key]) +await (await Mina.transaction(sender, () => contract.deploy())) + .sign([contractAccount.key, sender.key]) .send(); // deposit call -let balanceBefore = Mina.getBalance(zkappAccount); +let balanceBefore = Mina.getBalance(contractAccount); -let depositTx = await Mina.transaction(sender, () => zkapp.deposit()); +let depositTx = await Mina.transaction(sender, () => contract.deposit()); console.log(depositTx.toPretty()); await depositTx.prove(); await depositTx.sign([sender.key]).send(); -Mina.getBalance(zkappAccount).assertEquals(balanceBefore.add(1)); +Mina.getBalance(contractAccount).assertEquals(balanceBefore.add(1)); // deposit call using tree balanceBefore = balanceBefore.add(1); -depositTx = await Mina.transaction(sender, () => zkapp.depositUsingTree()); +depositTx = await Mina.transaction(sender, () => contract.depositUsingTree()); console.log(depositTx.toPretty()); await depositTx.prove(); await depositTx.sign([sender.key]).send(); -Mina.getBalance(zkappAccount).assertEquals(balanceBefore.add(1)); +Mina.getBalance(contractAccount).assertEquals(balanceBefore.add(1)); diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index a4487f7db7..2388c4ea1e 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -81,7 +81,7 @@ function LocalBlockchain({ for (let i = 0; i < 100; ++i) { let MINA = 10n ** 9n; const largeValue = 1000n * MINA; - const testAccount = new TestAccount(PrivateKey.random()); + const testAccount = TestAccount.random(); addAccount(testAccount, largeValue.toString()); testAccounts.push(testAccount); } From 5122119e97d113c7cef29f761ddb4a8f1a3ebfcb Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Sun, 14 Apr 2024 09:56:30 -0400 Subject: [PATCH 03/11] more convention related --- src/examples/commonjs.cjs | 11 +- src/examples/simple-zkapp.js | 10 +- src/examples/simple-zkapp.web.ts | 6 +- src/examples/zkapps/local-events-zkapp.ts | 6 +- .../zkapps/reducer/actions-as-merkle-list.ts | 8 +- .../zkapps/set-local-preconditions-zkapp.ts | 14 +- src/examples/zkapps/simple-zkapp-payment.ts | 6 +- src/examples/zkapps/token-with-proofs.ts | 53 ++- src/examples/zkapps/zkapp-self-update.ts | 6 +- src/lib/mina/token.test.ts | 304 ++++++++---------- 10 files changed, 197 insertions(+), 227 deletions(-) diff --git a/src/examples/commonjs.cjs b/src/examples/commonjs.cjs index 7dc7cbd107..5cfb93e839 100644 --- a/src/examples/commonjs.cjs +++ b/src/examples/commonjs.cjs @@ -4,7 +4,6 @@ let { Field, State, - PrivateKey, SmartContract, Mina, AccountUpdate, @@ -12,7 +11,7 @@ let { declareMethods, } = require('o1js'); -class Contract extends SmartContract { +class Updater extends SmartContract { constructor(address) { super(address); this.x = State(); @@ -33,8 +32,8 @@ class Contract extends SmartContract { this.x.set(x.add(y)); } } -declareState(Contract, { x: Field }); -declareMethods(Contract, { update: [Field] }); +declareState(Updater, { x: Field }); +declareMethods(Updater, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); @@ -42,7 +41,7 @@ Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts let contractAccount = new Mina.random(); -let contract = new Contract(contractAccount); +let contract = new Updater(contractAccount); let initialState = Field(1); @@ -50,7 +49,7 @@ main(); async function main() { console.log('compile'); - await Contract.compile(); + await Updater.compile(); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { diff --git a/src/examples/simple-zkapp.js b/src/examples/simple-zkapp.js index be292d959d..d66a8b694a 100644 --- a/src/examples/simple-zkapp.js +++ b/src/examples/simple-zkapp.js @@ -13,7 +13,7 @@ import { declareMethods, } from 'o1js'; -class Contract extends SmartContract { +class Updater extends SmartContract { constructor(address) { super(address); this.x = State(); @@ -35,8 +35,8 @@ class Contract extends SmartContract { this.x.set(x.add(y)); } } -declareState(Contract, { x: Field }); -declareMethods(Contract, { update: [Field] }); +declareState(Updater, { x: Field }); +declareMethods(Updater, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); @@ -46,10 +46,10 @@ const [feePayer] = Local.testAccounts let contractAccount = Mina.TestAccount.random() let initialState = Field(1); -let contract = new Contract(contractAccount); +let contract = new Updater(contractAccount); console.log('compile'); -await Contract.compile(); +await Updater.compile(); console.log('deploy'); let tx = await Mina.transaction(feePayer, async () => { diff --git a/src/examples/simple-zkapp.web.ts b/src/examples/simple-zkapp.web.ts index 1d7b8d7ba9..bd03ce1373 100644 --- a/src/examples/simple-zkapp.web.ts +++ b/src/examples/simple-zkapp.web.ts @@ -16,7 +16,7 @@ const doProofs = true; const beforeGenesis = UInt64.from(Date.now()); -class Contract extends SmartContract { +class Simple extends SmartContract { @state(Field) x = State(); events = { update: Field, payout: UInt64, payoutReceiver: PublicKey }; @@ -78,11 +78,11 @@ let privileged = new Mina.TestAccount( let initialBalance = 10_000_000_000; let initialState = Field(1); -let contract = new Contract(contractAccount); +let contract = new Simple(contractAccount); if (doProofs) { console.log('compile'); - await Contract.compile(); + await Simple.compile(); } console.log('deploy'); diff --git a/src/examples/zkapps/local-events-zkapp.ts b/src/examples/zkapps/local-events-zkapp.ts index a5daf85d34..5cbee1c160 100644 --- a/src/examples/zkapps/local-events-zkapp.ts +++ b/src/examples/zkapps/local-events-zkapp.ts @@ -16,7 +16,7 @@ const doProofs = false; class Event extends Struct({ pub: PublicKey, value: Field }) {} -class Contract extends SmartContract { +class LocalEvents extends SmartContract { @state(Field) x = State(); events = { @@ -48,13 +48,13 @@ Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts; let contractAccount = Mina.TestAccount.random(); -let contract = new Contract(contractAccount); +let contract = new LocalEvents(contractAccount); let initialState = Field(1); if (doProofs) { console.log('compile'); - await Contract.compile(); + await LocalEvents.compile(); } console.log('deploy'); diff --git a/src/examples/zkapps/reducer/actions-as-merkle-list.ts b/src/examples/zkapps/reducer/actions-as-merkle-list.ts index eeceb20468..4d6750425f 100644 --- a/src/examples/zkapps/reducer/actions-as-merkle-list.ts +++ b/src/examples/zkapps/reducer/actions-as-merkle-list.ts @@ -52,7 +52,7 @@ const MAX_ACTIONS_PER_UPDATE = 2; * This contract allows you to push either 1 or 2 public keys as actions, * and has a reducer-like method which checks whether a given public key is contained in those actions. */ -class Contract extends SmartContract { +class MerkleListReducing extends SmartContract { reducer = Reducer({ actionType: Action }); @method @@ -108,14 +108,14 @@ Mina.setActiveInstance(Local); let [sender, contractAccount, otherAddress, anotherAddress] = Local.testAccounts; -let contract = new Contract(contractAccount); +let contract = new MerkleListReducing(contractAccount); // deploy the contract -await Contract.compile(); +await MerkleListReducing.compile(); console.log( `rows for ${MAX_UPDATES_WITH_ACTIONS} updates with actions`, - (await Contract.analyzeMethods()).assertContainsAddress.rows + (await MerkleListReducing.analyzeMethods()).assertContainsAddress.rows ); let deployTx = await Mina.transaction(sender, async () => contract.deploy()); await deployTx.sign([sender.key, contractAccount.key]).send(); diff --git a/src/examples/zkapps/set-local-preconditions-zkapp.ts b/src/examples/zkapps/set-local-preconditions-zkapp.ts index b5451f2d5d..f7686b0b47 100644 --- a/src/examples/zkapps/set-local-preconditions-zkapp.ts +++ b/src/examples/zkapps/set-local-preconditions-zkapp.ts @@ -10,8 +10,8 @@ import { method, SmartContract, Mina, AccountUpdate, UInt32 } from 'o1js'; const doProofs = false; -class Contract extends SmartContract { - @method async blockheightEquals(y: UInt32) { +class BlockHeightReference extends SmartContract { + @method async blockHeightEquals(y: UInt32) { let length = this.network.blockchainLength.get(); this.network.blockchainLength.requireEquals(length); @@ -26,11 +26,11 @@ const [feePayer] = Local.testAccounts; let contractAccount = Mina.TestAccount.random(); -let contract = new Contract(contractAccount); +let contract = new BlockHeightReference(contractAccount); if (doProofs) { console.log('compile'); - await Contract.compile(); + await BlockHeightReference.compile(); } console.log('deploy'); @@ -45,7 +45,7 @@ let blockHeight: UInt32 = UInt32.zero; console.log('assert block height 0'); tx = await Mina.transaction(feePayer, async () => { // block height starts at 0 - await contract.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockHeightEquals(UInt32.from(blockHeight)); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -55,7 +55,7 @@ Local.setBlockchainLength(blockHeight); console.log('assert block height 500'); tx = await Mina.transaction(feePayer, async () => { - await contract.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockHeightEquals(UInt32.from(blockHeight)); }); await tx.prove(); await tx.sign([feePayer.key]).send(); @@ -65,7 +65,7 @@ Local.setBlockchainLength(UInt32.from(5)); console.log('invalid block height precondition'); try { tx = await Mina.transaction(feePayer, async () => { - await contract.blockheightEquals(UInt32.from(blockHeight)); + await contract.blockHeightEquals(UInt32.from(blockHeight)); }); await tx.prove(); await tx.sign([feePayer.key]).send(); diff --git a/src/examples/zkapps/simple-zkapp-payment.ts b/src/examples/zkapps/simple-zkapp-payment.ts index 1c50fac6ea..77f8cb337b 100644 --- a/src/examples/zkapps/simple-zkapp-payment.ts +++ b/src/examples/zkapps/simple-zkapp-payment.ts @@ -7,7 +7,7 @@ import { Permissions, } from 'o1js'; -class Contract extends SmartContract { +class PaymentContainer extends SmartContract { init() { super.init(); this.account.permissions.set({ @@ -30,7 +30,7 @@ class Contract extends SmartContract { } let proofsEnabled = false; -if (proofsEnabled) await Contract.compile(); +if (proofsEnabled) await PaymentContainer.compile(); let Local = Mina.LocalBlockchain({ proofsEnabled }); Mina.setActiveInstance(Local); @@ -47,7 +47,7 @@ function printBalances() { console.log(`account2 balance: ${Mina.getBalance(account2).div(1e9)} MINA\n`); } -let zkapp = new Contract(contractAccount); +let zkapp = new PaymentContainer(contractAccount); let tx; console.log('deploy and fund user accounts'); diff --git a/src/examples/zkapps/token-with-proofs.ts b/src/examples/zkapps/token-with-proofs.ts index e1ceae51c6..8221f9bc25 100644 --- a/src/examples/zkapps/token-with-proofs.ts +++ b/src/examples/zkapps/token-with-proofs.ts @@ -26,13 +26,13 @@ class Token extends TokenContract { } } -class ContractB extends SmartContract { +class B extends SmartContract { @method async approveSend() { this.balance.subInPlace(1_000); } } -class ContractC extends SmartContract { +class C extends SmartContract { @method async approveSend() { this.balance.subInPlace(1_000); } @@ -44,62 +44,59 @@ Mina.setActiveInstance(Local); let [sender, tokenAccount1] = Local.testAccounts; let initialBalance = 10_000_000; -const [tokenContractAccount, addressC, accountC] = Mina.TestAccount.random(3); +const [tokenAccount, cAccount, bAccount] = Mina.TestAccount.random(3); -let tokenContract = new Token(tokenContractAccount); -let tokenId = tokenContract.deriveTokenId(); +let token = new Token(tokenAccount); +let tokenId = token.deriveTokenId(); -let contractB = new ContractB(accountC, tokenId); -let contractC = new ContractC(addressC, tokenId); +let b = new B(bAccount, tokenId); +let c = new C(cAccount, tokenId); let tx; -console.log('tokenContractAccount', tokenContractAccount.toBase58()); -console.log('accountC', accountC.toBase58()); -console.log('addressC', addressC.toBase58()); +console.log('tokenContractAccount', tokenAccount.toBase58()); +console.log('accountC', bAccount.toBase58()); +console.log('addressC', cAccount.toBase58()); console.log('receiverAddress', tokenAccount1.toBase58()); console.log('feePayer', sender.toBase58()); console.log('-------------------------------------------'); -console.log('compile (TokenContract)'); await Token.compile(); -console.log('compile (ZkAppB)'); -await ContractB.compile(); -console.log('compile (ZkAppC)'); -await ContractC.compile(); +await B.compile(); +await C.compile(); console.log('deploy tokenZkApp'); tx = await Mina.transaction(sender, async () => { - await tokenContract.deploy(); + await token.deploy(); AccountUpdate.fundNewAccount(sender).send({ - to: tokenContract.self, + to: token.self, amount: initialBalance, }); }); -await tx.sign([sender.key, tokenContractAccount.key]).send(); +await tx.sign([sender.key, tokenAccount.key]).send(); console.log('deploy zkAppB and zkAppC'); tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender, 2); - await contractC.deploy(); - await contractB.deploy(); - await tokenContract.approveAccountUpdates([contractC.self, contractB.self]); + await c.deploy(); + await b.deploy(); + await token.approveAccountUpdates([c.self, b.self]); }); console.log('deploy zkAppB and zkAppC (proof)'); await tx.prove(); -await tx.sign([sender.key, accountC.key, addressC.key]).send(); +await tx.sign([sender.key, bAccount.key, cAccount.key]).send(); console.log('mint token to zkAppB'); tx = await Mina.transaction(sender, async () => { - await tokenContract.mint(accountC); + await token.mint(bAccount); }); await tx.prove(); await tx.sign([sender.key]).send(); console.log('approve send from zkAppB'); tx = await Mina.transaction(sender, async () => { - await contractB.approveSend(); + await b.approveSend(); // we call the token contract with the self update - await tokenContract.transfer(contractB.self, addressC, 1_000); + await token.transfer(b.self, cAccount, 1_000); }); console.log('approve send (proof)'); await tx.prove(); @@ -107,17 +104,17 @@ await tx.sign([sender.key]).send(); console.log( `contractC's balance for tokenId: ${TokenId.toBase58(tokenId)}`, - Mina.getBalance(addressC, tokenId).value.toBigInt() + Mina.getBalance(cAccount, tokenId).value.toBigInt() ); console.log('approve send from zkAppC'); tx = await Mina.transaction(sender, async () => { // Pay for tokenAccount1's account creation AccountUpdate.fundNewAccount(sender); - await contractC.approveSend(); + await c.approveSend(); // we call the token contract with the tree - await tokenContract.transfer(contractC.self, tokenAccount1, 1_000); + await token.transfer(c.self, tokenAccount1, 1_000); }); console.log('approve send (proof)'); await tx.prove(); diff --git a/src/examples/zkapps/zkapp-self-update.ts b/src/examples/zkapps/zkapp-self-update.ts index dc0a6bd752..188650392e 100644 --- a/src/examples/zkapps/zkapp-self-update.ts +++ b/src/examples/zkapps/zkapp-self-update.ts @@ -12,7 +12,7 @@ import { TransactionVersion, } from 'o1js'; -class Contract extends SmartContract { +class SelfUpdater extends SmartContract { init() { super.init(); this.account.permissions.set({ @@ -41,13 +41,13 @@ const Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); const contractAccount = Mina.TestAccount.random(); -const contract = new Contract(contractAccount); +const contract = new SelfUpdater(contractAccount); const [deployer] = Local.testAccounts; // deploy first verification key -await Contract.compile(); +await SelfUpdater.compile(); const tx = await Mina.transaction(deployer, async () => { AccountUpdate.fundNewAccount(deployer); diff --git a/src/lib/mina/token.test.ts b/src/lib/mina/token.test.ts index 3bfa15f76e..2586b704c0 100644 --- a/src/lib/mina/token.test.ts +++ b/src/lib/mina/token.test.ts @@ -30,19 +30,16 @@ class TokenContract extends TokenContractBase { } /** - * This deploy method lets a another token account deploy their zkApp and verification key as a child of this token contract. - * This is important since we want the native token id of the deployed zkApp to be the token id of the token contract. + * This deploy method lets a another token account deploy their contract and verification key as a child of this token contract. + * This is important since we want the native token id of the deployed contract to be the token id of the token contract. */ - @method async deployZkapp( - address: PublicKey, - verificationKey: VerificationKey - ) { + @method async deploy_(address: PublicKey, verificationKey: VerificationKey) { let tokenId = this.deriveTokenId(); - let zkapp = AccountUpdate.defaultAccountUpdate(address, tokenId); - this.approve(zkapp); - zkapp.account.permissions.set(Permissions.default()); - zkapp.account.verificationKey.set(verificationKey); - zkapp.requireSignature(); + let au = AccountUpdate.defaultAccountUpdate(address, tokenId); + this.approve(au); + au.account.permissions.set(Permissions.default()); + au.account.verificationKey.set(verificationKey); + au.requireSignature(); } init() { @@ -101,13 +98,13 @@ class TokenContract extends TokenContractBase { } } -class ContractB extends SmartContract { +class B extends SmartContract { @method async approveSend(amount: UInt64) { this.balance.subInPlace(amount); } } -class ContractC extends SmartContract { +class C extends SmartContract { @method async approveSend(amount: UInt64) { this.balance.subInPlace(amount); } @@ -121,15 +118,15 @@ class ContractC extends SmartContract { let feePayer: Mina.TestAccount; -let tokenContractAccount: Mina.TestAccount; -let tokenContract: TokenContract; +let tokenAccount: Mina.TestAccount; +let token: TokenContract; let tokenId: Field; -let contractBAccount: Mina.TestAccount; -let contractB: ContractB; +let bAccount: Mina.TestAccount; +let b: B; -let contractCAccount: Mina.TestAccount; -let contractC: ContractC; +let cAccount: Mina.TestAccount; +let c: C; function setupAccounts() { let Local = Mina.LocalBlockchain({ @@ -137,57 +134,46 @@ function setupAccounts() { enforceTransactionLimits: false, }); Mina.setActiveInstance(Local); - [feePayer, contractBAccount, contractCAccount] = Local.testAccounts; - tokenContractAccount = Mina.TestAccount.random(); - tokenContract = new TokenContract(tokenContractAccount); - tokenId = tokenContract.deriveTokenId(); - contractB = new ContractB(contractBAccount, tokenId); - contractC = new ContractC(contractCAccount, tokenId); + [feePayer, bAccount, cAccount] = Local.testAccounts; + tokenAccount = Mina.TestAccount.random(); + token = new TokenContract(tokenAccount); + tokenId = token.deriveTokenId(); + b = new B(bAccount, tokenId); + c = new C(cAccount, tokenId); return Local; } async function setupLocal() { setupAccounts(); let tx = await Mina.transaction(feePayer, async () => { - await tokenContract.deploy(); + await token.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer); feePayerUpdate.send({ - to: tokenContract.self, + to: token.self, amount: Mina.getNetworkConstants().accountCreationFee, }); }); - tx.sign([tokenContractAccount.key, feePayer.key]); + tx.sign([tokenAccount.key, feePayer.key]); await tx.send(); } async function setupLocalProofs() { let Local = setupAccounts(); - contractC = new ContractC(contractCAccount, tokenId); + c = new C(cAccount, tokenId); // don't use proofs for the setup, takes too long to do this every time Local.setProofsEnabled(false); let tx = await Mina.transaction({ sender: feePayer }, async () => { - await tokenContract.deploy(); + await token.deploy(); let feePayerUpdate = AccountUpdate.fundNewAccount(feePayer, 3); feePayerUpdate.send({ - to: tokenContract.self, + to: token.self, amount: Mina.getNetworkConstants().accountCreationFee, }); - await tokenContract.deployZkapp( - contractBAccount, - ContractB._verificationKey! - ); - await tokenContract.deployZkapp( - contractCAccount, - ContractC._verificationKey! - ); + await token.deploy_(bAccount, B._verificationKey!); + await token.deploy_(cAccount, C._verificationKey!); }); await tx.prove(); - tx.sign([ - tokenContractAccount.key, - contractBAccount.key, - contractCAccount.key, - feePayer.key, - ]); + tx.sign([tokenAccount.key, bAccount.key, cAccount.key, feePayer.key]); await tx.send(); Local.setProofsEnabled(true); } @@ -195,8 +181,8 @@ async function setupLocalProofs() { describe('Token', () => { beforeAll(async () => { await TokenContract.compile(); - await ContractB.compile(); - await ContractC.compile(); + await B.compile(); + await C.compile(); }); describe('Signature Authorization', () => { @@ -205,7 +191,7 @@ describe('Token', () => { Check token contract can be deployed and initialized tested cases: - create a new token - - deploy a zkApp under a custom token + - deploy a contract under a custom token - create a new valid token with a different parentTokenId - set the token symbol after deployment */ @@ -215,23 +201,23 @@ describe('Token', () => { }); test('correct token id can be derived with an existing token owner', () => { - expect(tokenId).toEqual(TokenId.derive(tokenContractAccount)); + expect(tokenId).toEqual(TokenId.derive(tokenAccount)); }); test('deployed token contract exists in the ledger', () => { - expect(Mina.getAccount(tokenContractAccount, tokenId)).toBeDefined(); + expect(Mina.getAccount(tokenAccount, tokenId)).toBeDefined(); }); test('setting a valid token symbol on a token contract', async () => { await ( await Mina.transaction({ sender: feePayer }, async () => { - let tokenZkapp = AccountUpdate.createSigned(tokenContractAccount); - tokenZkapp.account.tokenSymbol.set(tokenSymbol); + let au = AccountUpdate.createSigned(tokenAccount); + au.account.tokenSymbol.set(tokenSymbol); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); - const symbol = Mina.getAccount(tokenContractAccount).tokenSymbol; + const symbol = Mina.getAccount(tokenAccount).tokenSymbol; expect(tokenSymbol).toBeDefined(); expect(symbol).toEqual(tokenSymbol); }); @@ -253,25 +239,22 @@ describe('Token', () => { await ( await Mina.transaction({ sender: feePayer }, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(100_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 100_000n + ); }); test('minting should fail if overflow occurs ', async () => { await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint( - contractBAccount, - UInt64.from(100_000_000_000) - ); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000_000_000)); + token.requireSignature(); }).catch((e) => { expect(e).toBeDefined(); }); @@ -293,41 +276,41 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); await ( await Mina.transaction(feePayer, async () => { - await tokenContract.burn(contractBAccount, UInt64.from(10_000)); - tokenContract.requireSignature(); + await token.burn(bAccount, UInt64.from(10_000)); + token.requireSignature(); }) ) - .sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]) + .sign([bAccount.key, feePayer.key, tokenAccount.key]) .send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(90_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 90_000n + ); }); test('throw error if token owner burns more tokens than token account has', async () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(1_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(1_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - await tokenContract.burn(contractBAccount, UInt64.from(10_000)); - tokenContract.requireSignature(); + await token.burn(bAccount, UInt64.from(10_000)); + token.requireSignature(); }) - ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); + ).sign([bAccount.key, feePayer.key, tokenAccount.key]); await expect(tx.send()).rejects.toThrow(); }); }); @@ -348,58 +331,53 @@ describe('Token', () => { test('change the balance of a token account after sending', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }); - await tx.sign([feePayer.key, tokenContractAccount.key]).send(); + await tx.sign([feePayer.key, tokenAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenContract.internal.send({ - from: contractBAccount, - to: contractCAccount, + token.internal.send({ + from: bAccount, + to: cAccount, amount: UInt64.from(10_000), }); - AccountUpdate.attachToTransaction(tokenContract.self); - tokenContract.requireSignature(); + AccountUpdate.attachToTransaction(token.self); + token.requireSignature(); }); - tx.sign([ - contractBAccount.key, - contractCAccount.key, - feePayer.key, - tokenContractAccount.key, - ]); + tx.sign([bAccount.key, cAccount.key, feePayer.key, tokenAccount.key]); await tx.send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(90_000n); - expect( - Mina.getBalance(contractCAccount, tokenId).value.toBigInt() - ).toEqual(10_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 90_000n + ); + expect(Mina.getBalance(cAccount, tokenId).value.toBigInt()).toEqual( + 10_000n + ); }); test('should error creating a token account if no account creation fee is specified', async () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenContract.internal.send({ - from: contractBAccount, - to: contractCAccount, + token.internal.send({ + from: bAccount, + to: cAccount, amount: UInt64.from(10_000), }); - AccountUpdate.attachToTransaction(tokenContract.self); - tokenContract.requireSignature(); + AccountUpdate.attachToTransaction(token.self); + token.requireSignature(); }) - ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); + ).sign([bAccount.key, feePayer.key, tokenAccount.key]); await expect(tx.send()).rejects.toThrow(); }); @@ -408,23 +386,23 @@ describe('Token', () => { await ( await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); let tx = ( await Mina.transaction(feePayer, async () => { - tokenContract.internal.send({ - from: contractBAccount, - to: contractCAccount, + token.internal.send({ + from: bAccount, + to: cAccount, amount: UInt64.from(100_000), }); - AccountUpdate.attachToTransaction(tokenContract.self); - tokenContract.requireSignature(); + AccountUpdate.attachToTransaction(token.self); + token.requireSignature(); }) - ).sign([contractBAccount.key, feePayer.key, tokenContractAccount.key]); + ).sign([bAccount.key, feePayer.key, tokenAccount.key]); await expect(tx.send()).rejects.toThrow(); }); }); @@ -445,15 +423,11 @@ describe('Token', () => { }); }); - test('should successfully deploy a token account under a zkApp', async () => { - expect(Mina.getAccount(contractBAccount, tokenId)).toBeDefined(); - expect(Mina.getAccount(contractBAccount, tokenId).tokenId).toEqual( - tokenId - ); - expect(Mina.getAccount(contractCAccount, tokenId)).toBeDefined(); - expect(Mina.getAccount(contractCAccount, tokenId).tokenId).toEqual( - tokenId - ); + test('should successfully deploy a token account under a contract', async () => { + expect(Mina.getAccount(bAccount, tokenId)).toBeDefined(); + expect(Mina.getAccount(bAccount, tokenId).tokenId).toEqual(tokenId); + expect(Mina.getAccount(cAccount, tokenId)).toBeDefined(); + expect(Mina.getAccount(cAccount, tokenId).tokenId).toEqual(tokenId); }); }); @@ -471,14 +445,14 @@ describe('Token', () => { test('token contract can successfully mint and updates the balances in the ledger (proof)', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); + await token.mint(bAccount, UInt64.from(100_000)); }); await tx.prove(); - tx.sign([tokenContractAccount.key, feePayer.key]); + tx.sign([tokenAccount.key, feePayer.key]); await tx.send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(100_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 100_000n + ); }); }); @@ -496,19 +470,19 @@ describe('Token', () => { test('token contract can successfully burn and updates the balances in the ledger (proof)', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }); - await tx.sign([feePayer.key, tokenContractAccount.key]).send(); + await tx.sign([feePayer.key, tokenAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { - await tokenContract.burn(contractBAccount, UInt64.from(10_000)); + await token.burn(bAccount, UInt64.from(10_000)); }); await tx.prove(); - tx.sign([contractBAccount.key, feePayer.key]); + tx.sign([bAccount.key, feePayer.key]); await tx.send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(90_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 90_000n + ); }); }); @@ -527,51 +501,51 @@ describe('Token', () => { test('should approve and the balance of a token account after sending', async () => { let tx = await Mina.transaction(feePayer, async () => { - await tokenContract.mint(contractBAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(bAccount, UInt64.from(100_000)); + token.requireSignature(); }); await tx.prove(); - await tx.sign([feePayer.key, tokenContractAccount.key]).send(); + await tx.sign([feePayer.key, tokenAccount.key]).send(); tx = await Mina.transaction(feePayer, async () => { - await contractB.approveSend(UInt64.from(10_000)); + await b.approveSend(UInt64.from(10_000)); - await tokenContract.approveTransfer( - contractBAccount, - contractCAccount, + await token.approveTransfer( + bAccount, + cAccount, UInt64.from(10_000), - contractB.self + b.self ); }); await tx.prove(); await tx.sign([feePayer.key]).send(); - expect( - Mina.getBalance(contractBAccount, tokenId).value.toBigInt() - ).toEqual(90_000n); - expect( - Mina.getBalance(contractCAccount, tokenId).value.toBigInt() - ).toEqual(10_000n); + expect(Mina.getBalance(bAccount, tokenId).value.toBigInt()).toEqual( + 90_000n + ); + expect(Mina.getBalance(cAccount, tokenId).value.toBigInt()).toEqual( + 10_000n + ); }); test('should fail to approve with an incorrect layout', async () => { await ( await Mina.transaction(feePayer, async () => { - await tokenContract.mint(contractCAccount, UInt64.from(100_000)); - tokenContract.requireSignature(); + await token.mint(cAccount, UInt64.from(100_000)); + token.requireSignature(); }) ) - .sign([feePayer.key, tokenContractAccount.key]) + .sign([feePayer.key, tokenAccount.key]) .send(); await expect(() => Mina.transaction(feePayer, async () => { - await contractC.approveIncorrectLayout(UInt64.from(10_000)); - await tokenContract.approveTransfer( - contractBAccount, - contractCAccount, + await c.approveIncorrectLayout(UInt64.from(10_000)); + await token.approveTransfer( + bAccount, + cAccount, UInt64.from(10_000), - contractC.self + c.self ); }) ).rejects.toThrow(); @@ -580,11 +554,11 @@ describe('Token', () => { test('should reject tx if user bypasses the token contract by using an empty account update', async () => { let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - tokenContract.internal.mint({ - address: contractBAccount, + token.internal.mint({ + address: bAccount, amount: UInt64.from(100_000), }); - AccountUpdate.attachToTransaction(tokenContract.self); + AccountUpdate.attachToTransaction(token.self); }); await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /Update_not_permitted_access/ From 3b55f83a12a13f9a240aa39ca407fa8de9bf9349 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 07:47:44 -0400 Subject: [PATCH 04/11] more convention related --- src/lib/mina/precondition.test.ts | 184 +++++++++--------- .../on-chain-state-mgmt-zkapp-ui.js | 54 +++-- 2 files changed, 115 insertions(+), 123 deletions(-) diff --git a/src/lib/mina/precondition.test.ts b/src/lib/mina/precondition.test.ts index 09525bb378..a032efec81 100644 --- a/src/lib/mina/precondition.test.ts +++ b/src/lib/mina/precondition.test.ts @@ -17,25 +17,24 @@ class MyContract extends SmartContract { } } -let zkappKey: PrivateKey; -let zkappAddress: Mina.TestAccount; -let zkapp: MyContract; +let contractAccount: Mina.TestAccount; +let contract: MyContract; let feePayer: Mina.TestAccount; beforeAll(async () => { - // set up local blockchain, create zkapp keys, deploy the contract + // set up local blockchain, create contract account keys, deploy the contract let Local = Mina.LocalBlockchain({ proofsEnabled: false }); Mina.setActiveInstance(Local); [feePayer] = Local.testAccounts; - zkappAddress = Mina.TestAccount.random(); - zkapp = new MyContract(zkappAddress); + contractAccount = Mina.TestAccount.random(); + contract = new MyContract(contractAccount); let tx = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); - await zkapp.deploy(); + await contract.deploy(); }); - tx.sign([feePayer.key, zkappKey]).send(); + tx.sign([feePayer.key, contractAccount.key]).send(); }); describe('preconditions', () => { @@ -44,7 +43,7 @@ describe('preconditions', () => { await expect( Mina.transaction(feePayer, async () => { precondition().get(); - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }) ).rejects.toThrow(/precondition/); } @@ -55,18 +54,18 @@ describe('preconditions', () => { }); it('get + requireEquals should not throw', async () => { - let nonce = zkapp.account.nonce.get(); + let nonce = contract.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { - zkapp.requireSignature(); + contract.requireSignature(); for (let precondition of implemented) { let p = precondition().get(); precondition().requireEquals(p as any); } - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }); - await tx.sign([feePayer.key, zkappKey]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); + expect(contract.account.nonce.get()).toEqual(nonce.add(1)); }); it('get + requireEquals should throw for unimplemented fields', async () => { @@ -75,81 +74,82 @@ describe('preconditions', () => { Mina.transaction(feePayer, async () => { let p = precondition(); p.requireEquals(p.get() as any); - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }) ).rejects.toThrow(/not implemented/); } }); it('get + requireBetween should not throw', async () => { - let nonce = zkapp.account.nonce.get(); + let nonce = contract.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { for (let precondition of implementedWithRange) { let p: any = precondition().get(); precondition().requireBetween(p.constructor.zero, p); } - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); + contract.requireSignature(); + AccountUpdate.attachToTransaction(contract.self); }); - await tx.sign([feePayer.key, zkappKey]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); + expect(contract.account.nonce.get()).toEqual(nonce.add(1)); }); it('satisfied currentSlot.requireBetween should not throw', async () => { - let nonce = zkapp.account.nonce.get(); + let nonce = contract.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { - zkapp.currentSlot.requireBetween( + contract.currentSlot.requireBetween( UInt32.from(0), UInt32.from(UInt32.MAXINT()) ); - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); + contract.requireSignature(); + AccountUpdate.attachToTransaction(contract.self); }); - await tx.sign([feePayer.key, zkappKey]).send(); - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); + await tx.sign([feePayer.key, contractAccount.key]).send(); + expect(contract.account.nonce.get()).toEqual(nonce.add(1)); }); it('get + requireNothing should not throw', async () => { - let nonce = zkapp.account.nonce.get(); + let nonce = contract.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { for (let precondition of implemented) { precondition().get(); precondition().requireNothing(); } - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); + contract.requireSignature(); + AccountUpdate.attachToTransaction(contract.self); }); - await tx.sign([feePayer.key, zkappKey]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); + expect(contract.account.nonce.get()).toEqual(nonce.add(1)); }); it('get + manual precondition should not throw', async () => { // we only test this for a couple of preconditions - let nonce = zkapp.account.nonce.get(); + let nonce = contract.account.nonce.get(); let tx = await Mina.transaction(feePayer, async () => { - zkapp.account.balance.get(); - zkapp.self.body.preconditions.account.balance.isSome = Bool(true); - zkapp.self.body.preconditions.account.balance.value.upper = + contract.account.balance.get(); + contract.self.body.preconditions.account.balance.isSome = Bool(true); + contract.self.body.preconditions.account.balance.value.upper = UInt64.from(10e9); - zkapp.network.blockchainLength.get(); - zkapp.self.body.preconditions.network.blockchainLength.isSome = + contract.network.blockchainLength.get(); + contract.self.body.preconditions.network.blockchainLength.isSome = Bool(true); - zkapp.self.body.preconditions.network.blockchainLength.value.upper = + contract.self.body.preconditions.network.blockchainLength.value.upper = UInt32.from(1000); - zkapp.network.totalCurrency.get(); - zkapp.self.body.preconditions.network.totalCurrency.isSome = Bool(true); - zkapp.self.body.preconditions.network.totalCurrency.value.upper = + contract.network.totalCurrency.get(); + contract.self.body.preconditions.network.totalCurrency.isSome = + Bool(true); + contract.self.body.preconditions.network.totalCurrency.value.upper = UInt64.from(1e9 * 1e9); - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); + contract.requireSignature(); + AccountUpdate.attachToTransaction(contract.self); }); - await tx.sign([feePayer.key, zkappKey]).send(); + await tx.sign([feePayer.key, contractAccount.key]).send(); // check that tx was applied, by checking nonce was incremented - expect(zkapp.account.nonce.get()).toEqual(nonce.add(1)); + expect(contract.account.nonce.get()).toEqual(nonce.add(1)); }); it('unsatisfied requireEquals should be rejected (numbers)', async () => { @@ -158,7 +158,7 @@ describe('preconditions', () => { let tx = await Mina.transaction(feePayer, async () => { let p = precondition().get(); precondition().requireEquals(p.add(1) as any); - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }); await tx.sign([feePayer.key]).send(); }).rejects.toThrow(/unsatisfied/); @@ -170,7 +170,7 @@ describe('preconditions', () => { let tx = await Mina.transaction(feePayer, async () => { let p = precondition().get(); precondition().requireEquals(p.not()); - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }); await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /unsatisfied/ @@ -181,8 +181,8 @@ describe('preconditions', () => { it('unsatisfied requireEquals should be rejected (public key)', async () => { let publicKey = PublicKey.from({ x: Field(-1), isOdd: Bool(false) }); let tx = await Mina.transaction(feePayer, async () => { - zkapp.account.delegate.requireEquals(publicKey); - AccountUpdate.attachToTransaction(zkapp.self); + contract.account.delegate.requireEquals(publicKey); + AccountUpdate.attachToTransaction(contract.self); }); await expect(tx.sign([feePayer.key]).send()).rejects.toThrow(/unsatisfied/); }); @@ -192,7 +192,7 @@ describe('preconditions', () => { let tx = await Mina.transaction(feePayer, async () => { let p: any = precondition().get(); precondition().requireBetween(p.add(20), p.add(30)); - AccountUpdate.attachToTransaction(zkapp.self); + AccountUpdate.attachToTransaction(contract.self); }); await expect(tx.sign([feePayer.key]).send()).rejects.toThrow( /unsatisfied/ @@ -202,8 +202,8 @@ describe('preconditions', () => { it('unsatisfied currentSlot.requireBetween should be rejected', async () => { let tx = await Mina.transaction(feePayer, async () => { - zkapp.currentSlot.requireBetween(UInt32.from(20), UInt32.from(30)); - AccountUpdate.attachToTransaction(zkapp.self); + contract.currentSlot.requireBetween(UInt32.from(20), UInt32.from(30)); + AccountUpdate.attachToTransaction(contract.self); }); await expect(tx.sign([feePayer.key]).send()).rejects.toThrow(/unsatisfied/); }); @@ -213,61 +213,61 @@ describe('preconditions', () => { // however, this is just because `zkapp.requireSignature()` overwrites the nonce precondition with one that is satisfied it.skip('unsatisfied nonce precondition should be rejected', async () => { let tx = await Mina.transaction(feePayer, async () => { - zkapp.account.nonce.requireEquals(UInt32.from(1e8)); - zkapp.requireSignature(); - AccountUpdate.attachToTransaction(zkapp.self); + contract.account.nonce.requireEquals(UInt32.from(1e8)); + contract.requireSignature(); + AccountUpdate.attachToTransaction(contract.self); }); - expect(() => tx.sign([zkappKey, feePayer.key]).send()).toThrow(); + expect(() => tx.sign([contractAccount.key, feePayer.key]).send()).toThrow(); }); }); let implementedNumber = [ - () => zkapp.account.balance, - () => zkapp.account.nonce, - () => zkapp.account.receiptChainHash, - () => zkapp.network.blockchainLength, - () => zkapp.network.globalSlotSinceGenesis, - () => zkapp.network.timestamp, - () => zkapp.network.minWindowDensity, - () => zkapp.network.totalCurrency, - () => zkapp.network.stakingEpochData.epochLength, - () => zkapp.network.stakingEpochData.ledger.totalCurrency, - () => zkapp.network.nextEpochData.epochLength, - () => zkapp.network.nextEpochData.ledger.totalCurrency, - () => zkapp.network.snarkedLedgerHash, - () => zkapp.network.stakingEpochData.lockCheckpoint, - () => zkapp.network.stakingEpochData.startCheckpoint, + () => contract.account.balance, + () => contract.account.nonce, + () => contract.account.receiptChainHash, + () => contract.network.blockchainLength, + () => contract.network.globalSlotSinceGenesis, + () => contract.network.timestamp, + () => contract.network.minWindowDensity, + () => contract.network.totalCurrency, + () => contract.network.stakingEpochData.epochLength, + () => contract.network.stakingEpochData.ledger.totalCurrency, + () => contract.network.nextEpochData.epochLength, + () => contract.network.nextEpochData.ledger.totalCurrency, + () => contract.network.snarkedLedgerHash, + () => contract.network.stakingEpochData.lockCheckpoint, + () => contract.network.stakingEpochData.startCheckpoint, // () => zkapp.network.stakingEpochData.seed, - () => zkapp.network.stakingEpochData.ledger.hash, - () => zkapp.network.nextEpochData.lockCheckpoint, - () => zkapp.network.nextEpochData.startCheckpoint, + () => contract.network.stakingEpochData.ledger.hash, + () => contract.network.nextEpochData.lockCheckpoint, + () => contract.network.nextEpochData.startCheckpoint, // () => zkapp.network.nextEpochData.seed, - () => zkapp.network.nextEpochData.ledger.hash, + () => contract.network.nextEpochData.ledger.hash, ]; let implementedBool = [ - () => zkapp.account.isNew, - () => zkapp.account.provedState, + () => contract.account.isNew, + () => contract.account.provedState, ]; let implemented = [ ...implementedNumber, ...implementedBool, - () => zkapp.account.delegate, + () => contract.account.delegate, ]; let implementedWithRange = [ - () => zkapp.account.balance, - () => zkapp.account.nonce, - () => zkapp.network.blockchainLength, - () => zkapp.network.globalSlotSinceGenesis, - () => zkapp.network.timestamp, - () => zkapp.network.minWindowDensity, - () => zkapp.network.totalCurrency, - () => zkapp.network.stakingEpochData.epochLength, - () => zkapp.network.stakingEpochData.ledger.totalCurrency, - () => zkapp.network.nextEpochData.epochLength, - () => zkapp.network.nextEpochData.ledger.totalCurrency, + () => contract.account.balance, + () => contract.account.nonce, + () => contract.network.blockchainLength, + () => contract.network.globalSlotSinceGenesis, + () => contract.network.timestamp, + () => contract.network.minWindowDensity, + () => contract.network.totalCurrency, + () => contract.network.stakingEpochData.epochLength, + () => contract.network.stakingEpochData.ledger.totalCurrency, + () => contract.network.nextEpochData.epochLength, + () => contract.network.nextEpochData.ledger.totalCurrency, ]; -let implementedWithRangeOnly = [() => zkapp.currentSlot]; +let implementedWithRangeOnly = [() => contract.currentSlot]; let unimplemented = [ - () => zkapp.network.stakingEpochData.seed, - () => zkapp.network.nextEpochData.seed, + () => contract.network.stakingEpochData.seed, + () => contract.network.nextEpochData.seed, ]; diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index 41e2a219ac..75884e94ee 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -9,7 +9,7 @@ const deployButton = document.querySelector('#deployButton'); const updateButton = document.querySelector('#updateButton'); const clearEventsButton = document.querySelector('#clearEventsButton'); const eventsContainer = document.querySelector('#eventsContainer'); -const zkAppStateContainer = document.querySelector('#zkAppStateContainer'); +const stateContainer = document.querySelector('#zkAppStateContainer'); logEvents( `o1js initialized after ${performance.now().toFixed(2)}ms`, @@ -20,37 +20,35 @@ logEvents( let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); // Test account that pays all the fees -const [feePayer] = Local.testAccounts -// zkApp account -const zkAppAccount = Mina.TestAccount.random() -const zkApp = new HelloWorld(zkAppAccount); +const [feePayer] = Local.testAccounts; +const contractAccount = Mina.TestAccount.random(); +const contract = new HelloWorld(contractAccount); let verificationKey = null; deployButton.addEventListener('click', async () => { deployButton.disabled = true; - logEvents('Deploying zkApp...', eventsContainer); + logEvents('Deploying...', eventsContainer); try { await HelloWorld.compile(); const deploymentTransaction = await Mina.transaction(feePayer, async () => { - if (!eventsContainer.innerHTML.includes('zkApp Deployed successfully')) { + if (!eventsContainer.innerHTML.includes('Deployed successfully')) { AccountUpdate.fundNewAccount(feePayer); } - await zkApp.deploy(); + await contract.deploy(); }); - await deploymentTransaction.sign([feePayer.key, zkAppAccount.key]).send(); + await deploymentTransaction + .sign([feePayer.key, contractAccount.key]) + .send(); const initialState = - Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); - zkAppStateContainer.innerHTML = initialState; + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); + stateContainer.innerHTML = initialState; logEvents(`Initial zkApp State: ${initialState}`, eventsContainer); - logEvents('zkApp Deployed successfully!', eventsContainer); + logEvents('Deployed successfully!', eventsContainer); } catch (exception) { - logEvents( - `zkApp Deployment failure: ${exception.message}`, - eventsContainer - ); + logEvents(`Deployment failure: ${exception.message}`, eventsContainer); console.log(exception); } @@ -64,18 +62,18 @@ updateButton.addEventListener('click', async (event) => { const formData = JSON.stringify( Object.fromEntries(new FormData(document.querySelector('#zkAppUpdateForm'))) ); - const zkAppStateValue = document.querySelector('#zkAppStateValue'); + const appStateValue = document.querySelector('#zkAppStateValue'); try { const currentState = - Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); logEvents( - `Updating zkApp State from ${currentState} to ${zkAppStateValue.value} with Admin Private Key and using form data: ${formData}...`, + `Updating zkApp State from ${currentState} to ${appStateValue.value} with Admin Private Key and using form data: ${formData}...`, eventsContainer ); const transaction = await Mina.transaction(feePayer, async () => { - await zkApp.update( - Field(parseInt(zkAppStateValue.value)), + await contract.update( + Field(parseInt(appStateValue.value)), adminPrivateKey ); }); @@ -90,17 +88,11 @@ updateButton.addEventListener('click', async (event) => { await transaction.sign([feePayer.key]).send(); const newState = - Mina.getAccount(zkAppAccount).zkapp?.appState?.[0].toString(); - zkAppStateContainer.innerHTML = newState; - logEvents( - `zkApp State successfully updated to: ${newState}!`, - eventsContainer - ); + Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); + stateContainer.innerHTML = newState; + logEvents(`State successfully updated to: ${newState}!`, eventsContainer); } catch (exception) { - logEvents( - `zkApp State Update failure: ${exception.message}`, - eventsContainer - ); + logEvents(`State Update failure: ${exception.message}`, eventsContainer); console.log(exception); } From fd4ea2d01c4f106ed3bf41177183a26c3cacc65c Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 10:09:42 -0400 Subject: [PATCH 05/11] Update src/lib/mina/local-blockchain.ts Co-authored-by: Gregor Mitscha-Baude --- src/lib/mina/local-blockchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 2388c4ea1e..6a84082e4a 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -54,7 +54,7 @@ class TestAccount extends PublicKey { } constructor(readonly key: PrivateKey) { - super(key.toPublicKey()); + super.from(key.toPublicKey()); } } /** From fffc927b40fbcfb6eef4a96b693bd370d926ecff Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 10:23:04 -0400 Subject: [PATCH 06/11] address cr feedback --- src/examples/nullifier.ts | 4 +-- src/examples/simple-zkapp.ts | 4 +-- src/examples/simple-zkapp.web.ts | 4 +-- src/examples/zkapps/composability.ts | 6 ++-- src/examples/zkapps/hashing/run.ts | 2 +- src/examples/zkapps/hello-world/run.ts | 2 +- src/examples/zkapps/local-events-zkapp.ts | 2 +- .../zkapps/merkle-tree/merkle-zkapp.ts | 2 +- src/examples/zkapps/reducer/map.ts | 2 +- .../zkapps/reducer/reducer-composite.ts | 2 +- .../zkapps/set-local-preconditions-zkapp.ts | 2 +- src/examples/zkapps/simple-zkapp-payment.ts | 2 +- .../zkapps/simple-zkapp-with-proof.ts | 2 +- src/examples/zkapps/token-with-proofs.ts | 2 +- src/examples/zkapps/zkapp-self-update.ts | 2 +- src/lib/mina/local-blockchain.ts | 29 ++++++++++--------- src/lib/mina/mina.ts | 4 +-- src/lib/mina/precondition.test.ts | 6 ++-- src/lib/mina/token.test.ts | 10 +++---- .../on-chain-state-mgmt-zkapp-ui.js | 2 +- 20 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/examples/nullifier.ts b/src/examples/nullifier.ts index 66fb852a46..e47e4f8138 100644 --- a/src/examples/nullifier.ts +++ b/src/examples/nullifier.ts @@ -54,10 +54,10 @@ Mina.setActiveInstance(Local); let [sender] = Local.testAccounts; // the contract account -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); // a special account that is allowed to pull out half of the contract balance, once -let privileged = Mina.TestAccount.random(); +let privileged = Mina.TestPublicKey.random(); let initialBalance = 10_000_000_000; let contract = new PayoutOnlyOnce(contractAccount); diff --git a/src/examples/simple-zkapp.ts b/src/examples/simple-zkapp.ts index da8d793b0e..a3859b503b 100644 --- a/src/examples/simple-zkapp.ts +++ b/src/examples/simple-zkapp.ts @@ -76,10 +76,10 @@ Mina.setActiveInstance(Local); let [sender, payout] = Local.testAccounts; // the zkapp account -let zkappAccount = Mina.TestAccount.random(); +let zkappAccount = Mina.TestPublicKey.random(); // a special account that is allowed to pull out half of the zkapp balance, once -let privileged = new Mina.TestAccount( +let privileged = Mina.TestPublicKey( PrivateKey.fromBase58('EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep') ); diff --git a/src/examples/simple-zkapp.web.ts b/src/examples/simple-zkapp.web.ts index bd03ce1373..27a7dae0c4 100644 --- a/src/examples/simple-zkapp.web.ts +++ b/src/examples/simple-zkapp.web.ts @@ -69,10 +69,10 @@ Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the contract let [sender] = Local.testAccounts; -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); // a special account that is allowed to pull out half of the contract balance, once -let privileged = new Mina.TestAccount( +let privileged = Mina.TestPublicKey( PrivateKey.fromBase58('EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep') ); diff --git a/src/examples/zkapps/composability.ts b/src/examples/zkapps/composability.ts index dffac43b83..8c4097be0b 100644 --- a/src/examples/zkapps/composability.ts +++ b/src/examples/zkapps/composability.ts @@ -58,11 +58,11 @@ Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts; -let incrementerAccount = Mina.TestAccount.random(); +let incrementerAccount = Mina.TestPublicKey.random(); let incrementer = new Incrementer(incrementerAccount); -let adderAccount = Mina.TestAccount.random(); +let adderAccount = Mina.TestPublicKey.random(); let adder = new Adder(adderAccount); -let callerAccount = Mina.TestAccount.random(); +let callerAccount = Mina.TestPublicKey.random(); let caller = new Caller(callerAccount); if (doProofs) { diff --git a/src/examples/zkapps/hashing/run.ts b/src/examples/zkapps/hashing/run.ts index cbc7d7c876..c656a385e1 100644 --- a/src/examples/zkapps/hashing/run.ts +++ b/src/examples/zkapps/hashing/run.ts @@ -16,7 +16,7 @@ if (proofsEnabled) { const [feePayer] = Local.testAccounts; // zkapp account -const contractAccount = Mina.TestAccount.random(); +const contractAccount = Mina.TestPublicKey.random(); const contract = new HashStorage(contractAccount); // 0, 1, 2, 3, ..., 31 diff --git a/src/examples/zkapps/hello-world/run.ts b/src/examples/zkapps/hello-world/run.ts index db86e5d193..50372b53d3 100644 --- a/src/examples/zkapps/hello-world/run.ts +++ b/src/examples/zkapps/hello-world/run.ts @@ -14,7 +14,7 @@ Mina.setActiveInstance(Local); const [feePayer1, feePayer2, feePayer3, feePayer4] = Local.testAccounts; // zkapp account -const contractAccount = Mina.TestAccount.random(); +const contractAccount = Mina.TestPublicKey.random(); const contract = new HelloWorld(contractAccount); console.log('Deploying Hello World ....'); diff --git a/src/examples/zkapps/local-events-zkapp.ts b/src/examples/zkapps/local-events-zkapp.ts index 5cbee1c160..3396d15c63 100644 --- a/src/examples/zkapps/local-events-zkapp.ts +++ b/src/examples/zkapps/local-events-zkapp.ts @@ -47,7 +47,7 @@ Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp const [feePayer] = Local.testAccounts; -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); let contract = new LocalEvents(contractAccount); let initialState = Field(1); diff --git a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts index b2dfa3f5db..060944f533 100644 --- a/src/examples/zkapps/merkle-tree/merkle-zkapp.ts +++ b/src/examples/zkapps/merkle-tree/merkle-zkapp.ts @@ -97,7 +97,7 @@ let initialBalance = 10_000_000_000; let [feePayer] = Local.testAccounts; -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); // this map serves as our off-chain in-memory storage let Accounts: Map = new Map( diff --git a/src/examples/zkapps/reducer/map.ts b/src/examples/zkapps/reducer/map.ts index c185eefda3..d65f998219 100644 --- a/src/examples/zkapps/reducer/map.ts +++ b/src/examples/zkapps/reducer/map.ts @@ -97,7 +97,7 @@ console.log('set rows:', cs['set'].rows); let [feePayer] = Local.testAccounts; // the contract account -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); let contract = new StorageContract(contractAccount); await StorageContract.compile(); diff --git a/src/examples/zkapps/reducer/reducer-composite.ts b/src/examples/zkapps/reducer/reducer-composite.ts index 975412e372..7cc2807b71 100644 --- a/src/examples/zkapps/reducer/reducer-composite.ts +++ b/src/examples/zkapps/reducer/reducer-composite.ts @@ -79,7 +79,7 @@ Mina.setActiveInstance(Local); let [feePayer] = Local.testAccounts; // the contract account -let contractAccount = new Mina.TestAccount( +let contractAccount = Mina.TestPublicKey( PrivateKey.fromBase58('EKEQc95PPQZnMY9d9p1vq1MWLeDJKtvKj4V75UDG3rjnf32BerWD') ); let contract = new Counter(contractAccount); diff --git a/src/examples/zkapps/set-local-preconditions-zkapp.ts b/src/examples/zkapps/set-local-preconditions-zkapp.ts index f7686b0b47..cc09bd2f81 100644 --- a/src/examples/zkapps/set-local-preconditions-zkapp.ts +++ b/src/examples/zkapps/set-local-preconditions-zkapp.ts @@ -24,7 +24,7 @@ Mina.setActiveInstance(Local); const [feePayer] = Local.testAccounts; -let contractAccount = Mina.TestAccount.random(); +let contractAccount = Mina.TestPublicKey.random(); let contract = new BlockHeightReference(contractAccount); diff --git a/src/examples/zkapps/simple-zkapp-payment.ts b/src/examples/zkapps/simple-zkapp-payment.ts index 77f8cb337b..8a17144e5f 100644 --- a/src/examples/zkapps/simple-zkapp-payment.ts +++ b/src/examples/zkapps/simple-zkapp-payment.ts @@ -37,7 +37,7 @@ Mina.setActiveInstance(Local); // a test account that pays all the fees, and puts additional funds into the zkapp const [feePayer] = Local.testAccounts; -const [contractAccount, account1, account2] = Mina.TestAccount.random(3); +const [contractAccount, account1, account2] = Mina.TestPublicKey.random(3); function printBalances() { console.log( diff --git a/src/examples/zkapps/simple-zkapp-with-proof.ts b/src/examples/zkapps/simple-zkapp-with-proof.ts index 493c47d79d..693a8a7762 100644 --- a/src/examples/zkapps/simple-zkapp-with-proof.ts +++ b/src/examples/zkapps/simple-zkapp-with-proof.ts @@ -46,7 +46,7 @@ Mina.setActiveInstance(Local); let [feePayer] = Local.testAccounts; const [trivialContractAccount, notSoSimpleContractAccount] = - Mina.TestAccount.random(2); + Mina.TestPublicKey.random(2); // compile and prove trivial zkapp console.log('compile (trivial zkapp)'); diff --git a/src/examples/zkapps/token-with-proofs.ts b/src/examples/zkapps/token-with-proofs.ts index 8221f9bc25..8765081aa3 100644 --- a/src/examples/zkapps/token-with-proofs.ts +++ b/src/examples/zkapps/token-with-proofs.ts @@ -44,7 +44,7 @@ Mina.setActiveInstance(Local); let [sender, tokenAccount1] = Local.testAccounts; let initialBalance = 10_000_000; -const [tokenAccount, cAccount, bAccount] = Mina.TestAccount.random(3); +const [tokenAccount, cAccount, bAccount] = Mina.TestPublicKey.random(3); let token = new Token(tokenAccount); let tokenId = token.deriveTokenId(); diff --git a/src/examples/zkapps/zkapp-self-update.ts b/src/examples/zkapps/zkapp-self-update.ts index 188650392e..b7fe46e1dc 100644 --- a/src/examples/zkapps/zkapp-self-update.ts +++ b/src/examples/zkapps/zkapp-self-update.ts @@ -40,7 +40,7 @@ class Bar extends SmartContract { const Local = Mina.LocalBlockchain({ proofsEnabled: true }); Mina.setActiveInstance(Local); -const contractAccount = Mina.TestAccount.random(); +const contractAccount = Mina.TestPublicKey.random(); const contract = new SelfUpdater(contractAccount); const [deployer] = Local.testAccounts; diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index 6a84082e4a..7dcdf41eba 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -40,22 +40,23 @@ import { verifyAccountUpdate, } from './transaction-validation.js'; -export { LocalBlockchain, TestAccount }; +export { LocalBlockchain, TestPublicKey }; -class TestAccount extends PublicKey { - static random( +type TestPublicKey = PublicKey & { + key: PrivateKey; +}; +function TestPublicKey(key: PrivateKey): TestPublicKey { + return Object.assign(PublicKey.fromPrivateKey(key), { key }); +} +namespace TestPublicKey { + export function random( count: N = 1 as never - ): N extends 1 ? TestAccount : TupleN { - if (count === 1) return new this(PrivateKey.random()) as never; - return Array.from( - { length: count as number }, - () => new this(PrivateKey.random()) + ): N extends 1 ? TestPublicKey : TupleN { + if (count === 1) return TestPublicKey(PrivateKey.random()) as never; + return Array.from({ length: count as number }, () => + TestPublicKey(PrivateKey.random()) ) as never; } - - constructor(readonly key: PrivateKey) { - super.from(key.toPublicKey()); - } } /** * A mock Mina blockchain running locally and useful for testing. @@ -76,12 +77,12 @@ function LocalBlockchain({ ledger.addAccount(Ml.fromPublicKey(publicKey), balance); } - let testAccounts = [] as never as TupleN; + let testAccounts = [] as never as TupleN; for (let i = 0; i < 100; ++i) { let MINA = 10n ** 9n; const largeValue = 1000n * MINA; - const testAccount = TestAccount.random(); + const testAccount = TestPublicKey.random(); addAccount(testAccount, largeValue.toString()); testAccounts.push(testAccount); } diff --git a/src/lib/mina/mina.ts b/src/lib/mina/mina.ts index 8977c32c60..68697e3844 100644 --- a/src/lib/mina/mina.ts +++ b/src/lib/mina/mina.ts @@ -50,7 +50,7 @@ import { defaultNetworkState, filterGroups, } from './transaction-validation.js'; -import { LocalBlockchain, TestAccount } from './local-blockchain.js'; +import { LocalBlockchain, TestPublicKey } from './local-blockchain.js'; export { LocalBlockchain, @@ -62,7 +62,7 @@ export { type RejectedTransaction, type PendingTransactionStatus, type PendingTransactionPromise, - TestAccount, + TestPublicKey, activeInstance, setActiveInstance, transaction, diff --git a/src/lib/mina/precondition.test.ts b/src/lib/mina/precondition.test.ts index a032efec81..1737e7a080 100644 --- a/src/lib/mina/precondition.test.ts +++ b/src/lib/mina/precondition.test.ts @@ -17,9 +17,9 @@ class MyContract extends SmartContract { } } -let contractAccount: Mina.TestAccount; +let contractAccount: Mina.TestPublicKey; let contract: MyContract; -let feePayer: Mina.TestAccount; +let feePayer: Mina.TestPublicKey; beforeAll(async () => { // set up local blockchain, create contract account keys, deploy the contract @@ -27,7 +27,7 @@ beforeAll(async () => { Mina.setActiveInstance(Local); [feePayer] = Local.testAccounts; - contractAccount = Mina.TestAccount.random(); + contractAccount = Mina.TestPublicKey.random(); contract = new MyContract(contractAccount); let tx = await Mina.transaction(feePayer, async () => { diff --git a/src/lib/mina/token.test.ts b/src/lib/mina/token.test.ts index 2586b704c0..59cf540fd0 100644 --- a/src/lib/mina/token.test.ts +++ b/src/lib/mina/token.test.ts @@ -116,16 +116,16 @@ class C extends SmartContract { } } -let feePayer: Mina.TestAccount; +let feePayer: Mina.TestPublicKey; -let tokenAccount: Mina.TestAccount; +let tokenAccount: Mina.TestPublicKey; let token: TokenContract; let tokenId: Field; -let bAccount: Mina.TestAccount; +let bAccount: Mina.TestPublicKey; let b: B; -let cAccount: Mina.TestAccount; +let cAccount: Mina.TestPublicKey; let c: C; function setupAccounts() { @@ -135,7 +135,7 @@ function setupAccounts() { }); Mina.setActiveInstance(Local); [feePayer, bAccount, cAccount] = Local.testAccounts; - tokenAccount = Mina.TestAccount.random(); + tokenAccount = Mina.TestPublicKey.random(); token = new TokenContract(tokenAccount); tokenId = token.deriveTokenId(); b = new B(bAccount, tokenId); diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index 75884e94ee..9c407b3fe1 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -21,7 +21,7 @@ let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); // Test account that pays all the fees const [feePayer] = Local.testAccounts; -const contractAccount = Mina.TestAccount.random(); +const contractAccount = Mina.TestPublicKey.random(); const contract = new HelloWorld(contractAccount); let verificationKey = null; From 07534cd7d2d22e23f7ace813a3fc63218c9bcc5a Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 10:26:11 -0400 Subject: [PATCH 07/11] name change --- .../javascript/on-chain-state-mgmt-zkapp-ui.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index 9c407b3fe1..6ad25e9162 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -21,8 +21,8 @@ let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); // Test account that pays all the fees const [feePayer] = Local.testAccounts; -const contractAccount = Mina.TestPublicKey.random(); -const contract = new HelloWorld(contractAccount); +const contractAddress = Mina.TestPublicKey.random(); +const contract = new HelloWorld(contractAddress); let verificationKey = null; deployButton.addEventListener('click', async () => { @@ -40,10 +40,10 @@ deployButton.addEventListener('click', async () => { }); await deploymentTransaction - .sign([feePayer.key, contractAccount.key]) + .sign([feePayer.key, contractAddress.key]) .send(); const initialState = - Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAddress).zkapp?.appState?.[0].toString(); stateContainer.innerHTML = initialState; logEvents(`Initial zkApp State: ${initialState}`, eventsContainer); logEvents('Deployed successfully!', eventsContainer); @@ -66,7 +66,7 @@ updateButton.addEventListener('click', async (event) => { try { const currentState = - Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAddress).zkapp?.appState?.[0].toString(); logEvents( `Updating zkApp State from ${currentState} to ${appStateValue.value} with Admin Private Key and using form data: ${formData}...`, eventsContainer @@ -88,7 +88,7 @@ updateButton.addEventListener('click', async (event) => { await transaction.sign([feePayer.key]).send(); const newState = - Mina.getAccount(contractAccount).zkapp?.appState?.[0].toString(); + Mina.getAccount(contractAddress).zkapp?.appState?.[0].toString(); stateContainer.innerHTML = newState; logEvents(`State successfully updated to: ${newState}!`, eventsContainer); } catch (exception) { From ab1b5cdaa44740378b9e47f363fa04069901b4e5 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 11:38:31 -0400 Subject: [PATCH 08/11] fix typo in cjs example --- src/examples/commonjs.cjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/examples/commonjs.cjs b/src/examples/commonjs.cjs index 5cfb93e839..664c505770 100644 --- a/src/examples/commonjs.cjs +++ b/src/examples/commonjs.cjs @@ -38,9 +38,9 @@ declareMethods(Updater, { update: [Field] }); let Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); -const [feePayer] = Local.testAccounts +const [feePayer] = Local.testAccounts; -let contractAccount = new Mina.random(); +let contractAccount = Mina.TestPublicKey.random(); let contract = new Updater(contractAccount); let initialState = Field(1); From 575096c290c0344cd420621bed76351c67645f59 Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Mon, 15 Apr 2024 14:50:41 -0400 Subject: [PATCH 09/11] fix breaking test --- .../on-chain-state-mgmt-zkapp-ui.js | 6 ++--- tests/pages/on-chain-state-mgmt-zkapp.ts | 26 +++++++------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js index 6ad25e9162..c3b2c08373 100644 --- a/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js +++ b/tests/artifacts/javascript/on-chain-state-mgmt-zkapp-ui.js @@ -3,7 +3,7 @@ import { adminPrivateKey, HelloWorld, } from './examples/zkapps/hello-world/hello-world.js'; -import { AccountUpdate, Field, Mina, PrivateKey, verify } from './index.js'; +import { AccountUpdate, Field, Mina, verify } from './index.js'; const deployButton = document.querySelector('#deployButton'); const updateButton = document.querySelector('#updateButton'); @@ -45,7 +45,7 @@ deployButton.addEventListener('click', async () => { const initialState = Mina.getAccount(contractAddress).zkapp?.appState?.[0].toString(); stateContainer.innerHTML = initialState; - logEvents(`Initial zkApp State: ${initialState}`, eventsContainer); + logEvents(`Initial state: ${initialState}`, eventsContainer); logEvents('Deployed successfully!', eventsContainer); } catch (exception) { logEvents(`Deployment failure: ${exception.message}`, eventsContainer); @@ -68,7 +68,7 @@ updateButton.addEventListener('click', async (event) => { const currentState = Mina.getAccount(contractAddress).zkapp?.appState?.[0].toString(); logEvents( - `Updating zkApp State from ${currentState} to ${appStateValue.value} with Admin Private Key and using form data: ${formData}...`, + `Updating state from ${currentState} to ${appStateValue.value} with Admin Private Key and using form data: ${formData}...`, eventsContainer ); const transaction = await Mina.transaction(feePayer, async () => { diff --git a/tests/pages/on-chain-state-mgmt-zkapp.ts b/tests/pages/on-chain-state-mgmt-zkapp.ts index 092ae65bf4..bf1a8027d9 100644 --- a/tests/pages/on-chain-state-mgmt-zkapp.ts +++ b/tests/pages/on-chain-state-mgmt-zkapp.ts @@ -41,36 +41,30 @@ export class OnChainStateMgmtZkAppPage { } async checkDeployedZkApp() { - await expect(this.eventsContainer).toContainText('Deploying zkApp'); - await expect(this.eventsContainer).toContainText('Initial zkApp State: 2'); - await expect(this.eventsContainer).toContainText( - 'zkApp Deployed successfully!' - ); + await expect(this.eventsContainer).toContainText('Deploying'); + await expect(this.eventsContainer).toContainText('Initial state: 2'); + await expect(this.eventsContainer).toContainText('Deployed successfully!'); await expect(this.zkAppStateContainer).toHaveText('2'); } async checkUpdatedZkAppState(currentValue: string, nextValue: string) { await expect(this.eventsContainer).toContainText( - `Updating zkApp State from ${currentValue} to ${nextValue}` + `Updating state from ${currentValue} to ${nextValue}` ); await expect(this.eventsContainer).toContainText( - `zkApp State successfully updated to: ${nextValue}!` + `State successfully updated to: ${nextValue}!` ); await expect(this.zkAppStateContainer).toHaveText(nextValue); } async checkZkAppDeploymentFailureByFeeExcess() { - await expect(this.eventsContainer).toContainText('Deploying zkApp'); - await expect(this.eventsContainer).toContainText( - 'zkApp Deployment failure' - ); + await expect(this.eventsContainer).toContainText('Deploying'); + await expect(this.eventsContainer).toContainText('Deployment failure'); await expect(this.eventsContainer).toContainText('Invalid_fee_excess'); } async checkZkAppStateUpdateFailureByUnknownAccount() { - await expect(this.eventsContainer).toContainText( - 'zkApp State Update failure' - ); + await expect(this.eventsContainer).toContainText('State update failure'); await expect(this.eventsContainer).toContainText( 'Could not find account for public key' ); @@ -83,10 +77,10 @@ export class OnChainStateMgmtZkAppPage { expectedValue: string ) { await expect(this.eventsContainer).toContainText( - `Updating zkApp State from ${actualValue} to ${expectedValue}` + `Updating state from ${actualValue} to ${expectedValue}` ); await expect(this.eventsContainer).toContainText( - `zkApp State Update failure: Field.assertEquals(): ${nextValue} != ${expectedValue}` + `State Update failure: Field.assertEquals(): ${nextValue} != ${expectedValue}` ); await expect(this.zkAppStateContainer).toHaveText(actualValue); } From e74ef4559eb7c7b1cfdca58a92f862d31735f84f Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Tue, 16 Apr 2024 07:31:29 -0400 Subject: [PATCH 10/11] back to 10 test public keys --- src/lib/mina/local-blockchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index df70db4ff2..c39e72c4fc 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -83,7 +83,7 @@ function LocalBlockchain({ let testAccounts = [] as never as TupleN; - for (let i = 0; i < 100; ++i) { + for (let i = 0; i < 10; ++i) { let MINA = 10n ** 9n; const largeValue = 1000n * MINA; const testAccount = TestPublicKey.random(); From 95d32f5ec939eefff747acf89b92f9964ea6c06a Mon Sep 17 00:00:00 2001 From: Harry Solovay Date: Tue, 16 Apr 2024 07:32:08 -0400 Subject: [PATCH 11/11] back to 10 test public keys --- src/lib/mina/local-blockchain.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/mina/local-blockchain.ts b/src/lib/mina/local-blockchain.ts index c39e72c4fc..69f2151603 100644 --- a/src/lib/mina/local-blockchain.ts +++ b/src/lib/mina/local-blockchain.ts @@ -81,7 +81,7 @@ function LocalBlockchain({ } } - let testAccounts = [] as never as TupleN; + let testAccounts = [] as never as TupleN; for (let i = 0; i < 10; ++i) { let MINA = 10n ** 9n;