Account updates in Mina are handled within transactions with AccountUpdate class. Also, there are so many properties of ZkApps that are implemented by AccountUpdate class. You should see the for learning the properties of it.
Example:
ZkLocus is a ZkApp that ensures the location you shared is true, while you are able to keep your exacy location private. Here, the file:
import { DeployArgs, SmartContract, State, state, Permissions, method, Field, PublicKey, AccountUpdate, UInt64 } from "o1js";
import { ZKLContract } from "../tokens/zkl/ZKLContract";
export class BountySC extends SmartContract {
@state(Field) deployer = State<Field>();
@state(Field) funder = State<Field>();
async deploy(args: DeployArgs) {
super.deploy(args);
this.account.permissions.set({
...Permissions.default(),
editState: Permissions.proofOrSignature(),
});
}
/**
* Claims the bounty by transferring the ZKL tokens to the claimer's address.
*
* @param zklTokenAddr - The address of the ZKL token contract.
*/
@method async claim(zklTokenAddr: PublicKey) {
// ensure that the sender is the claimed one, by requiring a signature
const claimer: PublicKey = this.sender.getAndRequireSignature();
const ac: AccountUpdate = AccountUpdate.createSigned(claimer);
this.approve(ac);
const zklTokenSC: ZKLContract = new ZKLContract(zklTokenAddr);
let au = AccountUpdate.create(this.address, zklTokenSC.tokenId);
let balance: UInt64 = au.account.balance.getAndRequireEquals();
zklTokenSC.sendFromTo(this.address, claimer, balance);
}
/**
* Asserts that the verification key of the smart contract is the expected one.
* This is done by calling an empty method on the smart contract.
* Method call = Account Update with proof of authorization.
*/
@method async assertVerificationKeyIsCorrect() {
// must remain empty. no need for assertions or state changes
}
}
Here you see, using this.account, you are able to access to the account settings. In here, editState property of a Permission is set to be need of proof or a signature, athers are set to be default values.
import { SecondaryZkApp } from './SecondaryZkApp.js';
import {
Field,
SmartContract,
state,
State,
method,
PublicKey,
Permissions,
TransactionVersion,
} from 'o1js';
export class ProofsOnlyZkApp extends SmartContract {
@state(Field) num = State<Field>();
@state(Field) calls = State<Field>();
async deploy() {
await super.deploy();
this.account.permissions.set({
...Permissions.default(),
setDelegate: Permissions.proof(),
setPermissions: Permissions.proof(),
setVerificationKey: {
auth: Permissions.proof(),
txnVersion: TransactionVersion.current(),
},
setZkappUri: Permissions.proof(),
setTokenSymbol: Permissions.proof(),
incrementNonce: Permissions.proof(),
setVotingFor: Permissions.proof(),
setTiming: Permissions.proof(),
});
}
@method async init() {
this.account.provedState.getAndRequireEquals();
this.account.provedState.get().assertFalse();
super.init();
this.num.set(Field(1));
this.calls.set(Field(0));
}
@method async add(incrementBy: Field) {
this.account.provedState.getAndRequireEquals();
this.account.provedState.get().assertTrue();
const num = this.num.getAndRequireEquals();
this.num.set(num.add(incrementBy));
await this.incrementCalls();
}
@method async incrementCalls() {
this.account.provedState.getAndRequireEquals();
this.account.provedState.get().assertTrue();
const calls = this.calls.getAndRequireEquals();
this.calls.set(calls.add(Field(1)));
}
@method async callSecondary(secondaryAddr: PublicKey) {
this.account.provedState.getAndRequireEquals();
this.account.provedState.get().assertTrue();
const secondaryContract = new SecondaryZkApp(secondaryAddr);
const num = this.num.getAndRequireEquals();
await secondaryContract.add(num);
// NOTE this gets the state at the start of the transaction
this.num.set(secondaryContract.num.get());
await this.incrementCalls();
}
}
First of all, we recommend you to check the examples folder. There are pretty educational content in there, where you can test the code on your local machine.
As you see in the code above, The permissions are set to proof only, which means that only parties who provide account update accompanied by valid proofs.
Additionally, there are advanced features of AccountUpdate you can see in . However, some applications of token contract and other classes are currently on audit process (like Token Standard). It will be updated pretty soon, so that you will be able to issue new tokens on chain and make your flexible actions with AccountUpdate!