Skip to main content

TokenContract

o1js / Modules / TokenContract

Class: TokenContract

Base token contract which

  • implements the Approvable API, with the approveBase() method left to be defined by subclasses
  • implements the Transferable API as a wrapper around the Approvable API

Hierarchy

Table of contents

Constructors

Properties

Accessors

Methods

Constructors

constructor

new TokenContract(address, tokenId?)

Parameters

NameType
addressPublicKey
tokenId?Field

Inherited from

SmartContract.constructor

Defined in

lib/zkapp.ts:574

Properties

#_senderState

Private #_senderState: Object

Type declaration

NameType
senderPublicKey
transactionIdnumber

Inherited from

SmartContract.#_senderState

Defined in

lib/zkapp.ts:822


#executionState

Private #executionState: undefined | ExecutionState

Inherited from

SmartContract.#executionState

Defined in

lib/zkapp.ts:541


address

address: PublicKey

Inherited from

SmartContract.address

Defined in

lib/zkapp.ts:538


events

events: Object = {}

A list of event types that can be emitted using this.emitEvent()`.

Index signature

[key: string]: FlexibleProvablePure\<any>

Inherited from

SmartContract.events

Defined in

lib/zkapp.ts:928


tokenId

tokenId: Field

Inherited from

SmartContract.tokenId

Defined in

lib/zkapp.ts:539


_maxProofsVerified

Static Optional _maxProofsVerified: 0 | 2 | 1

Inherited from

SmartContract._maxProofsVerified

Defined in

lib/zkapp.ts:559


_methodMetadata

Static Optional _methodMetadata: Record\<string, { actions: number ; digest: string ; gates: Gate[] ; hasReturn: boolean ; rows: number }>

Inherited from

SmartContract._methodMetadata

Defined in

lib/zkapp.ts:548


_methods

Static Optional _methods: MethodInterface[]

Inherited from

SmartContract._methods

Defined in

lib/zkapp.ts:547


_provers

Static Optional _provers: Prover[]

Inherited from

SmartContract._provers

Defined in

lib/zkapp.ts:558


_verificationKey

Static Optional _verificationKey: Object

Type declaration

NameType
datastring
hashField

Inherited from

SmartContract._verificationKey

Defined in

lib/zkapp.ts:560

Accessors

account

get account(): Account

Current account of the SmartContract.

Returns

Account

Inherited from

SmartContract.account

Defined in

lib/zkapp.ts:853


balance

get balance(): Object

Balance of this SmartContract.

Returns

Object

NameType
addInPlace(x: string | number | bigint | UInt64 | UInt32 | Int64) => void
subInPlace(x: string | number | bigint | UInt64 | UInt32 | Int64) => void

Inherited from

SmartContract.balance

Defined in

lib/zkapp.ts:922


currentSlot

get currentSlot(): CurrentSlot

Current global slot on the network. This is the slot at which this transaction is included in a block. Since we cannot know this value at the time of transaction construction, this only has the assertBetween() method but no get() (impossible to implement) or assertEquals() (confusing, because the developer can't know the exact slot at which this will be included either)

Returns

CurrentSlot

Inherited from

SmartContract.currentSlot

Defined in

lib/zkapp.ts:867


internal

get internal(): Object

Helper methods to use from within a token contract.

Returns

Object

NameType
burn(__namedParameters: { address: PublicKey | AccountUpdate | SmartContract ; amount: number | bigint | UInt64 }) => AccountUpdate
mint(__namedParameters: { address: PublicKey | AccountUpdate | SmartContract ; amount: number | bigint | UInt64 }) => AccountUpdate
send(__namedParameters: { amount: number | bigint | UInt64 ; from: PublicKey | AccountUpdate | SmartContract ; to: PublicKey | AccountUpdate | SmartContract }) => AccountUpdate

Defined in

lib/mina/token/token-contract.ts:76


network

get network(): Network

Current network state of the SmartContract.

Returns

Network

Inherited from

SmartContract.network

Defined in

lib/zkapp.ts:859


self

get self(): AccountUpdate

Returns the current AccountUpdate associated to this SmartContract.

Returns

AccountUpdate

Inherited from

SmartContract.self

Defined in

lib/zkapp.ts:779


sender

get sender(): PublicKey

The public key of the current transaction's sender account.

Throws an error if not inside a transaction, or the sender wasn't passed in.

Warning: The fact that this public key equals the current sender is not part of the proof. A malicious prover could use any other public key without affecting the validity of the proof.

Returns

PublicKey

Inherited from

SmartContract.sender

Defined in

lib/zkapp.ts:832


token

get token(): Object

Returns

Object

NameType
idField
parentTokenIdField
tokenOwnerPublicKey
burn(__namedParameters: { address: PublicKey | AccountUpdate | SmartContract ; amount: number | bigint | UInt64 }) => AccountUpdate
mint(__namedParameters: { address: PublicKey | AccountUpdate | SmartContract ; amount: number | bigint | UInt64 }) => AccountUpdate
send(__namedParameters: { amount: number | bigint | UInt64 ; from: PublicKey | AccountUpdate | SmartContract ; to: PublicKey | AccountUpdate | SmartContract }) => AccountUpdate

Deprecated

SmartContract.token will be removed, and token methods will only be available on TokenContract.internal. Instead of SmartContract.token.id, use TokenContract.deriveTokenId().

For security reasons, it is recommended to use TokenContract as the base contract for all tokens.

Inherited from

SmartContract.token

Defined in

lib/zkapp.ts:877


tokenSymbol

get tokenSymbol(): Object

Returns

Object

NameType
set(tokenSymbol: string) => void

Deprecated

use this.account.tokenSymbol

Inherited from

SmartContract.tokenSymbol

Defined in

lib/zkapp.ts:916

Methods

approve

approve(update): void

Approve an account update or tree / forest of updates. Doing this means you include the account update in the zkApp's public input, which allows you to read and use its content in a proof, make assertions about it, and modify it.

`@method` myApprovingMethod(update: AccountUpdate) {
this.approve(update);

// read balance on the account (for example)
let balance = update.account.balance.getAndRequireEquals();
}

Under the hood, "approving" just means that the account update is made a child of the zkApp in the tree of account updates that forms the transaction. Similarly, if you pass in an AccountUpdateTree, the entire tree will become a subtree of the zkApp's account update.

Passing in a forest is a bit different, because it means you set the entire children of the zkApp's account update at once. approve() will fail if the zkApp's account update already has children, to prevent you from accidentally excluding important information from the public input.

Parameters

NameType
updateAccountUpdate | AccountUpdateTree | AccountUpdateForest

Returns

void

Inherited from

SmartContract.approve

Defined in

lib/zkapp.ts:902


approveAccountUpdate

approveAccountUpdate(accountUpdate): void

Approve a single account update (with arbitrarily many children).

Parameters

NameType
accountUpdateAccountUpdate | AccountUpdateTree

Returns

void

Defined in

lib/mina/token/token-contract.ts:137


approveAccountUpdates

approveAccountUpdates(accountUpdates): void

Approve a list of account updates (with arbitrarily many children).

Parameters

NameType
accountUpdates(AccountUpdate | AccountUpdateTree)[]

Returns

void

Defined in

lib/mina/token/token-contract.ts:145


approveBase

Abstract approveBase(forest): void

Parameters

NameType
forestAccountUpdateForest

Returns

void

Defined in

lib/mina/token/token-contract.ts:83


checkZeroBalanceChange

checkZeroBalanceChange(updates): void

Use forEachUpdate() to prove that the total balance change of child account updates is zero.

This is provided out of the box as it is both a good example, and probably the most common implementation, of approveBase().

Parameters

NameType
updatesAccountUpdateForest

Returns

void

Defined in

lib/mina/token/token-contract.ts:121


deploy

deploy(args?): void

Deploys a TokenContract.

In addition to base smart contract deployment, this adds two steps:

  • set the access permission to proofOrSignature(), to prevent against unauthorized token operations
    • not doing this would imply that anyone can bypass token contract authorization and simply mint themselves tokens
  • require the zkapp account to be new, using the isNew precondition. this guarantees that the access permission is set from the very start of the existence of this account. creating the zkapp account before deployment would otherwise be a security vulnerability that is too easy to introduce.

Note that because of the isNew precondition, the zkapp account must not be created prior to calling deploy().

If the contract needs to be re-deployed, you can switch off this behaviour by overriding the isNew precondition:

deploy() {
super.deploy();
// DON'T DO THIS ON THE INITIAL DEPLOYMENT!
this.account.isNew.requireNothing();
}

Parameters

NameType
args?DeployArgs

Returns

void

Overrides

SmartContract.deploy

Defined in

lib/mina/token/token-contract.ts:51


deriveTokenId

deriveTokenId(): Field

Returns the tokenId of the token managed by this contract.

Returns

Field

Defined in

lib/mina/token/token-contract.ts:69


emitEvent

emitEvent\<K>(type, event): void

Emits an event. Events will be emitted as a part of the transaction and can be collected by archive nodes.

Type parameters

NameType
Kextends string | number

Parameters

NameType
typeK
eventany

Returns

void

Inherited from

SmartContract.emitEvent

Defined in

lib/zkapp.ts:934


fetchEvents

fetchEvents(start?, end?): Promise\<{ blockHash: string ; blockHeight: UInt32 ; chainStatus: string ; event: { data: ProvablePure\<any> ; transactionInfo: { transactionHash: string ; transactionMemo: string ; transactionStatus: string } } ; globalSlot: UInt32 ; parentBlockHash: string ; type: string }[]>

Asynchronously fetches events emitted by this SmartContract and returns an array of events with their corresponding types.

Parameters

NameTypeDescription
start?UInt32The start height of the events to fetch.
end?UInt32The end height of the events to fetch. If not provided, fetches events up to the latest height.

Returns

Promise\<{ blockHash: string ; blockHeight: UInt32 ; chainStatus: string ; event: { data: ProvablePure\<any> ; transactionInfo: { transactionHash: string ; transactionMemo: string ; transactionStatus: string } } ; globalSlot: UInt32 ; parentBlockHash: string ; type: string }[]>

A promise that resolves to an array of objects, each containing the event type and event data for the specified range.

Async

Throws

If there is an error fetching events from the Mina network.

Example

const startHeight = UInt32.from(1000);
const endHeight = UInt32.from(2000);
const events = await myZkapp.fetchEvents(startHeight, endHeight);
console.log(events);

Inherited from

SmartContract.fetchEvents

Defined in

lib/zkapp.ts:980


forEachUpdate

forEachUpdate(updates, callback): void

Iterate through the account updates in updates and apply callback to each.

This method is provable and is suitable as a base for implementing approveUpdates().

Parameters

NameType
updatesAccountUpdateForest
callback(update: AccountUpdate, usesToken: Bool) => void

Returns

void

Defined in

lib/mina/token/token-contract.ts:90


init

init(): void

SmartContract.init() will be called only when a SmartContract will be first deployed, not for redeployment. This method can be overridden as follows

class MyContract extends SmartContract {
init() {
super.init();
this.account.permissions.set(...);
this.x.set(Field(1));
}
}

Returns

void

Inherited from

SmartContract.init

Defined in

lib/zkapp.ts:734


newSelf

newSelf(methodName?): AccountUpdate

Same as SmartContract.self but explicitly creates a new AccountUpdate.

Parameters

NameType
methodName?string

Returns

AccountUpdate

Inherited from

SmartContract.newSelf

Defined in

lib/zkapp.ts:814


requireSignature

requireSignature(): void

Use this command if the account update created by this SmartContract should be signed by the account owner, instead of authorized with a proof.

Note that the smart contract's Permissions determine which updates have to be (can be) authorized by a signature.

If you only want to avoid creating proofs for quicker testing, we advise you to use LocalBlockchain({ proofsEnabled: false }) instead of requireSignature(). Setting proofsEnabled to false allows you to test your transactions with the same authorization flow as in production, with the only difference being that quick mock proofs are filled in instead of real proofs.

Returns

void

Inherited from

SmartContract.requireSignature

Defined in

lib/zkapp.ts:755


send

send(args): AccountUpdate

Parameters

NameType
argsObject
args.amountnumber | bigint | UInt64
args.toPublicKey | AccountUpdate | SmartContract

Returns

AccountUpdate

Inherited from

SmartContract.send

Defined in

lib/zkapp.ts:906


setPermissions

setPermissions(permissions): void

Parameters

NameType
permissionsPermissions

Returns

void

Deprecated

use this.account.permissions.set()

Inherited from

SmartContract.setPermissions

Defined in

lib/zkapp.ts:1161


setValue

setValue\<T>(maybeValue, value): void

Type parameters

Name
T

Parameters

NameType
maybeValueSetOrKeep\<T>
valueT

Returns

void

Deprecated

use this.account.<field>.set()

Inherited from

SmartContract.setValue

Defined in

lib/zkapp.ts:1154


sign

sign(zkappKey?): void

Parameters

NameType
zkappKey?PrivateKey

Returns

void

Deprecated

this.sign() is deprecated in favor of this.requireSignature()

Inherited from

SmartContract.sign

Defined in

lib/zkapp.ts:761


skipAuthorization

skipAuthorization(): void

Use this command if the account update created by this SmartContract should have no authorization on it, instead of being authorized with a proof.

WARNING: This is a method that should rarely be useful. If you want to disable proofs for quicker testing, take a look at LocalBlockchain({ proofsEnabled: false }), which causes mock proofs to be created and doesn't require changing the authorization flow.

Returns

void

Inherited from

SmartContract.skipAuthorization

Defined in

lib/zkapp.ts:772


transfer

transfer(from, to, amount): void

Transfer amount of tokens from from to to.

Parameters

NameType
fromPublicKey | AccountUpdate
toPublicKey | AccountUpdate
amountnumber | bigint | UInt64

Returns

void

Defined in

lib/mina/token/token-contract.ts:155


Proof

Static Proof(): typeof __class

Returns a Proof type that belongs to this SmartContract.

Returns

typeof __class

Inherited from

SmartContract.Proof

Defined in

lib/zkapp.ts:565


analyzeMethods

Static analyzeMethods(«destructured»?): Record\<string, { actions: number ; digest: string ; gates: Gate[] ; hasReturn: boolean ; rows: number }>

This function is run internally before compiling a smart contract, to collect metadata about what each of your smart contract methods does.

For external usage, this function can be handy because calling it involves running all methods in the same "mode" as compile() does, so it serves as a quick-to-run check for whether your contract can be compiled without errors, which can greatly speed up iterating.

analyzeMethods() will also return the number of rows of each of your method circuits (i.e., the number of constraints in the underlying proof system), which is a good indicator for circuit size and the time it will take to create proofs. To inspect the created circuit in detail, you can look at the returned gates.

Note: If this function was already called before, it will short-circuit and just return the metadata collected the first time.

Parameters

NameType
«destructured»Object
› printSummaryundefined | boolean

Returns

Record\<string, { actions: number ; digest: string ; gates: Gate[] ; hasReturn: boolean ; rows: number }>

an object, keyed by method name, each entry containing:

  • rows the size of the constraint system created by this method
  • digest a digest of the method circuit
  • hasReturn a boolean indicating whether the method returns a value
  • actions the number of actions the method dispatches
  • gates the constraint system, represented as an array of gates

Inherited from

SmartContract.analyzeMethods

Defined in

lib/zkapp.ts:1100


compile

Static compile(«destructured»?): Promise\<{ provers: Prover[] ; verificationKey: { data: string ; hash: Field } ; verify: (statement: Statement\<FieldConst>, proof: unknown) => Promise\<boolean> }>

Compile your smart contract.

This generates both the prover functions, needed to create proofs for running @methods, and the verification key, needed to deploy your zkApp.

Although provers and verification key are returned by this method, they are also cached internally and used when needed, so you don't actually have to use the return value of this function.

Under the hood, "compiling" means calling into the lower-level Pickles and Kimchi libraries to create multiple prover & verifier indices (one for each smart contract method as part of a "step circuit" and one for the "wrap circuit" which recursively wraps it so that proofs end up in the original finite field). These are fairly expensive operations, so expect compiling to take at least 20 seconds, up to several minutes if your circuit is large or your hardware is not optimal for these operations.

Parameters

NameType
«destructured»Object
› cacheundefined | Cache
› forceRecompileundefined | boolean

Returns

Promise\<{ provers: Prover[] ; verificationKey: { data: string ; hash: Field } ; verify: (statement: Statement\<FieldConst>, proof: unknown) => Promise\<boolean> }>

Inherited from

SmartContract.compile

Defined in

lib/zkapp.ts:602


digest

Static digest(): string

Computes a hash of your smart contract, which will reliably change whenever one of your method circuits changes. This digest is quick to compute. it is designed to help with deciding whether a contract should be re-compiled or a cached verification key can be used.

Returns

string

the digest, as a hex string

Inherited from

SmartContract.digest

Defined in

lib/zkapp.ts:643


runOutsideCircuit

Static runOutsideCircuit(run): void

Parameters

NameType
run() => void

Returns

void

Inherited from

SmartContract.runOutsideCircuit

Defined in

lib/zkapp.ts:1074