UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

136 lines (135 loc) 4.82 kB
import { FlexibleProvablePure } from '../../provable/types/struct.js'; import { SmartContract } from './zkapp.js'; import { Field } from '../../provable/wrapped.js'; import { ProvablePure, ProvableTypePure } from '../../provable/types/provable-intf.js'; import { Bool } from '../../provable/wrapped.js'; export { State, state, declareState }; export { assertStatePrecondition, cleanStatePrecondition, getLayout, InternalStateType }; /** * Gettable and settable state that can be checked for equality. */ type State<A> = { /** * Get the current on-chain state. * * Caution: If you use this method alone inside a smart contract, it does not prove that your contract uses the current on-chain state. * To successfully prove that your contract uses the current on-chain state, you must add an additional `.requireEquals()` statement or use `.getAndRequireEquals()`: * * ```ts * let x = this.x.get(); * this.x.requireEquals(x); * ``` * * OR * * ```ts * let x = this.x.getAndRequireEquals(); * ``` */ get(): A; /** * Get the current on-chain state and prove it really has to equal the on-chain state, * by adding a precondition which the verifying Mina node will check before accepting this transaction. */ getAndRequireEquals(): A; /** * Set the on-chain state to a new value. */ set(a: A): void; /** * Asynchronously fetch the on-chain state. This is intended for getting the state outside a smart contract. */ fetch(): Promise<A | undefined>; /** * Prove that the on-chain state has to equal the given state, * by adding a precondition which the verifying Mina node will check before accepting this transaction. */ requireEquals(a: A): void; /** * Require that the on-chain state has to equal the given state if the provided condition is true. * * If the condition is false, this is a no-op. * If the condition is true, this adds a precondition that the verifying Mina node will check before accepting this transaction. */ requireEqualsIf(condition: Bool, a: A): void; /** * **DANGER ZONE**: Override the error message that warns you when you use `.get()` without adding a precondition. */ requireNothing(): void; /** * Get the state from the raw list of field elements on a zkApp account, for example: * * ```ts * let myContract = new MyContract(address); * let account = Mina.getAccount(address); * * let x = myContract.x.fromAppState(account.zkapp!.appState); * ``` */ fromAppState(appState: Field[]): A; }; declare function State<A>(defaultValue?: A): State<A>; /** * A decorator to use within a zkapp to indicate what will be stored on-chain. * For example, if you want to store a field element `some_state` in a zkapp, * you can use the following in the declaration of your zkapp: * * ``` * @state(Field) some_state = State<Field>(); * ``` * */ declare function state<A>(type: ProvableTypePure<A> | FlexibleProvablePure<A>): (target: SmartContract & { constructor: any; }, key: string, _descriptor?: PropertyDescriptor) => void; /** * `declareState` can be used in place of the `@state` decorator to declare on-chain state on a SmartContract. * It should be placed _after_ the class declaration. * Here is an example of declaring a state property `x` of type `Field`. * ```ts * class MyContract extends SmartContract { * x = State<Field>(); * // ... * } * declareState(MyContract, { x: Field }); * ``` * * If you're using pure JS, it's _not_ possible to use the built-in class field syntax, * i.e. the following will _not_ work: * * ```js * // THIS IS WRONG IN JS! * class MyContract extends SmartContract { * x = State(); * } * declareState(MyContract, { x: Field }); * ``` * * Instead, add a constructor where you assign the property: * ```js * class MyContract extends SmartContract { * constructor(x) { * super(); * this.x = State(); * } * } * declareState(MyContract, { x: Field }); * ``` */ declare function declareState<T extends typeof SmartContract>(SmartContract: T, states: Record<string, FlexibleProvablePure<any>>): void; type StateAttachedContract<A> = { key: string; stateType: ProvablePure<A>; instance: SmartContract; class: typeof SmartContract; wasRead: boolean; wasConstrained: boolean; cachedVariable?: A; }; type InternalStateType<A> = State<A> & { _contract?: StateAttachedContract<A>; defaultValue?: A; }; declare function getLayout(scClass: typeof SmartContract): Map<any, any>; declare function assertStatePrecondition(sc: SmartContract): void; declare function cleanStatePrecondition(sc: SmartContract): void;