Skip to content

Instantly share code, notes, and snippets.

@marekyggdrasil
Last active December 5, 2022 21:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marekyggdrasil/9c26025a618dabe2a9a6113040e690e6 to your computer and use it in GitHub Desktop.
Save marekyggdrasil/9c26025a618dabe2a9a6113040e690e6 to your computer and use it in GitHub Desktop.
MINA zkApp that allows deposits and withdrawals

A very simple zkApp that allows user to deposit and withdraw. Run it with

node --experimental-vm-modules --experimental-wasm-modules --experimental-wasm-threads node_modules/jest/bin/jest.js -- fakemac.test.ts
import {
isReady,
shutdown,
Mina,
PrivateKey,
PublicKey,
UInt64,
AccountUpdate,
} from 'snarkyjs';
import { FakeMac } from './fakemac';
function createLocalBlockchain() {
const Local = Mina.LocalBlockchain();
Mina.setActiveInstance(Local);
let deployerAccount: PrivateKey = Local.testAccounts[0].privateKey;
let user_sk: PrivateKey = Local.testAccounts[1].privateKey;
return [deployerAccount, user_sk];
}
async function localDeploy(
zkAppInstance: FakeMac,
zkAppPrivatekey: PrivateKey,
deployerAccount: PrivateKey
) {
const tx = await Mina.transaction(deployerAccount, () => {
AccountUpdate.fundNewAccount(deployerAccount);
zkAppInstance.deploy({ zkappKey: zkAppPrivatekey });
zkAppInstance.sign(zkAppPrivatekey);
});
// await tx.prove();
await tx.send();
}
describe('Mac tests', () => {
let user_sk: PrivateKey;
let user_pk: PublicKey;
let deployerAccount: PrivateKey;
let zkAppPrivateKey: PrivateKey;
let zkAppAddress: PublicKey;
beforeEach(async () => {
await isReady;
await FakeMac.compile();
zkAppPrivateKey = PrivateKey.random();
zkAppAddress = zkAppPrivateKey.toPublicKey();
[deployerAccount, user_sk] = createLocalBlockchain();
user_pk = user_sk.toPublicKey();
});
afterAll(async () => {
setTimeout(shutdown, 0);
});
it('should correctly deploy, deposit and withdraw', async () => {
// deploy
const zkAppInstance = new FakeMac(zkAppAddress);
await localDeploy(zkAppInstance, zkAppPrivateKey, deployerAccount);
// ensure the user has full balance
Mina.getBalance(zkAppAddress).assertEquals(UInt64.from(0));
Mina.getBalance(user_pk).assertEquals(UInt64.from(1000000000000));
// deposit transaction
const tx_deposit = await Mina.transaction(user_sk, () => {
zkAppInstance.deposit(user_pk);
});
await tx_deposit.prove();
await tx_deposit.sign([user_sk]);
await tx_deposit.send();
// amount has been moved from the user to the contract
Mina.getBalance(zkAppAddress).assertEquals(UInt64.from(1000000));
Mina.getBalance(user_pk).assertEquals(UInt64.from(999999000000));
// withdraw transaction
const tx_withdraw = await Mina.transaction(user_sk, () => {
zkAppInstance.withdraw(user_pk);
});
await tx_withdraw.prove();
await tx_withdraw.sign([user_sk]);
await tx_withdraw.send();
// back to initial balance
Mina.getBalance(zkAppAddress).assertEquals(UInt64.from(0));
Mina.getBalance(user_pk).assertEquals(UInt64.from(1000000000000));
});
});
import {
SmartContract,
state,
State,
method,
DeployArgs,
Permissions,
UInt64,
AccountUpdate,
PrivateKey,
PublicKey,
} from 'snarkyjs';
export class FakeMac extends SmartContract {
deploy(args: DeployArgs) {
super.deploy(args);
this.setPermissions({
...Permissions.default(),
editState: Permissions.proof(),
send: Permissions.proof(),
});
}
@method deposit(user: PublicKey) {
const payerUpdate = AccountUpdate.create(user);
payerUpdate.send({ to: this.address, amount: UInt64.from(1000000) });
}
@method withdraw(user: PublicKey) {
this.send({ to: user, amount: UInt64.from(1000000) });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment