Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement TestPublicKey util and refactor examples #1574

Merged
merged 12 commits into from
Apr 16, 2024
6 changes: 3 additions & 3 deletions src/examples/chaining-tx-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();

Expand All @@ -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();

Expand Down
29 changes: 13 additions & 16 deletions src/examples/commonjs.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
let {
Field,
State,
PrivateKey,
SmartContract,
Mina,
AccountUpdate,
declareState,
declareMethods,
} = require('o1js');

class SimpleZkapp extends SmartContract {
class Updater extends SmartContract {
constructor(address) {
super(address);
this.x = State();
Expand All @@ -33,39 +32,37 @@ class SimpleZkapp extends SmartContract {
this.x.set(x.add(y));
}
}
declareState(SimpleZkapp, { x: Field });
declareMethods(SimpleZkapp, { update: [Field] });
declareState(Updater, { x: Field });
declareMethods(Updater, { 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 = Mina.TestPublicKey.random();
let contract = new Updater(contractAccount);

let initialState = Field(1);
let zkapp = new SimpleZkapp(zkappAddress);

main();

async function main() {
console.log('compile');
await SimpleZkapp.compile();
await Updater.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());
}
46 changes: 22 additions & 24 deletions src/examples/nullifier.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import {
PrivateKey,
Nullifier,
Field,
SmartContract,
state,
State,
method,
MerkleMap,
Circuit,
MerkleMapWitness,
Mina,
AccountUpdate,
Expand Down Expand Up @@ -52,19 +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
let { privateKey: senderKey, publicKey: sender } = Local.testAccounts[0];
// 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();
// the contract account
let contractAccount = Mina.TestPublicKey.random();

// a special account that is allowed to pull out half of the zkapp balance, once
let privilegedKey = PrivateKey.random();
let privilegedAddress = privilegedKey.toPublicKey();
// a special account that is allowed to pull out half of the contract balance, once
let privileged = Mina.TestPublicKey.random();

let initialBalance = 10_000_000_000;
let zkapp = new PayoutOnlyOnce(zkappAddress);
let contract = new PayoutOnlyOnce(contractAccount);

// a unique message
let nullifierMessage = Field(5);
Expand All @@ -75,47 +71,49 @@ await PayoutOnlyOnce.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();

zkapp.nullifierRoot.set(NullifierTree.getRoot());
zkapp.nullifierMessage.set(nullifierMessage);
contract.nullifierRoot.set(NullifierTree.getRoot());
contract.nullifierMessage.set(nullifierMessage);
});
await tx.prove();
await tx.sign([senderKey, zkappKey]).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');

let jsonNullifier = Nullifier.createTestNullifier(
[nullifierMessage],
privilegedKey
privileged.key
);
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([senderKey]).send();
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(privilegedAddress).balance.div(1e9)} MINA`
`user balance: ${Mina.getAccount(privileged).balance.div(1e9)} MINA`
);

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();
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:'
Expand Down
29 changes: 13 additions & 16 deletions src/examples/simple-zkapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
import {
Field,
State,
PrivateKey,
SmartContract,
Mina,
AccountUpdate,
declareState,
declareMethods,
} from 'o1js';

class SimpleZkapp extends SmartContract {
class Updater extends SmartContract {
constructor(address) {
super(address);
this.x = State();
Expand All @@ -36,35 +35,33 @@ class SimpleZkapp extends SmartContract {
this.x.set(x.add(y));
}
}
declareState(SimpleZkapp, { x: Field });
declareMethods(SimpleZkapp, { update: [Field] });
declareState(Updater, { x: Field });
declareMethods(Updater, { 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 = Mina.TestAccount.random()

let initialState = Field(1);
let zkapp = new SimpleZkapp(zkappAddress);
let contract = new Updater(contractAccount);

console.log('compile');
await SimpleZkapp.compile();
await Updater.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());
38 changes: 18 additions & 20 deletions src/examples/simple-zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.TestPublicKey.random();

// a special account that is allowed to pull out half of the zkapp balance, once
let privilegedKey = PrivateKey.fromBase58(
'EKEeoESE2A41YQnSht9f7mjiKpJSeZ4jnfHXYatYi8xJdYSxWBep'
let privileged = Mina.TestPublicKey(
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');
Expand All @@ -101,63 +99,63 @@ 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');
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());
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);
}

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);
}
Expand Down
Loading