--- url: /glossary --- # Glossary [A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) G [H](#h) [I](#i) J [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) [P](#p) Q [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) W X Y [Z](#z) Are you looking for a zero knowledge, o1js, zkApp, or Mina term that isn't here yet? To let us know, please [create an issue](https://github.com/o1-labs/docs2/issues) or click **EDIT THIS PAGE** to submit a PR. ## A ### account Mina uses accounts to track each public key's state. This is distinct from Bitcoin's UTXO model of maintaining ledger state. ### archive node A Mina node that stores the historical chain data to a persistent data source so it can later be retrieved. A zkApp can retrieve events and actions from one or more Mina [archive nodes](/node-operators/archive-node/getting-started). ## B ### Base58 A group of encoding/decoding schemes used to switch data between binary format (hexadecimal) and alphanumeric text format (ASCII). The Base58 alphabet includes numbers (1 to 9) and English letters, except O (uppercase o), I (uppercase i), and l (lowercase L). These letters are omitted to avoid confusion. ### Base64 A binary-to-text encoding scheme that represents binary data in a human-readable ASCII string format string. For example, the zero knowledge proof is a Base64 string inside the `authorization` field of a transaction. ### best tip The blockchain's latest block with the highest [chain strength](#chain-strength) known to the mina daemon. ### bitwise operations Generally available in most programming languages, including TypeScript, [bitwise operations](/zkapps/o1js/bitwise-operations) manipulate individual bits within a binary representation of a number. o1js provides versions of bitwise operations that operate on Field elements and result in the necessary circuit constraints to generate a zero knowledge proof of the computation. ### block A set of transactions and consensus information that extend the state of the network. A block in Mina includes a proof that the current state of the network is fully valid. See also [extensional blocks](/glossary#extensional-blocks) and [precomputed blocks](/glossary#precomputed-blocks). See [What's in a Block?](/mina-protocol/whats-in-a-block) ### blockchain The data structure that is used in a cryptocurrency to maintain a shared state of all accounts in the network. ### block confirmations The number of blocks added after the reference block. As the number of confirmations increases, the likelihood of a [reorganization](/glossary#reorganization) decreases, thereby increasing the likelihood of all transactions in the reference block being confirmed. ### block explorer A web-based tool to extract, visualize, and review blockchain network metrics, including transaction histories, wallet balances, and details about individual blocks and transactions. Block explorers for Mina include: - https://minascan.io - https://minataur.net ### block fill rate The proportion of [slots](#slot) that should contain a block. Some slots are intentionally empty to ensure the network can [catch up](/glossary#catchup) in case of delay of messages. ### block header The portion of a block that contains information about the block itself (block metadata), typically includes a timestamp, a hash representation of the block data, the hash of the previous block's header, and a cryptographic nonce (if needed). ### block producer A node that participates in a process to determine what blocks it is allowed to produce and then produces blocks containing transactions that can be broadcast to the network. People who run [block producer](/mina-protocol/block-producers) nodes are also called block producers. ### bootstrap Part of the [syncing](#syncing) process of a node, bootstrapping gets the current [root](#root-of-transition-frontier) of the [transition frontier](#transition-frontier) from peers. Additional [transitions](#transition) obtained during the [catchup](#catchup) process are applied from this initial root state. ### breadcrumb A node in the [transition frontier](#transition-frontier) that contains the external transition, staged ledger, and pending coinbases and is generated by applying the transition to the prior state. ## C ### catch up {#catchup} The final stage of the [syncing](#syncing) process where the node attempts to catch up to the current [best tip](#best-tip) by determining and then downloading all [transitions](#transition) between the transition frontier [root](#root-of-transition-frontier) and the current best tip. First, a node requests the missing transition hashes and a transaction chain proof. This proof proves the path provided is valid, for example, that the provided transition hashes lead from the root to the best tip. After the node has all transition hashes, it requests the full external transition for each transition hash from peers. With each external transition, the node builds up its transition frontier by applying each to the prior state to construct a [breadcrumb](#breadcrumb). When the catch up stage is complete, the node's local best tip is the same as the network's best tip, and breadcrumbs have been constructed for all transitions from the transition frontier root (best tip - k) to the current tip, and each has been validated. At this point, the node is [synced](#syncing). A catch up can be triggered at any time if the node sees a disjoint transition in the same path that indicates there are missing transitions. ### chain strength Full history is not available in Mina, so a newly connected node to the network cannot sync from genesis by applying all prior transitions. To allow a node to determine the strongest chain, a minimum chain density is stored for a sliding window of time. As a result, honest nodes can choose the blockchain with the higher minimum density or chain strength. ### cold wallet A wallet is "cold" if the private key is not, and never has been, available on the internet. Cold storage is preferred for wallets associated with meaningful stake as it is harder to hack into cold wallet systems if they never have been on the internet. This could be as easy as generating a key pair on a laptop with the internet turned off or using a hardware wallet, like a [Ledger](https://shop.ledger.com/) device. ### compressing Generating a SNARK for a computation output can be thought of as compressing that output, as the proofs are fixed size. For example, Mina maintains a succinct blockchain by compressing all the historical data in a blockchain into a zk-SNARK. However, this is computationally different from lossy compression. The term _compress_ is used to more figuratively describe the process of reducing the size of required data. ### consensus A process through which all the peers of a blockchain network reach a common agreement about the present state of the distributed ledger. A consensus algorithm or set of rules that Mina nodes all agree upon when deciding to update the state of the network. Rules can include what data a new block can contain and how nodes are selected and rewarded for adding a block. Mina implements the [Ouroboros Samisika](/glossary#ouroboros-samisika) consensus mechanism. ### consensus node A participant in the Mina network that performs the consensus function, for example, a [block producer](#block-producer). ### cryptocurrency A digital asset or currency that uses cryptographic primitives to secure financial transactions and to verify ownership by using public/private key pairs. ## D ### daemon The Mina daemon is a background process that implements the Mina protocol and runs on a node locally so a local client or wallet can talk to the Mina network. For example, when a CLI is used to issue a command to send a transaction, this request is made to the Mina daemon, which then broadcasts it to the peer-to-peer network. The daemon also listens for events like new blocks and relays this to the client by using a publish-subcribe model. ### DAO A decentralized autonomous organization (DAO) operates based on rules that are encoded on a blockchain and executed through smart contracts. DAOs are an organizational structure built with blockchain technology. ### Dapp A decentralized application (Dapp) runs on a blockchain or decentralized network and offers benefits such as transparency, security, and censorship resistance. In the Mina ecosystem, Dapps are known as [zkApps](#zkapps). ### delegating Because staking MINA requires nodes to be online, some nodes delegate their MINA to another node that runs a staking service. This process is called delegating a stake. The service provider or staking pool operator can charge a fee that is deducted any time the delegator gets selected to be a block producer. ### deploy alias Created with the zkApp CLI, a [deploy alias](/zkapps/tutorials/deploying-to-a-network#deploy-alias) in your project `config.json` file contains the details to manage deployments. ### Devnet Dedicated for developers building on top of the Mina protocol, Devnet is designed for testing and experimentation so you can test tooling and integrations before going live on [Mainnet](#mainnet). See [Connect to Mainnet or Devnet](/node-operators/validator-node/connecting-to-the-network). ### distributed ledger technology (DLT) A digital system for recording the transaction of assets in which the transactions and their details are recorded in multiple places at the same time. In contrast to traditional databases, distributed ledgers have no central data store or administration functionality. ## E ## ECDSA Elliptic Curve Digital Signature Algorithm ([ECDSA](/zkapps/o1js/ecdsa)) a cryptographic algorithm used to sign and verify messages. It is used in many blockchains, including Ethereum, to sign transactions. ## elliptic curves Equations with a specific template, including: _y^2 = x^3 + ax^ + b_: [secp256k1](/glossary#secp256k1). ### elliptic-curve cryptography (ECC) An approach to public key cryptography based on the algebraic structure of elliptic curves over finite fields. ECC is the basis of how Ethereum and other cryptocurrencies use private keys and digital signatures. ### epoch A unit of time equal to 7140 slots at Mainnet. An epoch is divided into [slots](#slot) of 3 minutes each. ### extensional blocks Blocks extracted from the `mina-archive` database contain only the information required to restore data to the archive node and are more lightweight than [precomputed blocks](/glossary#precomputed-blocks). ### external port The port that the Mina daemon uses to connect to other nodes on the network. When starting the daemon, set using `-external-port`. ### external transition Also referred to as a [block](#block), an external transition is generated externally, for example, by another block producer, and gossiped to a node. ## F ## fee payer account A developer account that is funded and can always pay fees immediately. When you configure a zkApp, you can choose to use a stored account or create a new fee payer account. ### field element The basic unit of data in zero knowledge proof programming. Each field element can store a number up to almost 256 bits in size. You can think of a field element as a uint256 in Solidity. For the cryptography inclined, the exact max value that a field can store is 28,948,022,309,329,048,855,892,746,252,171,976,963,363,056,481,941,560,715,954,676,764,349,967,630,336. ### finality A consensus constant `k` is the point at which chain [reorganizations](#reorganization) are no longer possible. After a block has `k` [block confirmations](#block-confirmations) as defined by the consensus constants, it is considered final. ## foreign field A finite field different from the native field of the proof system. [Foreign Field Arithmetic](/zkapps/o1js/ecdsa) lets you perform algorithms that connect your zkApp with the outside world of cryptography. ### full node A Mina node that is able to verify the state of the network trustlessly. In Mina, every node is a full node since all nodes can receive and verify zk-SNARKs. # G ## gadgets Small, reusable, low-level building blocks that simplify the process of creating new cryptographic primitives. Most [gadgets](/zkapps/o1js/gadgets) build upon custom gates and act as low-level accelerators in the proof system. ## H ### hash A mathematical cryptographic function that converts an input of arbitrary length into an encrypted output of a fixed length. Hashing provides security through encryption and is an efficient store of data because the hash is of a fixed size. ### hot wallet A wallet is "hot" if the private key is available on a machine that is connected to the internet. To mitigate risk in the case of hackers breaking into their systems, careful block producers avoid having hot wallets with substantial stake on them. ## I ### internal transition A [transition](#transition) that is produced locally, for example, by a block producer. The generated transition is applied locally and added to the [transition frontier](#transition-frontier) before being broadcast to peers. ## K ## Keccak [Keccak (SHA-3)](/zkapps/o1js/keccak) is a flexible cryptographic hash function that provides more security than traditional SHA hash algorithms. ### key pair A combination of a [private key](#private-key) and [public key](#public-key). Key pairs can be generated by using a running daemon or using a dedicated keygen tool, see [Generating a Key Pair](/node-operators/validator-node/generating-a-keypair). In Mina, public keys start with `B62` and private keys start with `EK` for easy differentiability. ### Kimchi The proof system for Mina, Kimchi is the main machinery that generates the recursive proofs that keep the Mina blockchain small (about 22 KB). Kimchi is a zero knowledge proof system that's a variant of [PLONK](/glossary#plonk) and features a polynomial commitment scheme that supports verifiable computation using traditional Turing machine-based instruction sets. ## L ### layer 1 (L1) The fundamental, base-level chain in a network. An L1 blockchain provides the essential services to a network, like recording transactions on the public ledger and ensuring adequate security. Mina is a layer 1 blockchain. ### layer 2 (L2) An off-chain network, system, or technology built on top of a layer 1 blockchain that helps extend the capabilities of the underlying base layer network. ### ledger A cryptocurrency public record-keeping system. Mina has three types of ledgers: [staged ledger](/glossary#staged-ledger), [staking ledger](/glossary#staking-ledger), and [SNARKed ledger](/glossary#snarked-ledger). ### libp2p Mina uses this peer-to-peer networking library to provide things like message broadcast and file sharing. ### Lightnet A lightweight Mina network in a single Docker container. [Lightnet](zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet) is a resource-efficient solution with fast startup and syncing times that lets you test your zkApp locally on an accurate representation of Mina blockchain before you test with a live network. ### lightweight Mina Explorer Provided in Lightnet, a lightweight Mina Explorer lets you monitor transactions on your local network. See [Testing zkApps with Lightnet](zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet#lightweight-mina-explorer). ## M ### major upgrade Changes to the network that make the old chain incompatible with the new chain. A major upgrade to the Mina network requires all nodes or users to upgrade to the latest version of the protocol software. ### Mainnet The live version of the Mina blockchain network that is fully operational. On the Mina Mainnet public blockchain, real-world transactions are performed. See [Connect to the Mina Network](node-operators/validator-node/connecting-to-the-network). A Mainnet is different from a [Testnet](#testnet) and [Devnet](#devnet) which are used for development and testing. ### MINA The unit of the cryptocurrency that is exchanged by participating nodes on the Mina network. MINA is the exclusive currency of the [snarketplace](#snarketplace). ### Mina The underlying protocol and the network infrastructure that the system depends on. ### Mina CLI The primary way for users to interact with the Mina network. The [Mina CLI](/node-operators/reference/mina-cli-reference) command line tool provides standard client functionality to create accounts, send transactions, and participate in consensus and advanced client and daemon commands for power users. The Mina CLI is installed when you [install Mina](/node-operators/validator-node/installing-on-ubuntu-and-debian). ### Mina nodes Mina nodes fulfill different roles within the network, including [block producers](#block-producer) and [SNARK coordinators](#snark-coordinator). ## N ### node A machine running the Mina daemon. ### node operators People who run Mina nodes. Node operators participate in consensus to create new blocks and help compress data by generating zk-SNARKs. ### non-consensus node A [full node](#full-node) in the Mina protocol that does not participate in consensus but can still fully verify the zero knowledge proof to trustlessly validate the state of the chain. The size of Mina as 22 KB is in reference to non-consensus nodes. ### non-upgradeable If the verification key cannot be changed, a zkApp smart contract is considered non-upgradeable. You can make a smart contract upgradeable or not upgradeable using [permissions](/zkapps/writing-a-zkapp/feature-overview/permissions#upgradeability-of-smart-contracts). ### nonce An incrementing number attached to a transaction used to prevent a replay of a transaction on the network. Transactions are always included in blocks in the sequential order of the nonce. ## O ### o1js A TypeScript library for zk-SNARKs and zkApps. Use o1js to write zk smart contracts based on zero knowledge proofs for the Mina Protocol. ### off-chain A transfer of value or data, including transactions, that occurs outside a given blockchain network. These transfers do not need blockchain network confirmation, which speeds up the transaction process and reduces lag time. zkApps use an off-chain execution and mostly off-chain state model that allows for private computation and state that can be either private or public. ### off-chain state State stored anywhere other than the Mina blockchain. ### on-chain A transfer of value or data, including transactions, that exist on and have been verified to a blockchain network. All relevant information is timestamped and stored on the public ledger. On-chain transactions are recorded on the blockchain and need network confirmation before they are completed. ### on-chain state State that lives on the Mina blockchain. Each zkApp account provides eight fields of 32 bytes each of arbitrary storage for the on-chain state. ### oracle Specialized software or services that act as intermediaries between blockchain smart contracts and external data sources. [Oracles](/zkapps/tutorials/oracle) connect zkApp smart contracts with the outside world to get data on-chain. ### Ouroboros Samisika Mina builds on this provably secure proof of stake (PoS) protocol that combines the best features of each iteration of Ouroboros to deliver a PoS consensus mechanism that can resolve long-range forks without requiring history or risking centralization by relying on trusted third parties to provide fork information. ## P ## pasta curves A collective term for the Pallas and Vesta elliptic curves that are used by the Mina Protocol to generate proofs. See [Pasta Curves](https://o1-labs.github.io/proof-systems/specs/pasta.html?highlight=curves#pasta-curves) in the Mina book. ### peer-to-peer networks Networking systems that rely on peer nodes to distribute information amongst each other, are often distributed, and do not rely on any centralized resource broker. ### Pickles Mina's inductive zk-SNARK composition system. See [Pickles](https://o1-labs.github.io/proof-systems/specs/pickles.html). ### Pickles SNARK A proof system and associated toolkit that is the first deployed [SNARK](#snark) capable of recursive composition with no trusted setup. Pickles serves as the basis for developers to build private, scalable smart contracts on Mina. [Meet Pickles SNARK: Enabling Smart Contracts on Mina Protocol](https://medium.com/minaprotocol/meet-pickles-snark-enabling-smart-contract-on-coda-protocol-7ede3b54c250). ### PLONK Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge (PLONK) is a general-purpose zero knowledge proof scheme. ### polynomial commitment A commitment scheme that allows a committer to commit to a polynomial with a short string that can be used by a verifier to confirm claimed evaluations of the committed polynomial. ### Poseidon A family of [hash](#hash) functions that can efficiently run in a zk circuit. Poseidon operates over the native [Pallas base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) and uses parameters generated specifically for Mina, which makes Poseidon the most efficient hash function available in o1js. See [Poseidon: ZK-friendly Hashing](https://www.poseidon-hash.info/). Poseidon is a sponge construction based on the Hades permutation, with a state composed of field elements and a permutation based on field element operation (addition and exponentiation). ### precomputed blocks Precomputed blocks are [blocks](/glossary#block) logged by mina to disk, log file, or to cloud storage. ### preconditions Conditions that must be true for the account update to be applied. Corresponds to assertions in an o1js method. ### private key A component of public key cryptography, private keys are held privately, while public keys can be issued publicly. Only the holder of the public key's corresponding private key can attest to ownership of the public key. This allows for signing transactions to prove that you are the honest holder of any funds associated with any given public key. In Mina, private keys start with `EK` for easy differentiability from [public keys](#public-key). ### protocol state The state of the network that comprises the previous protocol state hash to link blocks together and a body that contains the genesis state hash, blockchain state, consensus state, and consensus constants. ### protocol state hash The hash of hashes of the previous state and [protocol state](#protocol-state) body. Acts as a unique identifier for a block. ### proof of liabilities (PoL) A cryptographic primitive to prove the size of funds a bank, or centralized exchange (CEX), owes to its customers in a decentralized manner and can be used for solvency audits with better privacy guarantees. ### proof of stake (PoS) The Mina consensus algorithm that allows nodes to agree on the state of the network. PoS allows nodes to [stake](/node-operators/validator-node/staking-and-snarking) MINA on the network to increase their chance of being selected as the next block producer. The winning validators are compensated with a percentage yield of the crypto they have staked as an incentive for engaging in this process. See [Proof-of-Work vs Proof-of-Stake](https://minaprotocol.com/blog/proof-of-work-vs-proof-of-stake). ### proof of work (PoW) The original consensus process used by Bitcoin, the first cryptocurrency. PoW achieves the decentralized consensus needed to add new blocks to a blockchain by using machines to compete against one another by guessing the answer to math problems that have no feasible faster solution. Computational power is a requirement for the PoW protocol success and assumes that those contributing more resources (energy, supercomputers, and infrastructure) to a problem are less likely to want to destroy the protocol. As an incentive to participate in this consensus process, miners are rewarded with tokens. ### prover function The function that generates a zero knowledge proof from the smart contract logic. ### public key A component of public key cryptography, public keys can be widely shared with the world and can be thought of as _addresses_ or identifiers for the person who holds the corresponding private key. In Mina, public keys start with `B62` for easy differentiability from [private keys](#private-key). ### publish-subscribe (pub-sub) A messaging pattern where message senders broadcast messages and notifies any listeners that have previously subscribed to that sender's messages. Mina utilizes pub-sub as a way to notify clients when a new block has been added to the chain. This event can be heard by all listeners, so each listener does not need to independently poll for new data. ## R ### recursion The layer 1 architecture of Mina Protocol is based on recursive composition, which means that each block in the blockchain is a tiny snapshot of the entire state of the network. This approach enables Mina to maintain a constant blockchain size of only 22KB regardless of the number of transactions processed. With recursion, you can realize composability between zero knowledge proofs to unlock many powerful technical abilities, such as creating high-throughput applications, creating proofs of large computations, and constructing multi-party proofs. ### reorganization When a competing fork of the blockchain increases in length relative to the main branch, the blockchain undergoes a reorganization to reflect the stronger fork as the main branch. After a reorganization, the transactions on the dropped branch are no longer guaranteed inclusion into the blockchain and must be added to new blocks on the longest branch. ### root of transition frontier The root of the [transition frontier](#transition-frontier) is the block `k` blocks from the [best tip](#best-tip). The root is obtained from peers during [bootstrap](#bootstrap). After a new best tip is seen, the root is moved, so only `k` blocks are persisted. The root is the point where the block has been [finalized](#finality) due to consensus. ### remote procedure call (RPC) An [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) is used to communicate between nodes on the network and to interact with the running [daemon](#daemon). ## S ### scan state A data structure that allows decoupling the production of transaction SNARKs from block producers to [SNARK workers](#snark-worker). See [Scan State](/mina-protocol/scan-state). ### secp256k1 The elliptic curve using this equation _y²=x³+7, a=0 b=7_, constructed in a special non-random way to allow for especially efficient computation. secp256k1 can have a key size of up to 256 bits. All points on this curve are valid public keys. ### seed nodes A Mina node that keeps a record of nodes in the network and enables nodes that are joining the network to connect to peer nodes. ### SHA-2 Secure Hash Algorithm 2 (SHA-2) is a family of two similar hash functions with different block sizes known as SHA-256 and SHA-512 that differ in word size. SHA-256 uses 32-bit words and SHA-512 uses 64-bit words. ### SHA-256 SHA-256, a part of the SHA-2 family, is a cryptographic hash function that generates a 256-bit (32-byte) hash output and is widely used for traditional Web2 applications and protocols as well as blockchain technology. ### SHA-3 Secure Hash Algorithm 3 (SHA-3) is the latest member of the Secure Hash Algorithm family of standards, released by NIST on August 5, 2015. [Keccak](#keccak) was standardized as SHA-3. ### signature Short for digital signature, a way to establish authenticity or ownership of digitally signed messages. ### simulated local blockchain The local testing blockchain you use in the first phase of testing. Using a simulated local blockchain speeds up development and tests the behavior of your smart contract locally. See [Testing zkApps Locally](zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally) and get step-by-steps guidance in [Tutorial 1: Hello World](/zkapps/tutorials/hello-world#simulated-local-blockchain). ### slot A unit of time in the Mina network. As of Mainnet launch, a slot in Mina is 3minutes long. An [epoch](#epoch) is divided into slots. Block producers can find eligible slots to produce blocks in to earn rewards. ### smart contract A tamper-proof program that runs on a blockchain network when certain predefined conditions are satisfied. On Mina, smart contracts (zkApps) are written with [o1js](#o1js). ### SNARK An acronym for succinct non-interactive argument of knowledge. See [zk-SNARK](/glossary#zk-snark). ### SNARK coordinator A role on a mina node in the Mina network. SNARK coordinators generate proofs of transactions by distributing work to a series of [SNARK workers](/node-operators/snark-workers). SNARK coordinators then submit that work to the network, and the proofs are sold to block producers. ### SNARK pool Referred to as the _snarketplace_, the pool that contains work completed by [SNARK workers](#snark-worker) for required work in the [scan state](#scan-state). The SNARK pool contains only the cheapest work offered by SNARK workers for each work bundle. Multiple SNARK workers compete for the same SNARK work, with only the lowest fee for each being included in the SNARK pool to be bought by block producers. ### SNARK worker External processes that connect to a Mina node on the network and create zk-SNARK proofs of transactions to compress the transactions so they can be folded into the tiny blockchain proof. The SNARK worker is incentivized with MINA as compensation to help compress transactions. See [What are SNARK Workers and the Snarketplace?](https://minaprotocol.com/blog/what-are-snark-workers-and-the-snarketplace). ### SNARKed ledger The ledger that contains only the transactions that have an associated proof. The SNARKed ledger is updated after a proof has been emitted from the [scan state](#scan-state). ### snarketplace Similar to a marketplace where people, or nodes, exchange services for a fee. It revolves around a fixed-size buffer like a queue or shelf of work to do. Block producers add work to this shelf in the form of transactions that need to be SNARKed, and then SNARK workers take the work off the shelf and create SNARKs out of them to process the transactions. Block producers purchase SNARK work for the lowest price from the snarketplace. Conversely, the SNARK workers want to maximize their profit while also being able to sell their SNARK work. These two roles act as the two sides of the marketplace and, over time, establish an equilibrium at a market price for SNARK work. ### soft fork An upgrade to the network that is backward-compatible. ### staged ledger The current account state that contains a pending accounts ledger and also a pending queue of un-SNARKed transactions known as the [scan state](#scan-state). ### staking Staking MINA allows nodes on the network to increase their chances of being selected as a block producer in accordance with the consensus mechanism. ### staking ledger The ledger used to determine block producers for a slot, as the probability of finding eligible slots to produce blocks in is proportional to the amount of stake. ### staking pool A pool of delegated funds that is run by a staking pool owner. To avoid the requirement of being online, other nodes can choose to delegate funds to a staking pool. ### state The current status or snapshot of all data stored within the blockchain. ### syncing To successfully produce a block that extends the Mina blockchain, a node requires the current state. To achieve this, a node initializes to connect to peers, [bootstrap](#bootstrap), and then performs a [catchup](#catchup). The syncing process builds the node's [transition frontier](#transition-frontier) by creating [breadcrumbs](#breadcrumb) for all transitions between the transition frontier's [root](#root-of-transition-frontier) to the current [best tip](#best-tip). When complete, the node is synced. ## T ### Testnet An instance of a blockchain used for testing and experimenting where MINA tokens have no real value. For example, for [zkApp Developer Tutorials](/zkapps/tutorials) and other development, you can request tMINA funds from the Testnet Faucet to fund your [fee payer account](#fee-payer-account). Mina's public Testnet is feature-complete and is called the `Devnet`. ### time-locked accounts An account with a non-vested amount of tokens that cannot be moved until a specific condition has been met, like a number of blocks that has been produced. See [Time-Locked Accounts](/zkapps/writing-a-zkapp/feature-overview/time-locked-accounts). ### tMINA MINA tokens that have no real-world value. You can request tMINA funds from the Testnet Faucet to fund your [fee payer account](#fee-payer-account) during development. ### tokens A digital asset that typically represents an asset, utility, or value in a particular blockchain ecosystem. The native cryptocurrency of the Mina blockchain is MINA. Tokens can serve a variety of purposes, including accessing platform features (utility tokens), representing ownership of assets (security tokens), or facilitating smart contracts and decentralized applications (Dapps). ### transaction pool An in-memory store of all the transactions that peer has heard on the network. Sometimes referred to as the mempool, each node has a local list of all pending transactions that have been gossiped to the node and validated. ### transition A transition in Mina is synonymous with a [block](#block). ### transition frontier A local data store that contains the last `k` blocks of the network. With a rose tree-type data structure, each node of the tree is a [breadcrumb](#breadcrumb) and can have multiple children (forks). ### TypeScript A superset of JavaScript that adds compile-time type safety. [o1js](https://www.npmjs.com/package/o1js) is a TypeScript library for zk-SNARKs and zkApps. See the official [TypeScript docs](https://www.typescriptlang.org). ## U ### user transaction A transaction that is issued by a user, like a payment or a delegation change. ## V ### verification key A piece of data that is generated by the smart contract build process. When a smart contract is deployed, a transaction that contains the verification key is sent to an address on the Mina blockchain. Sending a verification key to a zkApp account allows Mina to verify zero knowledge proofs that were generated by a smart contract's prover function. ### verifier function The function that verifies a zero knowledge proof using the [verification key](#verification-key). ### verifiable random function (VRF) A function that generates an output that can be cryptographically verified as random. Mina uses VRF to select a block producer for a slot, taking as input a random seed that is derived from the previous epoch's VRF outputs, a public key, and the current staking ledger. VRF is deterministic, so the same output is returned regardless of how often it is run. ## Z ### zero knowledge proof A proof by which one party (a prover) can prove to another party (a verifier) that they have knowledge of something, without giving away that specific knowledge. Mina uses zero knowledge proofs, specifically zk-SNARKs, to generate a proof attesting to the blockchain's validity and allows any node on the network to verify the validity. ### zkApps Zero knowledge apps ([zkApps](/zkapps/writing-a-zkapp)) are Mina Protocol's smart contracts powered by zero-knowledge proofs, specifically using zk-SNARKs. zkApps provide powerful and unique characteristics such as unlimited off-chain execution, privacy for private data inputs that are never seen by the blockchain, the ability to write smart contracts in TypeScript, and more. The easiest way to write zk programs is using [o1js](https://www.npmjs.com/package/o1js). ### zkApp CLI A command line tool that zkApp developers use to scaffold and deploy smart contracts. Install the [zkApp CLI](https://www.npmjs.com/package/zkapp-cli). ### zkApp account A zkApp account is an account on the Mina blockchain where a zkApp smart contract is deployed. Each zkApp account provides 8 fields of 32 bytes each of arbitrary storage. When a Mina address contains a verification key, it acts as a zkApp account. ### zkApp manager account A specific type of smart contract that manages a particular thing. For example, the zkApp manager account for a token controls all properties of token accounts and determines rules for token minting, burning, and transfer. ### zkBridge Technology that the Mina network uses to connect to other chains. ### zk-SNARK A zero knowledge proof. zk-SNARK is the acronym for zero knowledge succinct non-interactive argument of knowledge. Specific properties of interest in Mina's implementation of SNARKs are succinctness and non-interactivity, which allow for any node to quickly verify the state of the network. SNARK workers create [zk-SNARKs](https://minaprotocol.com/blog/what-are-zk-snarks) for each transaction. zk-SNARKs are used to create recursive zk-SNARKs that prove the correctness of a block, and in turn, these zk-SNARKs are used to create recursive zk-SNARKs that prove the correctness of the network. [A](#a) [B](#b) [C](#c) [D](#d) [E](#e) [F](#f) G [H](#h) [I](#i) J [K](#k) [L](#l) [M](#m) [N](#n) [O](#o) [P](#p) Q [R](#r) [S](#s) [T](#t) [U](#u) [V](#v) W X Y [Z](#z) --- url: /mina-protocol/block-producers --- # Block Producers The role of a block producer in Mina is to achieve [consensus](https://minaprotocol.com/blog/what-is-ouroboros-samasika) and provide security to the blockchain. The block producer is responsible for creating new blocks that include recent transactions broadcast on the network and a blockchain proof that proves the current state of the chain is valid. In Mina, anyone can become a block producer. There is an unbounded number of participants with the chance of producing a block proportional to the funds staked. Funds are not locked and are not subject to slashing. In return for staking funds and generating the required blockchain proofs, blocks that are produced and included in the canonical chain are rewarded in the form of a coinbase and transaction fees, less any fees paid to purchase required [transaction SNARK work](./snark-workers). To successfully produce a block, a block producer must have the current state of the blockchain. A block producer must have enough available compute to produce a blockchain SNARK within the slot time and be connected to peers to broadcast the generated block within an acceptable delay as defined by the network consensus parameters. ### Select a block producer The opportunity to produce a block for a slot is determined by a [verifiable random function](/glossary#verifiable-random-function-vrf) (VRF). Think of this function as a lottery. Each block producer independently runs this VRF for each slot and if the output is greater than a threshold proportional to the producer's stake, they have the chance to produce a block at the designated slot. This process is secret so that only the private key holder can determine the VRF output and only they know when they are to produce a block. This selection process aids security as it is impossible for an adversary to target a known block producer at a certain slot, e.g., by a denial of service or targeted attack. As a result, multiple producers can be selected for the same slot. When multiple producers produce a valid block for the same slot, a short-range fork is produced where the consensus rules select the longest chain. The stake distribution is determined from the SNARKed ledger at the last block of `current epoch-2`, so there is a delay for any recently acquired or [delegated stake](#stake-delegation). For example, if the current epoch is 10, the staking distribution is determined from the SNARKed ledger of the last block of the 8th epoch. To view the output of the VRF in the logs, look for `Checking VRF evaluations`. ### Generating a block When a block producer is selected to produce a block for a slot, they perform the following actions: - Choose the current best tip from their transition frontier (local store of blocks) on which to build the new block. - Select transactions and any SNARK work required from the transaction and SNARK pools. A block producer must purchase SNARK work at least in equal quantity to the transactions they add to a block. In addition to any user transactions, a block producer must also add a coinbase transaction as a reward for producing the block and any fee transfers to pay the SNARK workers. - Generate the proposed next state of the blockchain. - Create a diff of the staged ledger that includes the account ledger and scan state (a queue of transactions yet to have proofs). - Apply this diff to the existing staged ledger to produce the new state. - Create a blockchain proof to prove that the new state is valid. This SNARK additionally validates the prior protocol state proof. - Create a delta transition chain proof that proves the validity of the block if it is received within an acceptable network delay as defined by the network consensus parameters. - Apply this newly generated state locally and add it into the existing transition frontier. - Broadcast the block (call an external transition) to its peers. ### Stake delegation Delegated funds are not spendable and can be undelegated at any time by re-delegating the stake back to the original account. --- url: /mina-protocol --- # Introduction The Mina Protocol is a layer one protocol designed to deliver on the original promise of blockchain, true decentralization, scale and security. Mina offers an elegant solution: replacing the blockchain with an easily verifiable, consistent-sized cryptographic proof. Mina dramatically reduces the amount of data each user needs to download. Instead of verifying the entire chain from the beginning of time, participants fully verify the network and transactions using recursive zero knowledge proofs (or zk-SNARKs). Nodes can then store the small proof, as opposed to the entire chain. Because it’s a consistent size, Mina stays accessible even as it scales to many users and accumulates years of transaction data. ## The Mina Protocol There are three public Mina Protocol networks: 1. `mainnet` - the production network 2. `devnet` - the test network based on the same software versions as the Mainnet 3. `berkeley` - a development network where new features are trialed You check the identity of the network with this graphQL query: ``` query MyQuery { networkID } ``` This section describes how the Mina Protocol works. - [Proof Of Stake](/mina-protocol/proof-of-stake) - [What's in a Block](/mina-protocol/whats-in-a-block) - [Block Producers](/mina-protocol/block-producers) - [SNARK Workers](/mina-protocol/snark-workers) - [Scan State](/mina-protocol/scan-state) - [Time-Locked Accounts](/mina-protocol/time-locked-accounts) - [Sending a Payment](/mina-protocol/sending-a-payment) - [Lifecycle of a Payment](/mina-protocol/lifecycle-of-a-payment) ## Node Operators [Node Operators](../node-operators) describe how to run Mina nodes on a Mina network. Mina nodes fulfill different roles within the network. ## Node Developers [Node Developers](../node-developers) describes how developers can add to and improve Mina nodes. ## Exchange Integration [Exchange Operators](/node-operators/exchange-operators) describes how exchanges can integrate with the Mina blockchain using Rosetta API, archive nodes, and validator nodes. --- url: /mina-protocol/lifecycle-of-a-payment --- # Lifecycle of a Payment In Mina, payments pass through several steps before they are considered verified and complete. This document walks through what happens to a single payment in a simplified overview to help you understand how Mina payments work. It it not a comprehensive technical overview, but instead a simplified walkthrough for users. ## Gossip Protocol Mina uses a gossip protocol to ensure that messages can be reliably transmitted to all other members of the network in a timely manner. ## Payments A payment is a type of transaction, requesting to transfer value from one account to another account, and the associated fee the sender is willing to pay for the payment to go through. This scenario walks through a scenario where a sender, Bob, wants to send some MINA to a receiver, Alice. ### Step 1: To create a payment, Bob clicks send Any member of the network can create a payment and share it with the Mina network. The payment is cryptographically signed with a private key so that the sender's account can be verified. The payment is then sent out to peers on the network to be processed. The payment, when received by a peer, exists in their local `transaction pool`, which is an in-memory store of all the transactions that peer has heard on the network. ### Step 2: To produce a block, Bob's payment gets put in a todo list A block producer node is chosen on the network for a given time slot. The currently active producer chooses in-flight payments based on payment fees and places them in a list to be processed called a transition block. Block producers earn mina for building these blocks. The producer generates a SNARK defining the structure of the transition block as compared to the previous block (but not yet verifying these new payments). The producer transmits this new information for SNARK workers to process. ### Step 3: To prove a SNARK transaction, Bob's payment gets SNARK-signed SNARK worker nodes on the network begin performing SNARK calculations on each step of the new transition block. These are individual proofs of each payment and then merge proofs of neighboring payments. Eventually, all the payments are verified. SNARK workers can earn currency by generating these proofs, paid for by block producers from their block rewards. These proofs are transmitted out over the network. ### Step 4: To verify a payment, Alice and Bob's accounts show the result of the transfer After the whole block has been proven, the block producer sends out a confirmation of the transition block. Then member nodes on the network apply the changes to their local account balances to reflect these changes. ### Step 5: To achieve a payment confidence level, Alice is confident the transfer is complete With each subsequent block, a recipient has a higher degree of confidence that the payment is actually complete and that the network has consensus about that block. However, like in most blockchains, payments are said to be confirmed after a certain number of blocks, also known as transaction finality. In the Bitcoin network, a transaction is confirmed after [6 blocks](https://en.bitcoin.it/wiki/Confirmation) (60 mins) with an assumption that an attacker is unlikely to amass more than 10% of the hashrate. With a slot duration of 3 mins and assuming 90% honest stake, the following table shows the finality in blocks, the average time it takes to produce the corresponding number of blocks, and the confidence that payment will be confirmed. | Finality (in blocks) | Average time for finality | Finality confidence (%) | | -------------------- | ------------------------- | ----------------------- | | 8 | 33 mins | 98.6709 | | 15 | 60 mins | 99.9231 | | 23 | 1hr 32mins | 99.9965 | | 30 | 2hrs | 99.9998 | | 38 | 2hrs 32mins | 100 | Average time is calculated based on consensus constants that determine the number of slots filled per epoch. This is currently set to 75%. The recommended wait time for a transaction to be confirmed is 15 blocks which provides a 99.9% confidence that the transaction will not be reversed. ## Failure Scenarios Payments can fail for several reasons. ### Transaction is not accepted by the network Several reasons why a transaction shared with peer nodes might not get accepted: - The transaction is not fundamentally valid. For example, the sender's account doesn't exist, the account doesn't have sufficient funds, the signature doesn't match with the account, or the nonce in the transaction was not incremented. - There could be adversarial nodes in the network that collude to deny service to specific senders in the network. However, this behavior is highly disincentivized and one honest node is enough to prevent this issue. ### Transaction is not included in a block If a transaction is valid and the network is honest, then in all likelihood, a transaction will make it into a block. However, there is one case where a transaction can be dumped from a transaction pool: - If the transaction pool hits its capacity, or `max_txpool_size`, then it evicts the transaction with the lowest fee in the pool, causing it to be dumped from memory. If this happens, the sender needs to resend the transaction with a higher fee, according to market dynamics at the time. --- url: /mina-protocol/proof-of-stake --- # Proof of Stake The proof of stake consensus mechanism implemented in Mina is a version of the [Ouroboros Praos](https://iohk.io/research/papers/#XJ6MHFXX) protocol, extended and modified slightly for our succinct blockchain. This document will provide an high level overview of how Ouroboros proof of stake works with detailed sections on our changes and additions. For a full description of the Ouroboros protocol, please refer to the original Ouroboros papers: [the original](https://eprint.iacr.org/2016/889.pdf) and [Praos](https://eprint.iacr.org/2017/573.pdf). ### A note on Praos, Genesis, and Mina Formally, our implementation of Ouroboros is an extension of Praos. There is, however, a newer paper which extends Praos, called Ouroboros Genesis. This extension fixes a vulnerability involving long fork attacks, but this cannot be implemented in a succinct blockchain protocol as described in that paper. Instead, we introduce a new, succinct method for protecting against long fork attacks. ## Additions to Praos ### Epoch Ledger Optimization In Ouroboros, nodes need to materialize/keep a ledger at the beginning of the previous epoch in order to VRF evaluations. This is because just having a VRF output is not enough to know that a block was proposed honestly. In order to know that a block was won by the node that proposed it, the VRF output must be such that it is underneath a threshold determined by the proposer's stake, proportional to the total currency in the ledger. In a succinct protocol, such as Mina, materializing/keeping such a ledger in the past is not an easy task. Unlike a non succinct blockchain, nodes cannot arbitrarily request pieces of the chain in the past in order to reconstruct the information they are interested in. This means if we were to implement this feature in a naive manner, we would need to keep in total 3 copies of the entire ledger at any point in time, as well as wait online for at least 2 whole epochs before we could access that information. With some thought, though, we can do much better. There is a big difference between how Ouroboros proves block winners and how Mina proves them. In Ouroboros, every node needs to validate that a block proposer actually won a block when they receive it, meaning they must look up the balance for the public key that evaluated the VRF themselves. In Mina, however, the correctness of the VRF evaluation can be calculated in the SNARK, so other nodes only need to verify the SNARK to know that the block was proposed by a winner. Since a proposer proves this itself, it can limit the information it needs to store about epoch ledgers to only the account record and the merkle path for any account it can propose for (itself and all of its delegated accounts). Furthermore, since Ouroboros guarantees us that the point of finality will be reached before two epochs, the proposer can wait to capture this information after finalization, further limiting the information it needs to store. This information is then fed into the SNARK, which proves that: 1) the VRF evaluation is accurate for the provided public key, and 2) the account for the public key exists in the epoch ledger with a balance that creates a VRF threshold greater than the VRF output (using the merkle path to prove the epoch ledger's merkle root from the account). This does not immediately address the issue of a proposer node needing to be online long enough in order to store this necessary information, but it does open up other avenues of the proposer acquiring that information. Mainly, the proposer could request an account record and merkle path proving it's existence at a given epoch ledger. In the current implementation, no nodes store this information and make it available for access, but one could imagine in the future a service being built that would allow proposers to get online and active quicker by providing this information, possibly for some sort of fee. --- url: /mina-protocol/scan-state --- # Scan State The scan state is a data structure that allows decoupling the production of transaction SNARKs from block producers to SNARK workers. [Block producers](/mina-protocol/block-producers) do not have to produce transaction SNARKs, so the block production time can remain constant regardless of the transaction throughput. The scan state data structure allows the transaction SNARK proof generation to be parallelized and completed by multiple competing [SNARK workers](/mina-protocol/snark-workers). The scan state is comprised of a forest of full [binary trees](https://en.wikipedia.org/wiki/Binary_tree), where each node in the tree is a job to be completed by a SNARK worker. The scan state periodically returns a single proof from the top of a tree that attests to the correctness of all transactions at the base of the tree. The block producers include the emitted ledger proof in the blockchain SNARK they generate that proves both the chain's current state is valid and attests to the validity of all transactions included in the SNARKed ledger. As a result, block times can remain constant regardless of the transaction throughput. The scan state is capable of adjusting to match a desired transaction throughput. :::tip In a steady state, when all slots are filled and all the required proofs are completed, a ledger proof is emitted every block. ::: ### Including transactions When constructing a block, a [block producer](/mina-protocol/block-producers) can include transactions up to the maximum defined by the [scan state constants](#scan-state-constants). Block producers can pick up any available transaction fees and pay themselves a coinbase reward by including transactions. Each transaction they add is transformed into new base jobs and added to the scan state. For every transaction added, a block producer must include an equivalent amount of completed SNARK work corresponding to a sequence of jobs already existing in the scan state. When added to the scan state, these completed jobs create new merge jobs, except for the root node, in which case the proof is returned as a result. The block producer, rather than completing the work themselves, can purchase the completed work from any SNARK workers from bids available in the SNARK pool (snarketplace). ### Scan state constants The following constants dictate the structure and behavior of the scan state: - `transaction_capacity_log_2` - `work_delay` The `transaction_capacity_log_2` constant defines the maximum number of transactions that can be included in a block: ``` max_no_of_transactions = 2^{transaction_capacity_log_2} ``` The work delay ensures there is enough time for the SNARK work to be completed by the SNARK workers. The block producer cannot include any transactions if no completed proofs are available. With the work delay, the maximum number of trees that can exist in the scan state is defined by: ``` max_number_of_trees = (transaction_capacity_log_2 + 1) * (work_delay + 1) + 1 ``` The maximum number of proofs that can be included per block is defined by: ``` max_number_of_proofs = 2^{transaction\_capacity_log_2 + 1} - 1 ``` These scan state constraints ensure that: - Only a single proof can be emitted per block - The merge node to be updated after adding proofs corresponding to its children is always empty. While the maximum number of transactions can be fixed, this number can dynamically adjust to the transaction throughput. As such, the scan state can handle an unlimited transaction throughput, albeit at the cost of increasing (logarithmically) the transaction proof latency. ### Example Consider a scan state with `max_no_of_transactions = 4`, and `work_delay = 1`. Accordingly, this means there can be a maximum amount of work to complete equal to 7 and a maximum of 7 trees. At **genesis**, the scan state is empty. Block 0 **Block 1**: A block producer includes four transactions into the scan state labeled `B1`. These transactions fill the base of the first tree. Block 1 **Block 2**: At the second block, a block producer adds another four transactions (`B2`). These are added to a second tree, once again filling the base. There are no proofs required due to the work delay of 1 block. Block 2 **Block 3**: At the third block, a block producer adds four `B3` transactions to the third tree but must include four proofs for the first tree. As a result of including these completed base proofs, two new `M3` merge jobs are created. Block 3 :::tip `B` or `M` indicates a base or merge job, with the number indicating the sequence order of being added to the scan state. ::: **Block 4**: For the fourth block, a block producer adds another four transactions (`B4`) to the base of the fourth tree. They must include four proofs corresponding to the work added in block 2. Again, two `M4` merge jobs are created as a result. Block 4 :::tip Any pending work (displayed in orange) is work for the SNARK workers to complete. The SNARK workers submit completed work to the SNARK pool. Multiple SNARK workers can complete the work, but only the lowest fee remains in the SNARK pool that can be purchased by the block producers. ::: **Block 5**: In the fifth block, another four transactions are included to fill the base of tree five (`B5`), and six proofs must be included (`B3`s and `M3`s). The `M3` merge jobs result in a final pending merge job for the first tree (`M5`). Block 5 **Block 6**: In the sixth block, another four transactions (`B6`) are added, filling the base of the sixth tree. Six proofs are included (`B4` and `M4`), and three new merge jobs are created (`M6`). Block 6 **Block 7**: In the seventh block, the block producer adds a further four transactions (`B7`), filling the base of the seventh tree. Seven trees are the maximum number of trees according to the specified scan state constants. The maximum number of proofs (7) are included (`B5` and `M5`). These included proofs create three new merge jobs (`M7`);additionally, the top `M5` proof is emitted from the scan state. Block 7 The proof that is emitted from the first tree is the ledger proof corresponding to the transactions added in block 1. The contents of the tree are then removed to create space for additional transactions. Emit proof **Block 8**: In the eighth block, the block producer adds two transactions (`B8`) and includes 4 (`B6`) proofs. These included proofs result in two new merge jobs (`M8`). Note that only four proofs are required for adding two transactions. Block 8 :::tip SNARK work is bundled into a work package typically containing two _workIds_, except for the final root proof of a tree. Prorated work for a transaction is two proofs, ensuring the equality of transactions included and SNARK work to be purchased. ::: **Block 9**: The block producer adds three transactions (`B9`) in the ninth block. Three proofs (`M6`) are required to occupy the slots in the currently unfilled tree. Four proofs were added in the previous block, so only three more proofs need to be done (given the maximum work is 7). The `M6` proof from tree two is returned as the ledger proof. The third `B9` transaction goes into the now empty tree, and two `B7` proofs are added. Block 9 **Block 10**: In block ten, the block producer adds four transactions and, as a result, includes seven proofs (`B7`, `M7`, and two `B8`s). Block 10 **Block 11**: In the eleventh block, the block producer adds three transactions (`B11`) and completes five proofs (`B9`, `B9`, `M8`, `M8`, `M9`) in that order. In addition, the `M9` ledger proof is returned from the fourth tree. Block 11 :::tip To view the contents of the scan state, run the `mina advanced snark-job-list` command. ::: ### Integration with the SNARK Pool Newly added jobs to the scan state are pending jobs for SNARK workers to complete. SNARK workers complete the required transaction SNARKs, submitting bids for their completed work. When a node receives and validates the completed work, SNARK workers add the completed work to the local SNARK pool if it is valid and has the lowest fee for the required work. The work is also gossiped to other peers in the network. :::tip While multiple SNARK workers can complete the same work, only the lowest fee is included in the SNARK pool. ::: When a block producer includes completed proofs into a block to offset any transactions they add, they may purchase the corresponding work from the SNARK pool. Continuing the previous example, consider the next block (12). If the block producer wants to add three transactions, comprising a coinbase, a user payment, and a fee transfer to the SNARK worker, the block producer must purchase three completed SNARK works. This corresponds to the six `B9`, `B10`s, `M9`, and `M10` (from the seventh tree) proofs, as each SNARK work includes two _workIds_. During the time the block is generated, the SNARK pool can include completed work and the best bids for the required jobs (0.025, 0.165, 0.1, and 0.5) respectively, in the example. Submitted work A block producer considers the price of available work before selecting transactions. - The first transaction a block producer adds is the coinbase transaction for which there is the coinbase reward. - If transaction fees do not cover the SNARK work fees required for them to be included, the transaction is not added. A block producer never purchases work if it is not economical. If completed SNARK work is not available to purchase in the order required, then the corresponding transactions are not included in a block. This situation can result in an empty block, but also, for the case where no transactions can be added (including a coinbase transaction), there is no reward for the block producer. To view the current SNARK pool, use: - [GraphQL API](/node-developers/graphql-api) - Mina CLI `mina advanced snark-pool` command --- url: /mina-protocol/sending-a-payment --- # Sending a Payment How to send a MINA payment using the Mina CLI. :::info Reminder that this section is intended for node operators. If you want to store, send, and receive MINA without running a node, please see the [Install a Wallet](../using-mina/install-a-wallet) page for links to various user-friendly wallets available for Mina. ::: In this section, we'll give a brief overview on how to send a transaction with the Mina client and how to get started with interacting with the blockchain. ## Using an offline signed-transaction If you want to send a transaction without running a node yourself, but by delegating to someone else running a node, keep following along here. If you wish to send the transaction directly with a running node, skip to [using a connected node](#using-a-connected-node). ### Using a Ledger device To generate a signed transaction offline if your private key is on a Ledger device, see [Ledger Hardware Wallet](/using-mina/ledger-hardware-wallet). ### Using a keypair generated with the generate-keypair tool A better tool is coming soon: https://github.com/MinaProtocol/mina/issues/8928. For now, please use the [workaround](https://github.com/MinaProtocol/mina/issues/8928#issuecomment-857095846) provided in a comment on that issue. ### Using a keypair generated with the offline client-sdk Use the [Mina Signer](/mina-signer). See the [Mina Signer documentation](/mina-signer) for installation and usage instructions. ### Send the transaction You can use a hosted service to broadcast your signed transaction. Sending your signed transaction _does not_ leak your private key. Transactions signed with the Mina Signer can use: [https://minascan.io/mainnet/broadcast/payment](https://minascan.io/mainnet/broadcast/payment) Transactions signed with the Ledger hardware wallet can use: [https://minascan.io/mainnet/broadcast/ledger-payment](https://minascan.io/mainnet/broadcast/ledger-payment) ## Using a connected node We are assuming in the rest of section that you have the Mina client installed on your system, if you do not have Mina installed please see the [Getting Started](/node-operators/block-producer-node/getting-started). ## Import your account Once our node is synced, we'll need to import our public/private keypair so that we can sign transactions and generate an address to receive payments. For security reasons, we'll want to put the keys under a directory that is harder for attackers to access. Run the following command to import your [previously generated](/node-operators/validator-node/generating-a-keypair) keypair file: mina accounts import --privkey-path ~/keys/my-wallet You will be prompted for the password you entered when the account was created. :::caution The public key can be shared freely with anyone, but be very careful with your private key file. Never share this private key with anyone, as it is the equivalent of a password for your funds. ::: The response from this command will look like this: 😄 Imported account! Public key: B62qjaA4N9843FKM5FZk1HmeuDiojG42cbCDyZeUDQVjycULte9PFkC Additionally you can use the `mina accounts create` command to generate new accounts to send and receive transactions. Since the public key is quite long and difficult to remember, let's save it as an environment variable. Use the following command but replace `` with the public key output from the previous command: export MINA_PUBLIC_KEY=`` Now we can access this everywhere as `$MINA_PUBLIC_KEY` -- check if it saved properly by trying `echo $MINA_PUBLIC_KEY`. Note that these environment variables will only be saved for the current shell session, so if you want to save them for future use, you can add them to `~/.profile` or `~/.bash_profile`. :::tip If you are running the node on a cloud virtual machine, make sure to export and save the key file. You can export the key with: mina accounts export --public-key `` --privkey-path `` Then save it to your local machine, maybe using [scp](https://linux.die.net/man/1/scp): scp `` `` Later, when starting up a new VM, you can upload the key and then import it: mina accounts import --privkey-path `` ::: If you ever forget what keypairs you've already created, you can see them all with: mina accounts list ## Check account balance We can check the balance of all our accounts using this command: mina accounts list You might see `Balance: 0 mina` for your account. Depending on the traffic in the network, it may take a few blocks before your transaction goes through. :::tip You can run `mina client status` to see the current block height updating. ::: ## Make a payment Finally, we get to the good stuff–sending our first transaction! Before you send a payment, you'll need to unlock your account: mina accounts unlock --public-key $MINA_PUBLIC_KEY For testing purposes, we will specify your public key as the receiver and sender. This just means that we are sending a transaction to ourselves, you can see your public key by issuing the following command: ``` echo $MINA_PUBLIC_KEY ``` :::caution If the receiving account has not received any transactions, there will be an additional Account Creation Fee of `1 MINA` that will be deducted from the transaction amount. ::: Let's send some of our Mina to ourselves to see what a payment looks like: mina client send-payment \ --amount 1.5 \ --receiver $MINA_PUBLIC_KEY \ --fee 0.1 \ --sender $MINA_PUBLIC_KEY If you're wondering what we passed in to the commands above: - For `amount`, we're sending a test value of `1.5` mina which is enough to cover the Account Creation Fee - The `receiver` is the public key of the account receiving the transaction, eg. `B62qjaA4N9843FKM5FZk...` - For `fee`, let's use 0.1 mina - The `sender` is the public key of the account sending the transaction, eg. `B62qjaA4N9843FKM5FZk...` If this command is formatted properly, we should get a response that looks like the following: Dispatched payment with ID 3XCgvAHLAqz9VVbU7an7f2L5ffJtZoFega7jZpVJrPCYA4j5HEmUAx51BCeMc232eBWVz6q9t62Kp2cNvQZoNCSGqJ1rrJpXFqMN6NQe7x987sAC2Sd6wu9Vbs9xSr8g1AkjJoB65v3suPsaCcvvCjyUvUs8c3eVRucH4doa2onGj41pjxT53y5ZkmGaPmPnpWzdJt4YJBnDRW1GcJeyqj61GKWcvvrV6KcGD25VEeHQBfhGppZc7ewVwi3vcUQR7QFFs15bMwA4oZDEfzSbnr1ECoiZGy61m5LX7afwFaviyUwjphtrzoPbQ2QAZ2w2ypnVUrcJ9oUT4y4dvDJ5vkUDazRdGxjAA6Cz86bJqqgfMHdMFqpkmLxCdLbj2Nq3Ar2VpPVvfn2kdKoxwmAGqWCiVhqYbTvHkyZSc4n3siGTEpTGAK9usPnBnqLi53Z2bPPaJ3PuZTMgmdZYrRv4UPxztRtmyBz2HdQSnH8vbxurLkyxK6yEwS23JSZWToccM83sx2hAAABNynBVuxagL8aNZF99k3LKX6E581uSVSw5DAJ2S198DvZHXD53QvjcDGpvB9jYUpofkk1aPvtW7QZkcofBYruePM7kCHjKvbDXSw2CV5brHVv5ZBV9DuUcuFHfcYAA2TVuDtFeNLBjxDumiBASgaLvcdzGiFvSqqnzmS9MBXxYybQcmmz1WuKZHjgqph99XVEapwTsYfZGi1T8ApahcWc5EX9 Receipt chain hash is now A3gpLyBJGvcpMXny2DsHjvE5GaNFn2bbpLLQqTCHuY3Nd7sqy8vDbM6qHTwHt8tcfqqBkd36LuV4CC6hVH6YsmRqRp4Lzx77WnN9gnRX7ceeXdCQUVB7B2uMo3oCYxfdpU5Q2f2KzJQ46 You may not see the `Receipt chain hash` on the first transaction from the account, but in following transactions, this will show you the head of the receipt chain hash list. ## Staking and Snarking Once you feel comfortable with the basics of creating an address, and sending & receiving mina, we can move on to the truly unique parts of the Mina network like [participating in consensus and helping compress the blockchain](/node-operators/validator-node/staking-and-snarking). ## Advanced ### Sending Many Transactions Sometimes you may wish to send many transactions: for example, to payout rewards to those delegating to you if you're running a staking pool. All information here is relevant as of the 3.0.3 build: ### Rate limiting Currently, nodes on the network will rate limit receiving messages from a given node. As of the 3.0.3 build, your node will also follow this rate limit when sending transactions. Specifically, the limit is currently set at 10 transactions every 15 seconds computed over a 5 minute window. If you attempt to send transactions faster than this rate, your node will queue them up and flush them as older transactions expire from the window upon which the rate limit is computed. You do not need to throttle sending these transactions yourself. Note that older releases of the mina daemon do not perform this rate limiting; if you are running an older version, you should manually limit the number of transactions. Due to overheads from rebroadcasting transactions, we do not recommend sending more than 50 transactions every 5 minutes if you need to manually rate limit. ### My node crashed or disconnected before I could finish sending transactions The Mina daemon does _not_ currently persist the transaction pool. This means that the transactions that your node will be unaware of any transactions that you've sent so far if your node crashes in the middle of this process. As of the 3.0.3 build, you can resend all transactions (exactly in the same manner as before) and they will be rebroadcasted on the network. If you believe you were temporarily disconnected from the network, but your node stayed online (i.e. the gossip network may have missed one or more of your transactions), as of the 3.0.3 build, you can resend any of the transactions locally and they will be broadcasted again to the network even if your node thinks they've already been shared. ### Cancelling a transaction and setting a new fee To cancel a transaction, you'll need to have all the transactions that haven't been committed to the chain yet before in your local transaction mempool. This means if your node crashed (see above) you'll need to resend those earlier transactions. Finally, to cancel a transaction, all you need to do is send a transaction with the same nonce of the one you want to cancel with a larger fee. There is no minimum increment, it just needs to be slightly larger (and large enough such that a block producer will choose your transaction). --- url: /mina-protocol/snark-workers --- # SNARK Workers While most protocols have just one primary group of node operators (often called miners, validators, or block producers), Mina has a second group — the **SNARK worker**. SNARK workers are integral to the Mina network's health because these nodes are responsible for snarking, or producing SNARK proofs, of transactions in the network. By producing these proofs, snark workers help maintain the succinctness of the Mina blockchain. Read on to learn why SNARK workers are needed, how the economic incentives align, and operational details of performing SNARK work. Feel free to click through to any of the sections that are most relevant to your needs. Note: The theory of zk-SNARKs is not covered. Deep knowledge of SNARKs is not required to read this section, but it is helpful to understand in general how SNARKs work and what they are useful for. To learn more, check out this [What are zk-SNARKs?](https://minaprotocol.com/blog/what-are-zk-snarks) primer first. ## How Mina Compresses the Blockchain The Mina protocol is unique because nodes are not required to maintain the full history of the blockchain like other cryptocurrency protocols. By recursively using cryptographic proofs, the Mina protocol effectively compresses the blockchain to constant size. This compression reduces terabytes of data to a few kilobytes. However, this isn't data encoding or compression in the traditional sense. Mina nodes _compress_ data in the network by generating cryptographic proofs. Node operators play a crucial role in this process by designating themselves as [SNARK workers](/glossary#snark-worker) that generate [zk-SNARKs](/glossary#zk-snark) for transactions that have been added to blocks. You can connect a SNARK worker to the network or use a SNARK coordinator. [SNARK coordinators](/glossary#snark-coordinator) can be used to coordinate and distribute work to any [SNARK workers](/glossary#snark-worker) that you are running. If you are running a SNARK coordinator, connect the SNARK coordinator to the network, then connect SNARK workers to the SNARK coordinator. ## Why SNARK Workers? Mina's unique property is the succinct blockchain. Each block producer, when they propose a new block to the network, must also include a zk-SNARK along with that block. This allows nodes to discard all historical data that's been finalized, and retain just the SNARK. If you are unfamiliar with the Mina protocol, [this video is a good start](https://www.youtube.com/watch?v=eWVGATxEB6M). However, it is not only sufficient for the block producers in Mina to generate SNARK proofs of blocks. Transactions also need to be SNARKed. The reason is because the blockchain SNARK does not make any statements of the validity of the transactions included in the block. For example — let's say the current head of the blockchain has a state hash `a6f8792226...` , and we receive a new block with a state hash `0ffdcf284f...` . This block will contain all the transactions that the block producer has chosen to include in this block, and associated metadata. We will also receive an accompanying SNARK that verifies the statement: > "There exists a block with a state hash 0ffdcf284f which extends the blockchain > with a previous best tip with state hash a6f8792226." Notice that this statement says nothing about the validity of the transactions included in the new block. If we were to believe this SNARK, and do nothing else, we may be tricked by a malicious block producer sending this block. Luckily, we have the raw block and we can check each transaction to ensure it is valid. But what about nodes in the network that may just want to receive the proof and not verify each block? ## Snarking Transactions In order to ensure that nodes can operate without trust on the Mina blockchain, it is important that each node can verify the state of the chain without needing to replay the transactions. In order for this to work, the blockchain SNARK is not enough. We need to know that the transactions are also valid. Well, since SNARKs are good for exactly that, the naive suggestion might be to generate a SNARK of each transaction as they come in, and then combine them. However, generating SNARK proofs is computationally expensive — if we had to compute SNARKs serially for each transaction, throughput would be very low and block times would skyrocket. Furthermore, transactions in a real world environment arrive asynchronously, so it would be very tough to predict when to perform the next item of work. Lucky for us, we can leverage two properties about SNARKs: 1. proofs can be merged - two proofs can be combined to form a _merge proof_ 2. merges are associative - merge proofs are identical, regardless of the order merged SNARK Workers What these two properties essentially allow us to do is take advantage of parallelism. If proofs can be merged, and it doesn't matter how they're combined, then SNARK proofs can be generated in parallel. Whichever proof is finished first can be combined later with the proofs in progress. This can be envisioned as a binary tree, where the bottom row (the leaves) consists of the individual transaction proofs, and each parent row, the set of respective merge proofs. We can combine these all the way to the root, which represents a state update performed by applying all the transactions. In addition, because the SNARK proofs don't depend on each other and we can exploit parallelism, this means anyone can do the work! The end result is that the distributed work pool is permission-less. Anyone with spare compute can join the network as SNARK workers, observe transactions that need to be SNARKed, and contribute their compute. And of course, they will be compensated for their work in what we affectionately call **the snarketplace**. Note: To learn more about the details of how this SNARK work scheme evolved, it is highly recommended to watch this video: [High Throughput with Slow Snarks](https://www.youtube.com/watch?v=NZmq1V-Te0E). If you're interested in functional programming and the details of the scan state (the tree structure described above), we have [a video](https://www.youtube.com/watch?v=ztH_Z5TCe9I) covering the technical details. ## The Snarketplace The key dynamic to understand about SNARK work is: _Block producers use their block rewards to purchase SNARK work from SNARK workers._ As a SNARK worker, you get to share some of the block rewards for each block that includes your compressed transactions. The block producer is responsible for gathering compressed transactions before including them into a block and is incentivized by the protocol to reward SNARK workers. There is no protocol involvement in pricing snarks, nor are there any protocol level rewards for SNARK workers to produce snarks. The incentives are purely peer-to-peer, and dynamically established in a public marketplace, aka the snarketplace. You may ask, why does a block producer need to buy SNARKs? Fair question — the reason is because of what we mentioned earlier. In order to know for sure the state at the head of the Mina blockchain is valid, the transactions need to be SNARKed. But if we keep adding more transactions without snarking them at an equal rate, then over time we accumulate work that never gets finished. In order to reach a steady state equilibrium, we need work to be processed at roughly the same rate that work is added. Since block producers profit from including transactions in a block (through transaction fees and the coinbase transaction), they are responsible for offsetting the transactions by purchasing an equal number of completed SNARK work, thereby creating demand for SNARK work. However, their imperative is to purchase SNARK work for the lowest price from the snarketplace. Conversely, the SNARK workers want to maximize their profit while also being able to sell their SNARK work. These two roles act as the two sides of the marketplace, and over time establish an equilibrium at a market price for SNARK work. ### How to price SNARK work We anticipate the snarketplace to dynamically rebalance — eg. follow the simple laws of [supply and demand](https://en.wikipedia.org/wiki/Supply_and_demand). While each SNARK work applies to a different transaction, seen from a larger perspective, SNARK work is largely a commodity (meaning it doesn't matter which SNARK worker produces the good — it will be the same). However, there are some nuances, so it may help to have some heuristics for pricing strategy: - if market price is X, it is likely effective to sell SNARK work for any price below X (eg. X - 1), provided it is profitable after operating expenses. - block producers are incentivized to purchase more units of SNARK work from the same SNARK worker because there will only be one _fee transfer_ transaction they have to include in the block. - Basically, the way a block producer pays a SNARK worker is through a special type of transaction called a fee transfer. The BP's incentive is to minimize the number of fee transfers, as each is a discrete transaction that needs to be added to a block (and consequently offset by more SNARK work). Thus, the best case scenario is to buy a bundle of SNARK work from the same SNARK worker. - some SNARK work will be more important to complete ahead of other work, as it would free up an entire tree worth of memory (see the video above for more details). This is made possible by different work selection methods. Currently, the three methods supported natively are sequential, random and sequential with a random offset. Neither of these however takes advantage of dynamic markets, which is an area of improvement that the Mina community can develop solutions for. Since all the data around snarks and prices are public, there are several ways to inspect the snarketplace. One example is [using the GraphQL API](https://youtu.be/XQlfX-LnK_A), and other options include using the CLI, or rolling a custom solution that tracks snarks in the SNARK mempool. Stay tuned for more detailed analysis on snarketplace dynamics. We will also be releasing an economic whitepaper shortly that will provide more context. See also: [SNARKs and SNARK Workers FAQ](/node-operators/faq#snarks-and-snark-workers) --- url: /mina-protocol/time-locked-accounts --- # Time-Locked Accounts A time-locked account disallows payments that would reduce the balance below a minimum, which depends on the block height. To create a time-lock, you must provide the configuration when creating a new account. This can happen only in the genesis ledger at the beginning of a network. In this section, we'll explore the mechanism behind time-locks and see how to interact with time-locked accounts. :::tip For the current release, values for time-locked accounts were assigned based on the order in which you signed up. ::: ## Understanding time-locks A time-lock consists of the following fields `initial_minimum_balance`, `cliff` time, a `vesting_period` time, and a `vesting_increment`. You can still use an account if it has a time-lock, as long as the account holds enough funds. The amount of funds that are time-locked starts off as `initial_minimum_balance` at the beginning of the network. Once the network reaches a block height equal to the `cliff`, the time-locked amount begins to decrease by the `vesting_increment` amount every `vesting_period`. For a more technical explanaition of this process, please see [RFC-0025](https://github.com/MinaProtocol/mina/blob/master/rfcs/0025-time-locked-accounts.md) which has a more in-depth overview. ### Liquid Balance Details: If you'd like to expose liquid balances for vesting accounts at some particular time period it is governed by the following function (Note: this computes the locked portion of an account): ``` (* * uint32 global_slot -- the "clock" it starts at 0 at the genesis block and ticks up every 3minutes. * uint32 cliff_time -- the slot where the cliff is (similar to startup equity vesting) * uint32 cliff_amount -- the amount that unlocks at the cliff * amount vesting_increment -- unlock this amount every "period" * uint32 vesting_period -- the period that we increment the unlocked amount * balance initial_minimum_balance -- the total locked amount until the cliff *) let min_balance_at_slot ~global_slot ~cliff_time ~cliff_amount ~vesting_period ~vesting_increment ~initial_minimum_balance = let open Unsigned in if Global_slot.(global_slot < cliff_time) then initial_minimum_balance else match Balance.(initial_minimum_balance - cliff_amount) with | None -> Balance.zero | Some min_balance_past_cliff -> ( (* take advantage of fact that global slots are uint32's *) let num_periods = UInt32.( Infix.((global_slot - cliff_time) / vesting_period) |> to_int64 |> UInt64.of_int64) in let vesting_decrement = UInt64.Infix.(num_periods * Amount.to_uint64 vesting_increment) |> Amount.of_uint64 in match Balance.(min_balance_past_cliff - vesting_decrement) with | None -> Balance.zero | Some amt -> amt ) ``` ## Creating a time-locked account As of the current release, the only way to create a time-locked account is with the genesis ledger. In future releases we may add commands to `mina client` and the GraphQL API that will allow you to create a new time-locked account. --- url: /mina-protocol/whats-in-a-block --- # What's in a Block? A block is a set of transactions and consensus information that extend the state of the network. A block in Mina includes a proof that the current state of the network is fully valid. A block in Mina is constituted of: * [Protocol state](#protocol-state) * [Protocol state proof](#protocol-state-proof) * [Staged ledger diff](#staged-ledger-diff) * [Delta transition chain proof](#delta-transition-chain-proof) * Current protocol version * Proposed protocol version When a node receives a block from a peer, it is first validated, applied to the existing state, and added to the node's transition frontier. If, according to the [consensus](https://minaprotocol.com/blog/what-is-ouroboros-samasika) rules, it results in increasing the length of the blockchain, the node's best tip is updated, and the root of the transition frontier is moved up to only maintain `k` blocks in the transition frontier. :::tip In Mina, blocks are synonymous with "transitions". When this transition (block) is received from a peer, it is referenced as an external transition, whereas one generated and applied locally is referred to as an internal transition. ::: ### Protocol State The protocol state is comprised of the **previous protocol state hash** and a body that contains: * [Genesis state hash](#genesis-state-hash) * [Blockchain state](#blockchain-state) * [Consensus state](#consensus-state) * [Consensus constants](#consensus-constants) Each block contains the protocol state hash of the previous block, such that blocks may be linked together to form an immutable chain. The protocol state hash is determined from the hash of hashes of the previous state and body and acts as a unique identifier for each block. #### Genesis State Hash The genesis state hash is the protocol state hash for the genesis protocol state. #### Blockchain State The blockchain state is comprised of: * Staged ledger hash * Genesis ledger hash * Ledger proof statement * Timestamp * Body reference ##### Ledger proof statement The ledger proof statement is comprised of: * Snarked ledger hash * Signed amount * Pending coinbase stack * Fee excess * Sok digest * Local state #### Consensus State The consensus state is comprised of: * Blockchain length * Epoch count * Min window density * Sub window density * Last VRF output * Total currency * Current global slot * Global slot since genesis * Staking epoch data * Next epoch data * Has ancestor in same checkpoint window * Block stake winner * Block creator * Coinbase receiver * Superchage coinbase #### Consensus Constants Constants define the consensus parameters: * k * delta * slots_per_sub_window * slots_per_window * sub_windows_per_window * slots_per_epoch * grace period slots * grace period end * checkpoint_window_slots_per_year * checkpoint_window_size_in_slots * block_window_duration_ms * slot_duration_ms * epoch_duration * delta_duration * genesis_state_timestamp ### Protocol State Proof The protocol state proof is a blockchain proof proving that the new protocol state generated by the block producer is valid. Due to the use of recursive SNARKs, this protocol state proof proves the entire history of the chain is valid. ### Staged Ledger Diff When a [block producer](/mina-protocol/block-producers) wins a slot to produce a block, they select transactions and any SNARK work required from the transaction and SNARK pools. They create the proposed next state of the blockchain, which comprises creating a diff of the staged ledger. A diff consists of: * Transactions included in the block * A list of SNARK proofs generated by [SNARK workers](/mina-protocol/snark-workers) for prior transactions added * Pending coinbase A staged ledger can be regarded as a pending accounts database that has transactions(payments, coinbase, and proof fee payments) applied for which there are no SNARKs available yet. A staged ledger consists of the accounts state (a ledger) and a transaction queue for transactions without SNARK proofs, which is the [scan state](/mina-protocol/scan-state). ### Delta Transition Chain Proof There is an allowed network delay when broadcasting or gossiping newly produced blocks around the network to allow for adverse network conditions. The delta transition chain proof proves that the block was produced within the allotted slot time. ### Example Block ``` { "external_transition": { "protocol_state": { "previous_state_hash": "3NLKJLNbD7rBAbGdjZz3tfNBPYxUJJaLmwCP9jMKR65KSz4RKV6b", "body": { "genesis_state_hash": "3NLxYrjb7zmHdoFgBrubCN8ijM8v7eT8kvLiPLc9DHt3M8XrDDEG", "blockchain_state": { "staged_ledger_hash": { "non_snark": { "ledger_hash": "jxV4SS44wHUVrGEucCsfxLisZyUC5QddsiokGH3kz5xm2hJWZ25", "aux_hash": "UmosfM82dH5xzqdckXgA1JoAvJ5tLxch2wsty4sXmiEPKnPTPq", "pending_coinbase_aux": "WLo8mDN6oBUTSyBkFCy7Fky7Na5fN4R6oGq4HMf3YoHCAj4cwY" }, "pending_coinbase_hash": "2mze7iXKwA9JAqVDC1MVvgWfJDgvbgSexKtuShdkgqMfv1tjATQQ" }, "ledger_proof_statement": { "connecting_ledger_right": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S", "sok_digest": null, "target": { "local_state": { "full_transaction_commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", "call_stack": "0x0000000000000000000000000000000000000000000000000000000000000000", "token_id": "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf", "excess": { "sgn": [ "Pos" ], "magnitude": "0" }, "success": true, "stack_frame": "0x0641662E94D68EC970D0AFC059D02729BBF4A2CD88C548CCD9FB1E26E570C66C", "will_succeed": true, "account_update_index": "0", "supply_increase": { "sgn": [ "Pos" ], "magnitude": "0" }, "ledger": "jw6bz2wud1N6itRUHZ5ypo3267stk4UgzkiuWtAMPRZo9g4Udyd", "failure_status_tbl": [], "transaction_commitment": "0x0000000000000000000000000000000000000000000000000000000000000000" }, "pending_coinbase_stack": { "state": { "init": "4Yx5U3t3EYQycZ91yj4478bHkLwGkhDHnPbCY9TxgUk69SQityej", "curr": "4Yx5U3t3EYQycZ91yj4478bHkLwGkhDHnPbCY9TxgUk69SQityej" }, "data": "4QNrZFBTDQCPfEZqBZsaPYx8qdaNFv1nebUyCUsQW9QUJqyuD3un" }, "first_pass_ledger": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S", "second_pass_ledger": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S" }, "fee_excess": [ { "token": "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf", "amount": { "sgn": [ "Pos" ], "magnitude": "0" } }, { "amount": { "sgn": [ "Pos" ], "magnitude": "0" }, "token": "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf" } ], "source": { "second_pass_ledger": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S", "local_state": { "account_update_index": "0", "supply_increase": { "sgn": [ "Pos" ], "magnitude": "0" }, "stack_frame": "0x0641662E94D68EC970D0AFC059D02729BBF4A2CD88C548CCD9FB1E26E570C66C", "ledger": "jw6bz2wud1N6itRUHZ5ypo3267stk4UgzkiuWtAMPRZo9g4Udyd", "transaction_commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", "token_id": "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf", "excess": { "sgn": [ "Pos" ], "magnitude": "0" }, "call_stack": "0x0000000000000000000000000000000000000000000000000000000000000000", "will_succeed": true, "full_transaction_commitment": "0x0000000000000000000000000000000000000000000000000000000000000000", "failure_status_tbl": [], "success": true }, "first_pass_ledger": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S", "pending_coinbase_stack": { "data": "4QNrZFBTDQCPfEZqBZsaPYx8qdaNFv1nebUyCUsQW9QUJqyuD3un", "state": { "curr": "4Yx5U3t3EYQycZ91yj4478bHkLwGkhDHnPbCY9TxgUk69SQityej", "init": "4Yx5U3t3EYQycZ91yj4478bHkLwGkhDHnPbCY9TxgUk69SQityej" } } }, "supply_increase": { "sgn": [ "Pos" ], "magnitude": "0" }, "connecting_ledger_left": "jwbhUympjiAFLPi7w3Cg9GEeNCfACEpPxrTp45XZt3BDA5UNV8S" }, "body_reference": "b94b2580ca80f27c9655289579a0d71df0b7604dfa7c404e6c309cccf7730d2f", "snarked_ledger_hash": "jx9171AbMApHNG1guAcKct1E6nyUFweA7M4ZPCjBZpgNNrE21Nj", "genesis_ledger_hash": "jxX6VJ84HaafrKozFRA4qjnni4aPXqXC2H5vQLKSryNpKTXuz1R", "snarked_next_available_token": "2", "timestamp": "1611691710000" }, "consensus_state": { "blockchain_length": "3852", "epoch_count": "1", "min_window_density": "1", "sub_window_densities": [ "3", "1", "3", "1", "4", "2", "1", "2", "2", "4", "5" ], "last_vrf_output": "g_1vrXSXLhvn1e4Ap1Ey5e8yh3PFMJT0vZyhZLlTBAA=", "total_currency": "167255800000001000", "curr_global_slot": { "slot_number": "12978", "slots_per_epoch": "7140" }, "global_slot_since_genesis": "12978", "staking_epoch_data": { "ledger": { "hash": "jxX6VJ84HaafrKozFRA4qjnni4aPXqXC2H5vQLKSryNpKTXuz1R", "total_currency": "165950000000001000" }, "seed": "2vb1Mjvydod6sEwn7qpbejKCfRqugMgyG3MHXXRKcAkwQLRs9fj8", "start_checkpoint": "3NK2tkzqqK5spR2sZ7tujjqPksL45M3UUrcA4WhCkeiPtnugyE2x", "lock_checkpoint": "3NK5G8Xqn1Prh3XoTyZ2tqntJC6X2nVwruv5mEJCL3GaTk7jKUNo", "epoch_length": "1769" }, "next_epoch_data": { "ledger": { "hash": "jx7XXjRfJj2mGXmiHQmpm6ZgTxz14udpugyFtw4DefJFpie7apN", "total_currency": "166537000000001000" }, "seed": "2vavBR2GfJWvWkpC7yGJQFnts18nHaFjdVEr84r1Y9DQXvnJRhmd", "start_checkpoint": "3NLdAqxtBRYxYbCWMXxGu6j1hGDrpQwGkBDF9QvGxmtpziXQDADu", "lock_checkpoint": "3NL4Eis1pS1yrPdfCbiJcpCCYsHuXY3ZgEzHojPnFWfMK9gKmhZh", "epoch_length": "2084" }, "has_ancestor_in_same_checkpoint_window": true, "block_stake_winner": "B62qpBrUYW8SHcKTFWLbHKD7d3FqYFvGRBaWRLQCgsr3V9pwsPSd7Ms", "block_creator": "B62qpBrUYW8SHcKTFWLbHKD7d3FqYFvGRBaWRLQCgsr3V9pwsPSd7Ms", "coinbase_receiver": "B62qpBrUYW8SHcKTFWLbHKD7d3FqYFvGRBaWRLQCgsr3V9pwsPSd7Ms", "supercharge_coinbase": true }, "constants": { "k": "290", "slots_per_epoch": "7140", "slots_per_sub_window": "7", "delta": "0", "genesis_state_timestamp": "1609355670000" } } }, "protocol_state_proof": "", "staged_ledger_diff": "", "delta_transition_chain_proof": "", "current_protocol_version": "1.1.0", "proposed_protocol_version": "" } } ``` --- url: /mina-security --- # Mina Security Mina Protocol is built with ZK from the ground up so anyone can quickly sync and verify the network, exponentially increasing participation, true decentralization, censorship resistance, and network security. However it doesn't stop there. Check out some other resources to see what measures are in place to keep Mina secure. ## Audits ### Protocol - [August 27, 2024 o1js](https://github.com/o1-labs/o1js/blob/a09c5167c4df64f879684e5af14c59cf7a6fce11/audits/VAR_o1js_240318_o1js_V3.pdf) by Veridise - [December 12, 2023 Pickles](https://minaprotocol.com/wp-content/uploads/Least-Authority-Pickles-Final-Audit-Report.pdf) by Least Authority - [August 28, 2023 Transaction Logic and Transaction Pool](https://minaprotocol.com/blog/least-authority-concludes-security-audit-of-mina-protocols-transaction-logic-and-transaction-pool) by Least Authority - [October 16, 2022 Mina codebase, ecosystem projects](https://minaprotocol.com/wp-content/uploads/Mina-Security-Assessment-2022.pdf) by Mo Ashouri - [February 22, 2022 Mina Client SDK, Signature Library and Base Components](https://www.nccgroup.com/us/research-blog/public-report-o-1-labs-mina-client-sdk-signature-library-and-base-components-cryptography-and-implementation-review/?sq=mina) by NCC Group - [December 2020 Mina Protocol and Staking Economics](https://gauntlet.network/reports/mina) by Gauntlet Network - [May 14, 2020 Coda Protocol ](https://minaprotocol.com/blog/ncc-group-security-audit-results-of-coda-protocol) by NCC Group ### Tools - [Feb 4, 2022 Mina Ledger Application](https://minaprotocol.com/blog/ledger-nanox-nanos-developer-mode) by Least Authority - [Sept 28, 2021 StakingPower Wallet ](https://minaprotocol.com/blog/least-authority-concludes-security-audit-on-stakingpower-wallet) by Least Authority - [August 9, 2021 Auro Wallet](https://minaprotocol.com/blog/least-authority-concludes-security-audit-on-auro-wallet) by Least Authority - [July 16, 2021 Clor.io Wallet](https://minaprotocol.com/blog/clorio-wallet-audit) by Least Authority ### Auditors - [Veridise](https://veridise.com/) - [Least Authority](https://leastauthority.com/) - [NCC Group](https://www.nccgroup.com/us/) - [Gauntlet Network](https://www.gauntlet.xyz/) ## Current Community Security Programs - [Bug Bounty Program](https://minaprotocol.com/blog/re-launching-the-mina-ecosystem-bug-bounty-program) - [Testworld Mission 2.0](https://minaprotocol.com/blog/testworld-2-protocol-performance-testing-program) ## Learn - [Solving for Blockchain’s Security Flaw — Accessible Nodes](https://minaprotocol.com/blog/solving-for-blockchains-security-flaw?utm_medium=gitHub&utm_source=social&utm_campaign=evergreen) - [What is Ouroboros Samisika?](https://minaprotocol.com/blog/how-ouroboros-samasika-upholds-minas-goals-of-decentralization?utm_medium=github&utm_source=social&utm_campaign=updates) - [How Ouroboros Samasika Upholds Mina’s Goals of Decentralization](https://minaprotocol.com/blog/how-ouroboros-samasika-upholds-minas-goals-of-decentralization?utm_medium=github&utm_source=social&utm_campaign=updates) - [Mina’s Mainnet Launch Marks a New Era for Internet Privacy and Data Security](https://minaprotocol.com/blog/minas-mainnet-launch-marks-a-new-era-for-internet-privacy-and-data-security?utm_medium=github&utm_source=social&utm_campaign=updates) --- url: /mina-signer --- # Mina Signer Mina Signer is a NodeJS/Browser compatible JavaScript library tailored for the Mina Protocol. This library aids developers in seamlessly signing transactions and generating keys. A noteworthy feature is the ability to sign transactions offline, allowing for their broadcasting to the network whenever required. It also supports functionalities such as signing zkApp transactions, verifying these transactions, generating nullifiers, and more. ## Installation To incorporate Mina Signer into your project: ```sh npm install mina-signer ``` ## Mina Protocol Usage Mina Signer offers a wide range of features for the Mina Protocol: - Generate keys - Sign transactions - Verify transactions Additionally, it ensures compatibility across various networks, like mainnet and testnet. ### Specifying the network When importing and initializing Mina Signer, it's imperative to designate the desired network. Different networks may employ varying cryptographic methods. This specification is executed by supplying the network parameter during the constructor's invocation. Possible values are `mainnet` and `testnet`. :::tip By default, if no network is explicitly chosen, `mainnet` is the default choice. For the Berkeley network, use `testnet`. ::: ```js const MainnetClient = new Client({ network: 'mainnet' }); // Specify mainnet const TestnetClient = new Client({ network: 'testnet' }); // Specify testnet (Berkeley) ``` ### Generating keys With Mina Signer, generating keypairs is straightforward. ```js const client = new Client({ network: 'mainnet' }); // Specify mainnet const keypair = client.genKeys(); // Generates a public and private keypair ``` ### Signing & Verifying Transactions Mina Signer facilitates both transaction and stake delegation signing and verification. To sign a transaction, the sender's private must be provided. Conversely, for verification, the sender's public key must be provided. Post-signing, the Mina Daemon can be utilized to broadcast the payment or delegation. #### Payments Payments are transactions that transfer funds from one account to another. To sign a payment, the following parameters must be provided: ```js const client = new Client({ network: 'mainnet' }); const keypair = client.genKeys(); const payment = client.signPayment( { to: keypair.publicKey, // Public key of the recipient from: keypair.publicKey, // Public key of the sender amount: '1', // Amount to be sent (in nano MINA) fee: '1', // Fee to be paid (in nano MINA) nonce: '0', // Nonce of the sender }, keypair.privateKey ); const verifiedPayment = client.verifyPayment(payment); ``` #### Delegations Stake delegations are a way for users to delegate their stake to a validator. This allows the validator to produce blocks on behalf of the delegator. To sign a stake delegation, the following parameters must be provided: ```js const client = new Client({ network: 'mainnet' }); const keypair = client.genKeys(); const delegation = client.signStakeDelegation( { to: keypair.publicKey, // Public key of the validator from: keypair.publicKey, // Public key of the delegator fee: '1', // Fee to be paid (in nano MINA) nonce: '0', // Nonce of the delegator }, keypair.privateKey ); const verifiedDelegation = client.verifyStakeDelegation(delegation); ``` #### Generic Signing Mina Signer can accept a generic payload and determine the most apt signing approach via `signTransaction()`. This functionality is especially beneficial for applications that support different types of transactions. ```js const client = new Client({ network: 'mainnet' }); const keypair = client.genKeys(); // Sign a payment client.signTransaction( { to: keypair.publicKey, from: keypair.publicKey, amount: '1', fee: '1', nonce: '0', }, keypair.privateKey ); // Sign a delegation client.signTransaction( { to: keypair.publicKey, from: keypair.publicKey, fee: '1', nonce: '0', }, keypair.privateKey ); // Sign a zkApp transaction client.signTransaction( { zkappCommand: ..., feePayer: ... }, keypair.privateKey ); // Sign a simple string payload client.signTransaction('Hello World', keypair.privateKey); ``` ### Broadcasting a Signed Payment After signing a payment, you can broadcast it to the network via a Mina Node GraphQL endpoint: ```javascript const client = new Client({ network: 'mainnet' }); const senderPrivateKey = 'EKFd1Gx...'; const senderPublicKey = 'B62qrDM...'; let payment = { from: senderPublicKey, to: 'B62qkBw...', amount: 100, nonce: 1, fee: 1000000, }; const signedPayment = client.signPayment(payment, senderPrivateKey); const url = 'https://your-mina-node/graphql'; const sendPaymentMutationQuery = ` mutation SendPayment($input: SendPaymentInput!, $signature: SignatureInput!) { sendPayment(input: $input, signature: $signature) { payment { hash } } } `; const graphQlVariables = { input: signedPayment.data, signature: signedPayment.signature, }; const body = JSON.stringify({ query: sendPaymentMutationQuery, variables: graphQlVariables, operationName: 'SendPayment', }); const paymentResponse = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body, }); const paymentResponseJson = await paymentResponse.json(); if (paymentResponse.ok) { console.log( `Transaction hash: ${paymentResponseJson.data.sendPayment.payment.hash}` ); } else { console.error(JSON.stringify(paymentResponseJson)); } ``` ### Payment & Delegation Transaction Hashes In addition to signing/verifying payments/delegations for the Mina Protocol, Mina Signer allows you to compute the hash that will be used to identify the transaction on the blockchain. This is useful for applications that require the transaction hash before the transaction is broadcasted to the network. ```js const client = new Client({ network: 'mainnet' }); const keypair = client.genKeys(); const payment = client.signTransaction( { to: keypair.publicKey, from: keypair.publicKey, amount: '1', fee: '1', nonce: '0', }, keypair.privateKey ); const hashedPayment = client.hashPayment(payment); const delegation = client.signTransaction( { to: keypair.publicKey, from: keypair.publicKey, fee: '1', nonce: '0', }, keypair.privateKey ); const hashedDelegation = client.hashStakeDelegation(delegation); ``` ### Rosetta Integration For those developing with [Rosetta](https://www.rosetta-api.org/), Mina Signer provides an avenue to transform a signed Rosetta transaction into a Mina-compliant transaction, ready for broadcasting through the Mina Daemon. ```js const client = new Client({ network: 'mainnet' }); const signedRosettaTx = '...'; const signedGraphQLCommand = client.signedRosettaTransactionToSignedCommand(signedRosettaTx); ``` For detailed Rosetta usage including the offline signer CLI tool and `signRosettaTransaction`, see the [Mina Signer for Node Operators](/node-operators/mina-signer) documentation. ## o1js Integration Mina Signer can seamlessly integrate with [o1js](/zkapps/o1js), delivering an array of features for zkApps like: - zkApp transaction signing and verification - Field payload signing and verification - Nullifier generation ### Signing & Verifying zkApp transactions Mina Signer supports signing and verifying zkApp transactions. o1js itself can be used to sign zkApp transactions, but Mina Signer offers the ability to sign a zkApp transaction that can easily be broadcasted with a Mina Daemon. This can be very useful for wallet applications that want to support zkApps. ```js const client = new Client({ network: 'testnet' }); const keypair = client.genKeys(); const zkAppTransaction = await Mina.transaction(feePayerAddress, () => { // ... Interact with a zkApp inside this block to produce a zkApp transaction }); // Sign the zkApp transaction with Mina Signer const signedZkAppTransaction = client.signZkappCommand( { zkappCommand: JSON.parse(JSON.stringify(txn.transaction)), feePayer: { feePayer: keypair.publicKey, fee: '1', nonce: '0', memo: 'memo', }, }, keypair.privateKey ); // Verify the zkApp transaction with Mina Signer const verifiedZkAppTransaction = client.verifyZkappCommand( signedZkAppTransaction ); ``` Firstly, when supplying the input parameters for `signZkappCommand()`, we must first parse the zkApp transaction into a string and then into a JSON object. This is because the types generated from `Mina.transaction()` are not compatible with the types used by Mina Signer. Secondly, we specify the `feePayer` object which contains the public key of the fee payer, the fee to be paid, the nonce of the fee payer, and the memo of the transaction. The `feePayer` object is used to sign the zkApp transaction. :::tip Use o1js to sign zkApp transactions if you can, as it's more ergonomic and easier to use. Only use `Mina Signer` if you need to sign zkApp transactions offline and broadcast at a later time (e.g. wallet software). ::: ### Signing/Verifying Field payloads Mina Signer can sign and validate Field payloads. This is invaluable when ensuring a Field payload's authenticity, as it confirms the payload remains untampered by external parties. ```js const client = new Client({ network: 'testnet' }); const keypair = client.genKeys(); const fields = [10n, 20n, 30n, 340817401n, 2091283n, 1n, 0n]; const signedFields = client.signFields(fields, keypair.privateKey); const verifiedFields = client.verifyFields(signedFields); ``` If you are using o1js to generate Field payloads, you must convert the Fields to BigInts before signing/verifying them. In Mina Signer, the Field type is a BigInt (while in o1js they are a separate data structure), so you must convert the fields from o1js to BigInts before signing/verifying them. ```js const client = new Client({ network: 'testnet' }); const keypair = client.genKeys(); const fields = [Field(10), Field(20)].map((f) => f.toBigInt()); const signedFields = client.signFields(fields, keypair.privateKey); const verifiedFields = client.verifyFields(signedFields); ``` ### Nullifiers Mina Signer supports generating nullifiers for zkApp transactions. In the world of cryptography, nullifiers play a pivotal role. They stand as unique markers, maintaining anonymity yet ensuring account reliability, and staving off illicit undertakings like double-spends. To generate a nullifier, provide a message (an array of BigInts) and the sender's private key. ```js const client = new Client({ network: 'testnet' }); const keypair = client.genKeys(); const message = [10n, 20n, 30n, 340817401n, 2091283n, 1n, 0n]; const nullifier = client.createNullifier(message, keypair.privateKey); ``` --- url: /network-upgrades/berkeley/appendix --- # Appendix ## Migration from o1labs/client-sdk to mina-signer The signing library `o1labs/client-sdk` was deprecated some time ago and will stop working after the Mina mainnet upgrade. All users should upgrade to use the [mina-signer](https://www.npmjs.com/package/mina-signer) library. Below you will find an example of how to use the `mina-signer` library. Please keep in mind the following: 1. Make sure to adjust the `nonce` to the correct nonce on the account you want to use as "sender" 1. Update the `url` variable with an existing Mina Node GraphQL endpoint ```javascript // create the client and define the keypair const client = new Client({ network: 'testnet' }); // Mind the `network` client configuration option const senderPrivateKey = 'EKFd1Gx...'; // Sender's private key const senderPublicKey = 'B62qrDM...'; // Sender's public key, perhaps derived from the private key using `client.derivePublicKey(senderPrivateKey)`; // define and sign payment let payment = { from: senderPublicKey, to: 'B62qkBw...', // Recipient public key amount: 100, nonce: 1, fee: 1000000, }; const signedPayment = client.signPayment(payment, senderPrivateKey); // send payment to graphql endpoint const url = 'https://qanet.minaprotocol.network/graphql'; const sendPaymentMutationQuery = ` mutation SendPayment($input: SendPaymentInput!, $signature: SignatureInput!) { sendPayment(input: $input, signature: $signature) { payment { hash } } } `; const graphQlVariables = { input: signedPayment.data, signature: signedPayment.signature, }; const body = JSON.stringify({ query: sendPaymentMutationQuery, variables: graphQlVariables, operationName: 'SendPayment', }); const paymentResponse = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body }); const paymentResponseJson = await paymentResponse.json(); if (paymentResponse.ok) { console.log(`Transaction hash: ${paymentResponseJson.data.sendPayment.payment.hash}`); } else { console.error(JSON.stringify(paymentResponseJson)); } ``` --- url: /network-upgrades/berkeley/archive-migration/appendix --- # Appendix ## Archive node schema changes If you are using the Archive Node database directly for your system integrations, then you should understand all the changes that might impact your applications. The most important change is that the `balances` table in the Berkeley schema will no longer exist. In the new schema, it is replaced with the table `accounts_accessed` - from an application semantics point of view, the data in `accounts_accessed` is still the same. In the Berkeley protocol, accounts can now have the same public key but a different token_id. This means accounts are identified by both their public key and token_id, not just the public key. Consequently, the foreign key for the account in all tables is account_identifier_id instead of public_key_id. ### Schema differences - **Removed Types** - The options `create_token`, `create_account`, and `mint_tokens` have been removed from the user_command_type enumeration. - Indexes Dropped - We've removed several indexes from tables, this may affect how you search and organize data: - `idx_public_keys_id` - `idx_public_keys_value` - `idx_snarked_ledger_hashes_value` - `idx_blocks_id` - `idx_blocks_state_hash` - **Table Removed** - The `balances` table is no longer available. - **New Tables Added** - We've introduced the following new tables: - `tokens` - `token_symbols` - `account_identifiers` - `voting_for` - `protocol_versions` - `accounts_accessed` - `accounts_created` - `zkapp_commands` - `blocks_zkapp_commands` - `zkapp_field` - `zkapp_field_array` - `zkapp_states_nullable` - `zkapp_states` - `zkapp_action_states` - `zkapp_events` - `zkapp_verification_key_hashes` - `zkapp_verification_keys` - `zkapp_permissions` - `zkapp_timing_info` - `zkapp_uris` - `zkapp_updates` - `zkapp_balance_bounds` - `zkapp_nonce_bounds` - `zkapp_account_precondition` - `zkapp_accounts` - `zkapp_token_id_bounds` - `zkapp_length_bounds` - `zkapp_amount_bounds` - `zkapp_global_slot_bounds` - `zkapp_epoch_ledger` - `zkapp_epoch_data` - `zkapp_network_precondition` - `zkapp_fee_payer_body` - `zkapp_account_update_body` - `zkapp_account_update` - `zkapp_account_update_failures` - **Updated Tables** - The following tables have been updated - `timing_info` - `user_commands` - `internal_commands` - `epoch_data` - `blocks` - `blocks_user_commands` - `blocks_internal_commands` ### Differences per table - **`timing_info`** - Removed columns: - `token` - `initial_balance` - **`user_commands`** - Removed columns: - `fee_token` - `token` - **`internal_commands`** - Removed columns: - `token` - Renamed column - `command_type` to `type` - **`epoch_data`** - Added columns: - `total_currency` - `start_checkpoint` - `lock_checkpoint` - `epoch_length` - **`blocks`** - Added columns: - `last_vrf_output` - `min_window_density` - `sub_window_densities` - `total_currency` - `global_slot_since_hard_fork` - `global_slot_since_genesis` - `protocol_version_id` - `proposed_protocol_version_id` - Removed column: - `global_slot` - **`blocks_user_commands`** - Removed columns: - `fee_payer_account_creation_fee_paid` - `receiver_account_creation_fee_paid` - `created_token` - `fee_payer_balance` - `source_balance` - `receiver_balance` - Added index: - `idx_blocks_user_commands_sequence_no` - **`blocks_internal_commands`** - Removed columns: - `receiver_account_creation_fee_paid` - `receiver_balance` - Added indexes: - `idx_blocks_internal_commands_sequence_no` - `idx_blocks_internal_commands_secondary_sequence_no` ### Rosetta API new operations The Berkeley upgrade introduces two new operation types: - `zkapp_fee_payer_dec` - `zkapp_balance_change` --- url: /network-upgrades/berkeley/archive-migration/archive-migration-installation --- The archive node Berkeley migration package is sufficient for satisfying the migration from Devnet/Mainnet to Berkeley. However, it has some limitations. For example, the migration package does not migrate a non-canonical chain and it skips orphaned blocks that are not part of a canonical chain. To mitigate these limitations, the archive node maintenance package is available for use by archive node operators who want to maintain a copy of their Devnet and Mainnet databases for historical reasons. ## Install with Google Cloud SDK The Google Cloud SDK installer does not always register a `google-cloud-sdk` apt package. The best way to install gsutil is using the apt repostory: ```sh curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list sudo apt-get update && sudo apt-get install google-cloud-sdk ``` ## Download the o1labs Mainnet archive database We strongly encourage you to perform the migration on your own data to preserve the benefits of decentralization. However, if you want to use the archive data that o1labs runs (for example, to bootstrap a new archive from SQL without waiting all day for the chain to download and replay), you can use the following steps: 1. Download the Devnet/Mainnet archive data using cURL or gsutil: - cURL: For Devnet: ```sh curl https://storage.googleapis.com/mina-archive-dumps/devnet-archive-dump-{date}_0000.sql.tar.gz ``` For Mainnet: ```sh curl https://storage.googleapis.com/mina-archive-dumps/mainnet-archive-dump-{date}_0000.sql.tar.gz ``` To filter the dumps by date, replace `{date}` using the required `yyyy-dd-mm` format. For example, for March 15, 2024, use `2024-03-15`. :warning: The majority of backups have the `0000` suffix. If a download with that name suffix is not available, try incrementing it. For example, `0001`, `0002`, and so on. - gsutil: ```sh gsutil cp gs://mina-archive-dumps/mainnet-archive-dump-2024-01-15* . ``` 2. Extract the tar package. ```sh tar -xvzf {network}-archive-dump-{date}_0000.sql.tar.gz {network}-archive-dump-{date}_0000.sql ``` 3. Import the Devnet/Mainnet archive dump into the Berkeley database. Run this command at the database server: ```sh psql -U {user} -f {network}-archive-dump-{date}_0000.sql ``` The database in the dump **archive_balances_migrated** is created with the Devnet/Mainnet archive schema. Note: This database does not have any Berkeley changes. ## Ensure the location of Google Cloud bucket with the Devnet/Mainnet precomputed blocks The recommended method is to perform migration on your own data to preserve the benefits of decentralization. `gsutil cp gs://mina_network_block_data/{network}-*.json .` :warning: Precomputed blocks for the Mainnet network take ~800 GB of disk space. Plan for adequate time to download these blocks. The Berkeley migration app downloads them incrementally only when needed. ## Validate the Devnet/Mainnet database The correct Devnet/Mainnet database state is crucial for a successful migration. [Missing blocks](/network-upgrades/berkeley/archive-migration/mainnet-database-maintenance#missing-blocks) is one the most frequent issues when dealing with the Devnet/Mainnet archive. Although this step is optional, it is strongly recommended that you verify the archive condition before you start the migration process. To learn how to maintain archive data, see [Devnet/Mainnet database maintenance](/network-upgrades/berkeley/archive-migration/mainnet-database-maintenance). ## Download the migration applications Migration applications are distributed as part of the archive migration Docker and Debian packages. Choose the packages that are appropriate for your environment. ### Debian packages To get the Debian packages: ``` CODENAME=bullseye CHANNEL=stable VERSION=3.0.1-e848ecb echo "deb [trusted=yes] http://packages.o1test.net $CODENAME $CHANNEL" | tee /etc/apt/sources.list.d/mina.list apt-get update apt-get install --allow-downgrades -y "mina-archive-migration=$VERSION" ``` ### Docker image To get the Docker image: ``` docker pull gcr.io/o1labs-192920/mina-archive-migration:3.0.1-e848ecb-{codename} ``` Where supported codenames are: - bullseye - focal - buster ## Devnet/Mainnet genesis ledger The Mina Devnet/Mainnet genesis ledger is stored in GitHub in the `mina` repository under the `genesis_ledgers` subfolder. However, if you are already running a daemon that is connected to the Mina Mainnet or the Devnet network, you already have the genesis ledger locally. ## Berkeley database schema files You can get the Berkeley schema files from different locations: - GitHub repository from the `berkeley` branch. Note: The `berkeley` branch can contain new updates regarding schema files, so always get the latest schema files instead of using an already downloaded schema. - Archive/Rosetta Docker from `berkeley` version ### Example: Downloading schema sources from GitHub ```sh wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/zkapp_tables.sql wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/create_schema.sql ``` ## Next steps Congratulations on completing the essential preparation and verification steps. You are now ready to perform the migration steps in [Migrating Devnet/Mainnet Archive to Berkeley Archive](/network-upgrades/berkeley/archive-migration/migrating-archive-database-to-berkeley). --- url: /network-upgrades/berkeley/archive-migration/archive-migration-prerequisites --- To successfully migrate the archive database into the Berkeley version of the Mina network, you must ensure that your environment meets the foundational requirements. ## Migration host - PostgreSQL database for database server - If you use Docker, then any of the supported OS by Mina (bullseye, focal, or buster) with at least 32 GB of RAM - gsutil application from Google Cloud Suite in version 5 or later - (Optional) Docker in version 23.0 or later ## (Optional) Devnet/Mainnet database One of the most obvious prerequisites is a Mainnet database. If you don't have an existing database with Devnet/Mainnet archive data, you can always download it from the Google Cloud bucket. However, we strongly encourage you to perform migration on your own data to preserve the benefits of decentralization. You can use any gsutil-compatible alternative to Google Cloud or a gsutil wrapper program. ## (Optional) Google Cloud bucket with Devnet/Mainnet precomputed blocks Precomputed blocks are the JSON files that a correctly configured node updloads to the Google Cloud bucket. The Devnet/Mainnet to Berkeley archive data migration requires access to precomputed blocks that are uploaded by daemons that are connected to the Devnet or Mainnet networks. The **berkeley-migration** app uses the gsutil app to download blocks. If you didn't store precomputed blocks during the first phase of migration, you can use the precomputed blocks provided by Mina Foundation. However, it is strongly recommended that you perform migration on your own data to preserve the benefits of decentralization. For Devnet blocks: ```sh gsutil cp gs://mina_network_block_data/devnet-*.json . ``` For Mainnet blocks: ```sh gsutil cp gs://mina_network_block_data/mainnet-*.json . ``` :warning: Precomputed blocks for the Mainnet network take ~800 GB of disk space. Plan for adequate time to download these blocks. The Berkeley migration app downloads them incrementally only when needed. You can instead download a 100 GB bundle of only the canonical Mainnet blocks that unpacks into ~220 GB: ```sh gsutil cp gs://mina_network_block_data/mainnet-bundle-2024-03-20.tar.zst . ; tar -xf mainnet-bundle-2024-03-20.tar.zst ``` :warning: Precomputed blocks for the Devnet network take several hundred GBs. Plan for adequate time to download these blocks. Instead, you can download a ~50 GB bundle of only the canonical Devnet blocks that unpacks into ~90 GB: ```sh gsutil cp gs://mina_network_block_data/devnet-bundle-3NKRsRWBzmPR8Z8ZmJb4u8FLpnSkjRitUpKZzVkHp11QuwP5i839.tar.gz . ; tar -xf devnet-bundle-3NKRsRWBzmPR8Z8ZmJb4u8FLpnSkjRitUpKZzVkHp11QuwP5i839.tar.gz ``` These bundles are partial. Updated documentation with the new links and final data will be provided _after_ the Berkeley major upgrade is completed. The best practice is to collect precomputed blocks by yourself or by other third parties to preserve the benefits of decentralization. --- url: /network-upgrades/berkeley/archive-migration/debian-example --- # Debian example You can follow these steps that can be copy-pasted directly into a fresh Debian 11. This example uses an altered two-step version of the [full simplified workflow](/network-upgrades/berkeley/archive-migration/migrating-archive-database-to-berkeley#simplified-approach). ```sh apt update && apt install lsb-release sudo postgresql curl wget gpg # debian:11 is surprisingly light curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list sudo apt-get update && sudo apt-get install google-cloud-sdk sudo rm /etc/apt/sources.list.d/mina*.list sudo echo "deb [trusted=yes] http://packages.o1test.net $(lsb_release -cs) unstable" | sudo tee /etc/apt/sources.list.d/mina.list sudo apt-get update && sudo apt-get install --allow-downgrades -y mina-archive-migration=3.0.0-rc1-4277e73 mkdir -p mina-migration-workdir cd mina-migration-workdir gsutil cp gs://mina_network_block_data/devnet-bundle-3NKRsRWBzmPR8Z8ZmJb4u8FLpnSkjRitUpKZzVkHp11QuwP5i839.tar.gz . tar -xf devnet-bundle-3NKRsRWBzmPR8Z8ZmJb4u8FLpnSkjRitUpKZzVkHp11QuwP5i839.tar.gz wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/create_schema.sql wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/zkapp_tables.sql # this next step is required only if you don't have an archive yet createdb devnet_balances_migrated createdb devnet_really_migrated psql -d devnet_really_migrated -f create_schema.sql gsutil cp gs://mina-archive-dumps/devnet-archive-dump-2024-03-22_0000.sql.tar.gz . tar -xf devnet-archive-dump-2024-03-22_0000.sql.tar.gz # the next step ensures you don't accidentally merge mainnet and devnet data sed -i -e s/archive_balances_migrated/devnet_balances_migrated/g devnet-archive-dump-2024-03-22_0000.sql psql -d devnet_balances_migrated -f devnet-archive-dump-2024-03-22_0000.sql mina-berkeley-migration-script initial \ --genesis-ledger /var/lib/coda/devnet.json \ --source-db postgres:///devnet_balances_migrated \ --target-db postgres:///devnet_really_migrated \ --blocks-batch-size 100 --blocks-bucket mina_network_block_data \ --network devnet # now, do a final migration gsutil cp gs://mina-archive-dumps/devnet-archive-dump-2024-03-22_2050.sql.tar.gz . tar -xf devnet-archive-dump-2024-03-22_2050.sql.tar.gz # the next step ensures you don't accidentally merge mainnet and devnet data sed -i -e s/archive_balances_migrated/devnet_balances_migrated/g devnet-archive-dump-2024-03-22_2050.sql psql -d devnet_balances_migrated -f devnet-archive-dump-2024-03-22_2050.sql curl -O https://gist.githubusercontent.com/ghost-not-in-the-shell/cfe629a15702e7bae7b0c1415fe0d85e/raw/8d8bff2814c1d0c15deb70b388dea8a28a485184/genesis.json mina-berkeley-migration-script final \ --genesis-ledger /var/lib/coda/devnet.json \ --source-db postgres:///devnet_balances_migrated \ --target-db postgres:///devnet_really_migrated \ --blocks-batch-size 100 --blocks-bucket mina_network_block_data \ --network devnet \ --replayer-checkpoint migration-checkpoint-437195.json \ --fork-state-hash 3NKoUJX87VrfmNAoUdqoWUykVvt66ztm5rzruDQR7ihwYaWsdJKq \ --fork-config genesis.json \ --prefetch-blocks ``` --- url: /network-upgrades/berkeley/archive-migration/docker-example --- # Docker example You can follow these steps that can be copy-pasted directly into a OS running Docker. This example performs a Mainnet initial migration following the [debian-example](/network-upgrades/berkeley/archive-migration/debian-example) ```sh # Create a new directory for the migration data mkdir $(pwd)/mainnet-migration && cd $(pwd)/mainnet-migration # Create Network docker network create mainnet # Launch Local Postgres Database docker run --name postgres -d -p 5432:5432 --network mainnet -v $(pwd)/mainnet-migration/postgresql/data:/var/lib/postgresql/data -e POSTGRES_USER=mina -e POSTGRES_PASSWORD=minamina -d postgres:13-bullseye export PGHOST="localhost" export PGPORT=5432 export PGUSER="mina" export PGPASSWORD="minamina" # Drop DBs if they exist psql -c "DROP DATABASE IF EXISTS mainnet_balances_migrated;" psql -c "DROP DATABASE IF EXISTS mainnet_really_migrated;" # Create DBs psql -c "CREATE DATABASE mainnet_balances_migrated;" psql -c "CREATE DATABASE mainnet_really_migrated;" # Retrieve Archive Node Backup wget https://storage.googleapis.com/mina-archive-dumps/mainnet-archive-dump-2024-04-29_0000.sql.tar.gz tar -xf mainnet-archive-dump-2024-04-29_0000.sql.tar.gz # Replace the database name in the dump sed -i -e s/archive_balances_migrated/mainnet_balances_migrated/g mainnet-archive-dump-2024-04-29_0000.sql psql mainnet_balances_migrated -f mainnet-archive-dump-2024-04-29_0000.sql # Prepare target wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/create_schema.sql wget https://raw.githubusercontent.com/MinaProtocol/mina/berkeley/src/app/archive/zkapp_tables.sql psql mainnet_really_migrated -f create_schema.sql # Start migration docker create --name mainnet-db-migration \ -v $(pwd)/mainnet-migration:/data \ --network mainnet minaprotocol/mina-archive-migration:3.0.1-e848ecb-bullseye -- bash -c ' wget http://673156464838-mina-genesis-ledgers.s3-website-us-west-2.amazonaws.com/mainnet/genesis_ledger.json; mina-berkeley-migration-script initial \ --genesis-ledger genesis_ledger.json \ --source-db postgres://mina:minamina@postgres:5432/mainnet_balances_migrated \ --target-db postgres://mina:minamina@postgres:5432/mainnet_really_migrated \ --blocks-batch-size 5000 \ --blocks-bucket mina_network_block_data \ --checkpoint-output-path /data/checkpoints/. \ --precomputed-blocks-local-path /data/precomputed_blocks/. \ --network mainnet' docker start mainnet-db-migration docker logs -f mainnet-db-migration ``` --- url: /network-upgrades/berkeley/archive-migration --- # Archive Migration The Berkeley upgrade is a major upgrade that requires all nodes in a network to upgrade to a newer version. It is not backward compatible. A major upgrade occurs when there are major changes to the core protocol that require all nodes on the network to update to the latest software. ## How to prepare for the Berkeley upgrade The Berkeley upgrade requires upgrading all nodes, including archive nodes. One of the required steps is to migrate archive databases from the current Mainnet format to Berkeley. This migration requires actions and efforts from node operators and exchanges. Learn about the archive data migration: - [Understanding the migration process](/network-upgrades/berkeley/archive-migration/understanding-archive-migration) - [Prerequisites before migration](/network-upgrades/berkeley/archive-migration/archive-migration-prerequisites) - [Suggested installation procedure](/network-upgrades/berkeley/archive-migration/archive-migration-installation) - [How to perform archive migration](/network-upgrades/berkeley/archive-migration/migrating-archive-database-to-berkeley) Finally, see the shell script example that is compatible with a stock Debian 11 container: - [Worked Devnet Debian example using March 22 data](/network-upgrades/berkeley/archive-migration/debian-example) - [Worked Mainnet Docker example using April 29 data](/network-upgrades/berkeley/archive-migration/docker-example) ## What will happen with original Devnet/Mainnet data After the migration, you will have two databases: - The original Devnet/Mainnet database with small data adjustments (all pending blocks from last canoncial block until the fork block are converted to canoncial blocks) - A new Berkeley database based on Devnet/Mainnet data, but: - Without Devnet/Mainnet orphaned blocks - Without pending blocks that are not in the canonical chain - With all pending blocks on the canonical chain converted to canonical blocks There is no requirement to preserve the original Devnet/Mainnet database after migration. However, if for some reason you want to keep the Mainnet orphaned or non-canonical pending blocks, you can download the archive maintenance package for the Devnet/Mainnet database. To learn about maintaining archive data, see [Devnet/Mainnet database maintenance](/network-upgrades/berkeley/archive-migration/mainnet-database-maintenance). --- url: /network-upgrades/berkeley/archive-migration/mainnet-database-maintenance --- # Devnet/Mainnet database maintenance After the Berkeley migration, the original Devnet/Mainnet database is not required unless you are interested in preserving some aspect of the database that is lost during the migration process. Two databases exist after the successful migration: - The original Devnet/Mainnet database with small data adjustments: - All pending blocks from last canoncial block until the fork block are converted to canonical blocks - A new Berkeley database based on Devnet/Mainnet data with these differences: - Without Devnet/Mainnet orphaned blocks - Without pending blocks that are not in the canonical chain - With all pending blocks on the canonical chain converted to canonical blocks The o1Labs and Mina Foundation teams have consistently prioritized rigorous testing and the delivery of high-quality software products. However, being human entails the possibility of making mistakes. ## Known issues Recently, a few mistakes were identified while working on a version of Mina used on Mainnet. These issues were promptly addressed; however, within the decentralized environment, archive nodes can retain historical issues despite our best efforts. Fixes are available for the following known issues: - **Missing or invalid nonces** - a historical issue skewed nonces in the `balances` table. Although the issue was resolved, you might still have nonces that are missing or invalid. - **Incorrect ledger hashes** - a historical issue with the same root cause as 'Missing or invalid nonces'. However, the outcome is that a 'replayer run' operation of validating archive node against daemon ledger shows ledger mismatches and cannot pass problematic blocks. - **Missing blocks** - This recurring missing blocks issue consistently poses challenges and is a source of concern for all archive node operators. This persistent challenge from disruptions in daemon node operations can potentially lead to incomplete block reception by archive nodes. This situation can compromise chain continuity within the archive database. To address these issues, install and use the special archive node maintenance package that includes fixes. ## Installing the archive node maintenance package The package provides support for codenames: - bullseye - buster - focal The following steps describe only the bullseye package installation. Modify the steps as appropriate for your environment. ### Debian packages To get the Debian package: ```sh CODENAME=bullseye CHANNEL=stable VERSION=1.4.1 echo "deb [trusted=yes] http://packages.o1test.net $CODENAME $CHANNEL" | tee /etc/apt/sources.list.d/mina.list apt-get update apt-get install --allow-downgrades -y "mina-archive-maintenance=$VERSION" ``` ### Docker image To get the Docker image: ```sh docker pull minaprotocol/mina-archive-maintenance:1.4.1-060f0a5-bullseye ``` ## Usage for missing or invalid nonces The replayer application was developed to verify the Devnet/Mainnet archive data. You must run the replayer application against your existing Devnet/Mainnet database to verify the blockchain state. To run the replayer application: ```sh mina-replayer \ --archive-uri {db_connection_string} \ --input-file reference_replayer_input.json \ --output-file replayer_input_file.json \ --checkpoint-interval 10000 \ --fix-nonces \ --set-nonces \ --dump-repair-script ``` where: - `archive-uri` - connection string to the archive database - `input-file` - JSON file that holds the archive database - `output-file` - JSON file that will hold the ledger with auxiliary information, like global slot and blockchain height, which will be dumped on the last block - `checkpoint-interval` - frequency of checkpoints expressed in blocks count - `replayer_input_file.json` - JSON file constructed from the Devnet/Mainnet genesis ledger: ```sh jq '.ledger.accounts' genesis_ledger.json | jq '{genesis_ledger: {accounts: .}}' > replayer_input_config.json ``` - `--fix-nonces` - adjust nonces values while replaying transactions - `--set-nonces` - set missing nonces while replaying transactions - `--dump-repair-script` - path to the output SQL script that will contain all updates to nonces made during the replayer run that can be directly applied to other database instances that contain the same data with invalid nonces Running a replayer from scratch on a Devnet/Mainnet database can take up to a couple of days. The recommended best practice is to break the replayer into smaller parts by using the checkpoint capabilities of the replayer. Additionally, running the replayer can exert significant demands on system resources that potentially affect the performance of the archive node. Because of the large resource requirements, we recommend that you execute the replayer in isolation from network connections, preferably within an isolated environment where the Devnet/Mainnet dumps can be imported. ## Bad ledger hashes There is no ultimate fix for this issue because preserving historical ledger hashes is essential to the overall security of the Mina network. Even with this issue, you can validate archive data integrity. The replayer application has a built-in mechanism to skip errors when the `--continue-on-error` flag is enabled. However, instead of skipping only blocks with bad ledger hashes, this mode skipped all of the problems with integrity. With the new archive node maintenance package, you can run the replayer application without a special flag and to correctly handle the bad ledger hashes issue. To run replayer: ```sh mina-replayer --archive-uri {db_connection_string} --input-file reference_replayer_input.json --output-file reference_replayer_output.json --checkpoint-interval 10000 ``` where: - `archive-uri` - connection string to the archive database - `input-file` - JSON file that holds the archive database - `output-file` - JSON file that will hold the ledger with auxiliary information, like global slot and blockchain height, which will be dumped on the last block - `checkpoint-interval` - frequency of checkpoints expressed in blocks count - `replayer_input_file.json` - JSON file constructed from the Devnet/Mainnet genesis ledger: ``` jq '.ledger.accounts' genesis_ledger.json | jq '{genesis_ledger: {accounts: .}}' > replayer_input_config.json ``` :warning: Running a replayer from scratch on a Devnet/Mainnet database can take up to a couple of days. The recommended best practice is to break the replayer into smaller parts by using the checkpoint capabilities of the replayer. :warning: You must run the replayer using the Mainnet version. You can run it from the Docker image at `minaprotocol/mina-archive:3.1.0-ae112d3-bullseye`. ## Missing blocks The daemon node unavailability can cause the archive node to miss some of the blocks. This recurring missing blocks issue consistently poses challenges. To address this issue, you can reapply missing blocks. If you uploaded the missing blocks to Google Cloud, the missing blocks can be reapplied from precomputed blocks to preserve chain continuity. 1. To automatically verify and patch missing blocks, use the [download-missing-blocks.sh](https://github.com/MinaProtocol/mina/blob/berkeley/scripts/archive/download-missing-blocks.sh) script. The `download-missing-blocks` script uses `localhost` as the database host so the script assumes that psql is running on localhost on port 5432. Modify `PG_CONN` in `download_missing_block.sh` for your environment. 1. Install the required `mina-archive-blocks` and `mina-missing-blocks-auditor` scripts that are packed in the `minaprotocol/mina-archive:3.1.0-ae112d3-bullseye` Docker image. 1. Export the `BLOCKS_BUCKET`: ```sh export BLOCKS_BUCKET="https://storage.googleapis.com/my_bucket_with_precomputed_blocks" ``` 1. Run the `mina-missing-blocks-auditor` script from the database host: For Devnet: ```sh download-missing-blocks.sh devnet {db_user} {db_password} ``` For Mainnet: ```sh download-missing-blocks.sh mainnet {db_user} {db_password} ``` ### Using precomputed blocks from O1labs bucket O1labs maintains a Google bucket containing precomputed blocks from Devnet and Mainnet, accessible at https://storage.googleapis.com/mina_network_block_data/. Note: It's important to highlight that precomputed blocks for **Devnet** between heights `2` and `1582` have missing fields or incorrect transaction data. Utilizing these blocks to patch your Devnet archive database will result in failure. For those who rely on precomputed blocks from this bucket, please follow the outlined steps: 1. Download additional blocks from `gs://mina_network_block_data/devnet-extensional-bundle.tar.gz`. 2. Install the necessary `mina-archive-blocks` script contained within the `minaprotocol/mina-archive:3.1.0-ae112d3-bullseye` Docker image. 3. Execute mina-archive-blocks to import the extracted blocks from step 1 using the provided command: ```sh mina-archive-blocks --archive-uri --extensional ./extensional/* ``` 4. Proceed with patching your Devnet database with blocks having heights other than `2` to `1582` using the available precomputed blocks. ## Next steps Now that you have completed the steps to properly maintain the correctness of the archive database, you are ready to perform the archive [migration process](/network-upgrades/berkeley/archive-migration/migrating-archive-database-to-berkeley). --- url: /network-upgrades/berkeley/archive-migration/migrating-archive-database-to-berkeley --- # Migrating Devnet/Mainnet Archive to Berkeley Archive Before you start the process to migrate your archive database from the current Mainnet or Devnet format to Berkeley, be sure that you: - [Understand the Archive Migration](/network-upgrades/berkeley/archive-migration/understanding-archive-migration) - Meet the foundational requirements in [Archive migration prerequisites](/network-upgrades/berkeley/archive-migration/archive-migration-prerequisites) - Have successfully installed the [archive migration package](/network-upgrades/berkeley/archive-migration/archive-migration-installation) ## Migration process The Devnet/Mainnet migration can take up to a couple of days. Therefore, you can achieve a successful migration by using three stages: - **Stage 1:** Initial migration - **Stage 2:** Incremental migration - **Stage 3:** Remainder migration Each stage has three migration phases: - **Phase 1:** Copying data and precomputed blocks from Devnet/Mainnet database using the **berkeley_migration** app. - **Phase 2:** Populating new Berkeley tables using the **replayer app in migration mode** - **Phase 3:** Additional validation for migrated database Review these phases and stages before you start the migration. ## Simplified approach For convenience, use the `mina-berkeley-migration-script` app if you do not need to delve into the details of migration or if your environment does not require a special approach to migration. ### Stage 1: Initial migration ``` mina-berkeley-migration-script \ initial \ --genesis-ledger ledger.json \ --source-db postgres://postgres:postgres@localhost:5432/source \ --target-db postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --blocks-batch-size 500 \ --checkpoint-interval 10000 \ --checkpoint-output-path . \ --precomputed-blocks-local-path . \ --network NETWORK ``` where: `-g | --genesis-ledger`: path to the genesis ledger file `-s | --source-db`: connection string to the database to be migrated `-t | --target-db`: connection string to the database that will hold the migrated data `-b | --blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `-bs | --blocks-batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up the migration process. `-n | --network`: network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json`. `-c | --checkpoint-output-path`: path to folder for replayer checkpoint files `-i | --checkpoint-interval`: frequency of dumping checkpoint expressed in blocks count `-l | --precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location The command output is the `migration-replayer-XXX.json` file required for the next run. ### Stage 2: Incremental migration ``` mina-berkeley-migration-script \ incremental \ --genesis-ledger ledger.json \ --source-db postgres://postgres:postgres@localhost:5432/source \ --target-db postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --blocks-batch-size 500 \ --network NETWORK \ --checkpoint-output-path . \ --checkpoint-interval 10000 \ --precomputed-blocks-local-path . \ --replayer-checkpoint migration-checkpoint-XXX.json ``` where: `-g | --genesis-ledger`: path to the genesis ledger file `-s | --source-db`: connection string to the database to be migrated `-t | --target-db`: connection string to the database that will hold the migrated data `-b | --blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `-bs | --blocks-batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up migration process. `-n | --network`: network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json`. `-r | --replayer-checkpoint`: path to the latest checkpoint file `migration-checkpoint-XXX.json` `-c | --checkpoint-output-path`: path to folder for replayer checkpoint files `-i | --checkpoint-interval`: frequency of dumping checkpoint expressed in blocks count `-l | --precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location ### Stage 3: Remainder migration ``` mina-berkeley-migration-script \ final \ --genesis-ledger ledger.json \ --source-db postgres://postgres:postgres@localhost:5432/source \ --target-db postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --blocks-batch-size 500 \ --network NETWORK \ --checkpoint-output-path . \ --checkpoint-interval 10000 \ --precomputed-blocks-local-path . \ --replayer-checkpoint migration-checkpoint-XXX.json \ -fc fork-genesis-config.json ``` where: `-g | --genesis-ledger`: path to the genesis ledger file `-s | --source-db`: connection string to the database to be migrated `-t | --target-db`: connection string to the database that will hold the migrated data `-b | --blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `-bs | --blocks-batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up the migration process. `-n | --network`: network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json`. `-r | --replayer-checkpoint`: path to the latest checkpoint file `migration-checkpoint-XXX.json` `-c | --checkpoint-output-path`: path to folder for replayer checkpoint files `-i | --checkpoint-interval`: frequency of dumping checkpoint expressed in blocks count `-l | --precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location `-fc | --fork-config`: fork genesis config file is the new genesis config that is distributed with the new daemon and is published after the fork block is announced ## Advanced approach If the simplified berkeley migration script is, for some reason, not suitable for you, it is possible to run the migration using the **berkeley_migration** and **replayer** apps without an interface the script provides. ### Stage 1: Initial migration This first stage requires only the initial Berkeley schema, which is the foundation for the next migration stage. This schema populates the migrated database and creates an initial checkpoint for further incremental migration. - Inputs - Unmigrated Devnet/Mainnet database - Devnet/Mainnet genesis ledger - Empty target Berkeley database with the schema created, but without any content - Outputs - Migrated Devnet/Mainnet database to the Berkeley format from genesis up to the last canonical block in the original database - Replayer checkpoint that can be used for incremental migration #### Phase 1: Berkeley migration app run ``` mina-berkeley-migration \ --batch-size 1000 \ --config-file ledger.json \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --precomputed-blocks-local-path . \ --keep-precomputed-blocks \ --network NETWORK ``` where: `--batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up migration process. `--config-file`: path to the genesis ledger file `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data `--blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `--precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location `--keep-precomputed-blocks`: keep the precomputed blocks on-disk after the migration is complete `--network`: the network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` #### Phase 2: Replayer in migration mode run Replayer config must contain the Devnet/Mainnet ledger as the starting point. So first, you must prepare the replayer config file: ``` jq '.ledger.accounts' genesis_ledger.json | jq '{genesis_ledger: {accounts: .}}' > replayer_input_config.json ``` where: `genesis_ledger.json` is the genesis file from a daemon bootstrap on a particular network Then: ``` mina-migration-replayer \ --migration-mode \ --archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --input-file replayer_input_config.json \ --checkpoint-interval 10000 \ --checkpoint-output-folder . ``` where: `--migration-mode`: flag for migration `--archive-uri`: connection string to the database that will hold the migrated data `--input-file`: path to the replayer input file, see below on how's created `replayer_input_config.json`: is a file constructed out of network genesis ledger: ``` jq '.ledger.accounts' genesis_ledger.json | jq '{genesis_ledger: {accounts: .}}' > replayer_input_config.json ``` `--checkpoint-interval`: frequency of checkpoints file expressed in blocks count `--checkpoint-output-folder`: path to folder for replayer checkpoint files #### Phase 3: Validations Use the **berkeley_migration_verifier** app to perform checks for both the fully migrated and partially migrated databases. ``` mina-berkeley-migration-verifier \ pre-fork \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated ``` where: `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data ### Stage 2: Incremental migration After the initial migration, the data is migrated data up to the last canonical block. However, Devnet/Mainnet data is progressing with new blocks that must also be migrated again and again until the fork block is announced. :::info Incremental migration can, and probably must, be repeated a couple of times until the fork block is announced by Mina Foundation. Run the incremental migration multiple times with the latest Devnet/Mainnet database and the latest replayer checkpoint file. ::: - Inputs - Latest Devnet/Mainnet database - Devnet/Mainnet genesis ledger - Replayer checkpoint from last run - Migrated berkeley database from initial migration - Outputs - Migrated Devnet/Mainnet database to the Berkeley format up to the last canonical block - Replayer checkpoint which can be used for the next incremental migration ### Phase 1: Berkeley migration app run ``` mina-berkeley-migration \ --batch-size 1000 \ --config-file ledger.json \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --precomputed-blocks-local-path . \ --keep-precomputed-blocks \ --network NETWORK ``` where: `--batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up migration process. `--config-file`: path to the genesis ledger file `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data `--blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `--precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location `--keep-precomputed-blocks`: keep the precomputed blocks on-disk after the migration is complete `--network`: the network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` #### Phase 2: Replayer in migration mode run ``` mina-migration-replayer \ --migration-mode \ --archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --input-file replayer-checkpoint-XXX.json \ --checkpoint-interval 10000 \ --checkpoint-output-folder . ``` where: `--migration-mode`: flag for migration `--archive-uri`: connection string to the database that will hold the migrated data `--input-file`: path to the latest checkpoint file `replayer-checkpoint-XXX.json` `replayer-checkpoint-XXX.json`: the latest checkpoint generated from the previous migration `--checkpoint-interval`: frequency of checkpoints file expressed in blocks count `--checkpoint-output-folder`: path to folder for replayer checkpoint files Incremental migration can be run continuously on top of the initial migration or last incremental until the fork block is announced. #### Phase 3: Validations Use the **berkeley_migration_verifier** app to perform checks for both the fully migrated and partially migrated database. ``` mina-berkeley-migration-verifier \ pre-fork \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated ``` where: `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data Note that: you can run incremental migration continuously on top of the initial migration or the last incremental until the fork block is announced. ### Stage 3: Remainder migration When the fork block is announced, you must tackle the remainder migration. This is the last migration run you need to perform. In this stage, you close the migration cycle with the last migration of the remainder blocks between the current last canonical block and the fork block (which can be pending, so you don't need to wait 290 blocks until it would become canonical). You must use `--fork-state-hash` as an additional parameter to the **berkeley-migration** app. - Inputs - Latest Devnet/Mainnet database - Devnet/Mainnet genesis ledger - Replayer checkpoint from last run - Migrated Berkeley database from last run - Fork block state hash - Outputs - Migrated devnet/mainnet database to berkeley up to fork point - Replayer checkpoint which can be used for the next incremental migration :::info The migrated database output from this stage of the final migration is required to initialize your archive nodes on the upgraded network. ::: #### Phase 1: Berkeley migration app run ``` mina-berkeley-migration \ --batch-size 1000 \ --config-file ledger.json \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --blocks-bucket mina_network_block_data \ --precomputed-blocks-local-path \ --keep-precomputed-blocks \ --network NETWORK \ --fork-state-hash {fork-state-hash} ``` where: `--batch-size`: number of precomputed blocks to be fetched at one time from Google Cloud. A larger number, like 1000, can help speed up migration process. `--config-file`: path to the genesis ledger file `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data `--blocks-bucket`: name of the precomputed blocks bucket. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `--precomputed-blocks-local-path`: path to folder for on-disk precomputed blocks location `--keep-precomputed-blocks`: keep the precomputed blocks on-disk after the migration is complete `--network`: the network name (`devnet` or `mainnet`) when determining precomputed blocks. Precomputed blocks are assumed to be named with format: `{network}-{height}-{state_hash}.json` `--fork-state-hash`: fork state hash :::info When you run the **berkeley-migration** app with fork-state-hash, there is no requirement for the fork state block to be canonical. The tool automatically converts all pending blocks in the subchain, including the fork block, to canonical blocks. ::: #### Phase 2: Replayer in migration mode run ``` mina-migration-replayer \ --migration-mode \ --archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --input-file replayer-checkpoint-XXX.json \ --checkpoint-interval 10000 \ --checkpoint-output-folder . ``` where: `--migration-mode`: flag for migration `--archive-uri`: connection string to the database that will hold the migrated data `--input-file`: path to the latest checkpoint file `replayer-checkpoint-XXX.json` from stage 1 `replayer-checkpoint-XXX.json`: the latest checkpoint generated from the previous migration `--checkpoint-interval`: frequency of checkpoints file expressed in blocks count `--checkpoint-output-folder`: path to folder for replayer checkpoint files #### Phase 3: Validations Use the **berkeley_migration_verifier** app to perform checks for both the fully migrated and partially migrated databases. ``` mina-berkeley-migration-verifier \ post-fork \ --mainnet-archive-uri postgres://postgres:postgres@localhost:5432/source \ --migrated-archive-uri postgres://postgres:postgres@localhost:5432/migrated \ --fork-config-file fork_genesis_config.json \ --migrated-replayer-output replayer-checkpoint-XXXX.json ``` where: `--mainnet-archive-uri`: connection string to the database to be migrated `--migrated-archive-uri`: connection string to the database that will hold the migrated data `--migrated-replayer-output`: path to the latest checkpoint file `replayer-checkpoint-XXX.json` `--fork-config`: fork genesis config file is the new genesis config that is distributed with the new daemon and is published after the fork block is announced ### Example migration steps using Mina Foundation data for Devnet using Debian See: [Worked example using March 22 data](/network-upgrades/berkeley/archive-migration/debian-example) ### Example migration steps using Mina Foundation data for Mainnet using Docker See: [Worked example using March 22 data](/network-upgrades/berkeley/archive-migration/docker-example) ## How to verify a successful migration o1Labs and Mina Foundation make every effort to provide reliable tools of high quality. However, it is not possible to eliminate all errors and test all possible Mainnet archive variations. All important checks are implemented in the `mina-berkeley-migration-verifier` application. However, you can use the following checklist if you want to perform the checks manually: 1. All transaction (user command and internal command) hashes are left intact. Verify that the `user_command` and `internal_command` tables have the Devnet/Mainnet format of hashes. For example, `CkpZirFuoLVV...`. 2. Parent-child block relationship is preserved Verify that a given block in the migrated archive has the same parent in the Devnet/Mainnet archive (`state_hash` and `parent_hash` columns) that was used as input. 3. Account balances remain the same Verify the same balance exists for a given block in Mainnet and the migrated databases. ## Tips and tricks We are aware that the migration process can be very long (a couple of days). Therefore, we encourage you to use cron jobs that migrate data incrementally. The cron job requires access to Google Cloud buckets (or other storage): - A bucket to store migrated-so-far database dumps - A bucket to store checkpoint files We are tightly coupled with Google Cloud infrastructure due to the precomputed block upload mechanism. This is why we are using also buckets for storing dumps and checkpoint. However, you do not have to use Google Cloud for other things than precomputed blocks. With configuration, you can use any gsutil-compatible storage backend (for example, S3). Before running the cron job, upload an initial database dump and an initial checkpoint file. To create the files, run these steps locally: 1. Download a Devnet/Mainnet archive dump and load it into PostgreSQL. 2. Create an empty database using the new archive schema. 3. Run the **berkeley-migration** app against the Devnet/Mainnet and new databases. 4. Run the **replayer app in migration mode** with the `--checkpoint-interval` set to a suitable value (perhaps 100) and start with the original Devnet/Mainnet ledger in the input file. 5. Use pg_dump to dump the migrated database and upload it. 6. Upload the most recent checkpoint file. The cron job performs the same steps in an automated fashion: 1. Pulls the latest Devnet/Mainnet archive dump and loads it into PostgresQL. 2. Pulls the latest migrated database and loads it into PostgreSQL. 3. Pulls the latest checkpoint file. 4. Runs the **berkeley-migration** app against the two databases. 5. Runs the **replayer app in migration mode** using the downloaded checkpoint file; set the checkpoint interval to be smaller (perhaps 50) because there are typically only 200 or so blocks in a day. 7. Uploads the migrated database. 8. Uploads the most recent checkpoint file. Be sure to monitor the cron job for errors. Just before the Berkeley upgrade, migrate the last few blocks by running locally: 1. Download the Devnet/Mainnet archive data directly from the k8s PostgreSQL node (not from the archive dump), and load it into PostgreSQL. 2. Download the most recent migrated database and load it into PostgresQL. 3. Download the most recent checkpoint file. 4. Run the **berkeley-migration** app against the two databases. 5. Run the **replayer app in migration mode** using the most recent checkpoint file. It is worthwhile to perform these last steps as a dry run to make sure all goes well. You can run these steps as many times as needed. ## Known migration problems Please remember that rerunning after crash is always possible. After solving any of below issues you can rerun process and migration will continue form last position #### Async was unable to add a file descriptor to its table of open file descriptors For example: ``` ("Async was unable to add a file descriptor to its table of open file descriptors" (file_descr 18) (error "Attempt to register a file descriptor with Async that Async believes it is already managing.") (backtrace ...... ``` A remedy is to lower `--block-batch-size` parameter to values up to 500. #### Map.find_exn: not found For example: ``` (monitor.ml.Error (Not_found_s ("Map.find_exn: not found" .... ``` Usually this error means that there is a gap in canonical chain. In order to fix it please ensure that missing-block-auditor run is successful #### Yojson.Json_error .. Unexpected end of input For example: ``` (monitor.ml.Error ("Yojson.Json_error(\"Line 1, bytes 1003519-1003520:\\nUnexpected end of input\")") ("Raised at Yojson.json_error in file \"common.ml\", line 5, characters 19-39" "Called from Yojson.Safe.__ocaml_lex_read_json_rec in file \"lib/read.mll\", line 215, characters 28-52" ... ``` This issue is caused by invalid precomputed block. Deleting the downloaded precomputed blocks should resolve this issue. #### Error querying db, error: Request to ... failed: ERROR: column \"type\" does not exist You provided the migrated schema as source one when invoking script or berkeley-migration app #### Poor performance of migration when accessing remote database We conducted migration tests with both a local database and a distant database (RDS). The migration using the local database appears to process significantly faster. We strongly suggest to use offline database installed locally #### ERROR: out of shared memory ``` (monitor.ml.Error (Failure "Error querying for user commands with id 1686617, error Request to postgresql://user:pwd@host:port/db failed: ERROR: out of shared memory \nHINT: You might need to increase max_pred_locks_per_transaction ``` Solution is either to increase `max_pred_locks_per_transaction` setting in postgres database. Alternative is to isolate database from mainnet traffic (for example by exporting dump from live database and import it on isolated environment) #### Berkeley migration app is consuming all of my resources When running a full migration, you can stumble on memory leaks that prevent you from cleanly performing the migration in one pass. A machine with 64 GB of RAM can be frozen after ~40k migrated blocks. Each 200 blocks inserted into the database increases the memory leak by 4-10 MB. A potential workaround is to split the migration into smaller parts using cron jobs or automation scripts. ## FAQ ### Migrated database is missing orphaned blocks By design, Berkeley migration omits orphaned blocks and, by default, migrates only canonical (and pending, if setup correctly) blocks. ### Replayer in migration mode overrides my old checkpoints By default, the replayer dumps the checkpoint to the current folder. All checkpoint files have a similar format: `replayer-checkpoint-{number}.json.` To prevent override of old checkpoints, use the `--checkpoint-output-folder` and `--checkpoint-file-prefix` parameters to modify the output folder and prefix. --- url: /network-upgrades/berkeley/archive-migration/understanding-archive-migration --- # Understanding the Archive Migration You can reduce risks and effort by reading all of the archive documentation in entirety. ## Archive node migration overview Archive node migration is a crucial part of the Berkeley upgrade. The current Devnet and Mainnet database format must be converted to the Berkeley format to preserve historical data and assure archive node chain continuity. For this purpose, the o1Labs and Mina Foundation teams prepared a migration package. ### Archive node Berkeley migration package This package contains the required applications to migrate existing Devnet and Mainnet databases into the new Berkeley schema and a usability script: 1. **berkeley-migration** Use the **berkeley-migration** app to migrate as much data as possible from the Devnet/Mainnet database and download precomputed blocks to get the window density data. This app runs against the Devnet/Mainnet database and the new Berkeley database. 2. **replayer app in migration mode** The existing replayer application is enhanced with a new migration mode. Use the **replayer app in migration mode** to analyze the transactions in the partially migrated database (resulting from running berkeley-migration app) and populate the `accounts_accessed` and `accounts_created` tables. This app also does the checks performed by the standard replayer, but does not check ledger hashes because the Berkeley ledger has greater depth that results in different hashes. This app runs only against the new archive database. 3. **berkeley-migration-verifier** Use the **berkeley-migration-verifier** verification software to determine if the migration (even incomplete) was successful. The app uses SQL validations on the migrated database. 4. **end-to-end migration script** This shell script wraps all phases and stages of migration into a single script. It is provided purely for node operators usability and is equivalent of running the **berkely-migration** app, the **replayer app in migration mode**, and the **berkeley-migration-verifier** apps in the correct order. ### Incrementality Use the **berkeley-migration** and **replayer** apps incrementally so that you can migrate part of the Devnet/Mainnet database, and, as new blocks are added to the Devnet/Mainnet databases, the new data can be migrated. To obtain that incrementality, the **berkeley-migration** app looks at the migrated database and determines the most recent migrated block. It continues migration starting at the next block in the Devnet/Mainnet data. The **replayer app in migration mode** uses the checkpoint mechanism already in place for the replayer. A checkpoint file indicates the global slot since genesis for starting the replay and the ledger to use for that replay. New checkpoint files are written as it proceeds. To take advantage of the incrementality, run a cron job that migrates a day's worth of data at a time (or some other interval). With the cron job in place, at the time of the actual Berkeley upgrade, you will need to migrate only a small amount of data. --- url: /network-upgrades/berkeley/flags-configs --- # Post-Upgrade Flags and Configurations for Mainnet Please refer to the Berkeley node release notes [here](https://github.com/MinaProtocol/mina/releases/tag/3.0.3). ### Network details ``` Chain ID a7351abc7ddf2ea92d1b38cc8e636c271c1dfd2c081c637f62ebc2af34eb7cc1 Git SHA-1 ae112d3a96fe71b4ccccf3c54e7b7494db4898a4 Seed List https://bootnodes.minaprotocol.com/networks/mainnet.txt Node build https://github.com/MinaProtocol/mina/releases/tag/3.0.3 ``` ### Block Producer's Start your node post-upgrade in Mainnet with the flags and environment variables listed below. ``` mina daemon --block-producer-key --config-directory --file-log-rotations 500 --generate-genesis-proof true --libp2p-keypair --log-json --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt ENVIRONMENT VARIABLES RAYON_NUM_THREADS=6 MINA_LIBP2P_PASS MINA_PRIVKEY_PASS ``` ### SNARK Coordinator Configure your node post-upgrade in Mainnet with specific flags and environment variables as listed. ``` mina daemon --config-directory --enable-peer-exchange true --file-log-rotations 500 --libp2p-keypair --log-json --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt --run-snark-coordinator --snark-worker-fee 0.001 --work-selection [seq|rand|roffset] ENVIRONMENT VARIABLES MINA_LIBP2P_PASS ``` ### SNARK Workers Connect to a SNARK Coordinator node if required and run the following flags. ``` mina internal snark-worker --proof-level full --shutdown-on-disconnect false --daemon-address ENVIRONMENT VARIABLES RAYON_NUM_THREADS:8 ``` ### Archive Node Running an Archive Node involves setting up a non-block-producing node and a PostgreSQL database configured with specific flags and environment variables. For more information about running archive nodes, see [Archive Node](/node-operators/archive-node). The PostgreSQL database requires two schemas: 1. The PostgreSQL schema used by the Mina archive database: in the [release notes](https://github.com/MinaProtocol/mina/releases/tag/3.0.3) 2. The PostgreSQL schema extensions to support zkApp commands: in the [release notes](https://github.com/MinaProtocol/mina/releases/tag/3.0.3) The non-block-producing node must be configured with the following flags: ``` mina daemon --archive-address : --config-directory --enable-peer-exchange true --file-log-rotations 500 --generate-genesis-proof true --libp2p-keypair --log-json --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt ENVIRONMENT VARIABLES MINA_LIBP2P_PASS ``` This non-block-producing node connects to the archive node with the addresses and port specified in the `--archive-address` flag. The **archive node** command looks like this: ``` mina-archive run --metrics-port --postgres-uri postgres://:@
:/ --server-port 3086 --log-json --log-level DEBUG ``` ### Rosetta API Once you have the Archive Node stack up and running, start the Rosetta API Docker image with the following command: ``` docker run --name rosetta --rm \ -p 3088:3088 \ --entrypoint '' \ minaprotocol/mina-rosetta:3.1.0-ae112d3-bullseye-mainnet \ /usr/local/bin/mina-rosetta \ --archive-uri "${PG_CONNECTION_STRING}" \ --graphql-uri "${GRAPHQL_URL}" \ --log-json \ --log-level ${LOG_LEVEL} \ --port 3088 ``` --- url: /network-upgrades/berkeley/requirements --- # Requirements ## Hardware Requirements Please note the following are the hardware requirements for each node type after the upgrade: | Node Type | Memory | CPU | Storage | Network | |--|--|--|--|--| | Mina Daemon Node | 32 GB RAM | 8 core processor with BMI2 and AVX CPU instruction set are required | 64 GB | 1 Mbps Internet Connection | | SNARK Coordinator | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | SNARK Worker | 32 GB RAM | 4 core/8 threads per worker with BMI2 and AVX CPU instruction set are required | 64 GB | 1 Mbps Internet Connection | | Archive Node | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | Rosetta API standalone Docker image | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | Mina Seed Node | 64 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | ## Mina Daemon Requirements ### Installation :::caution If you have `mina-generate-keypair` installed, you will need to first `sudo apt remove mina-generate-keypair` before installing `mina-mainnet=3.1.0-ae112d3`. The `mina-generate-keypair` binary is now installed as part of the mina-mainnet package. ::: ### IP and Port configuration **IP:** By default, the Mina Daemon will attempt to retrieve its public IP address from the system. If you are running the node behind a NAT or firewall, you can set the `--external-ip` flag to specify the public IP address. **Port:** Nodes must expose a port publicly to communicate with other peers. Mina uses by default the port `8302` which is the default libp2p port. You can use a different port by setting the `--external-port` flag. ### Node Auto-restart Ensure your nodes are set to restart automatically after a crash. For guidance, refer to the [auto-restart instructions](/node-operators/validator-node/connecting-to-the-network#running-mina-node-as-a-service) ## Seed Peer Requirements ### Generation of libp2p keypair To ensure connectivity across the network, it is essential that all seed nodes start with the **same** `libp2p` keypair. This consistency allows other nodes in the network to reliably connect. Although the same libp2p keys can be reused from before the upgrade, if you need to manually generate new libp2p keys, use the following command: ``` mina libp2p generate-keypair --privkey-path ``` Further information on [generating key pairs](/node-operators/validator-node/generating-a-keypair) on Mina Protocol. --- url: /network-upgrades/berkeley/upgrade-steps --- # Upgrade Steps Mainnet Upgrade steps Below it's the description in detail of all the upgrade steps and what which node operator type should do to in each step. ## Pre-Upgrade - During the Pre-Upgrade phase, node operators should prepare for the upcoming upgrade. The most important steps are: - Review the [upgrade readiness checklist](https://docs.google.com/document/d/1rTmJvyaK33dWjJXMOSiUIGgf8z7turxolGHUpVHNxEU/edit#heading=h.2hqz0ixwjk3f) to confirm they have covered the required steps. - Upgrade their nodes to the 1.4.1 stable version - Ensure servers are provisioned to run Berkeley nodes, meeting the new hardware requirements - Upgrade their nodes to the node version [3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3), with stop-slots, when this version becomes available - Start the archive node initial migration if they run archive nodes and wish to perform the migration in a decentralized manner **Please note:** a simplified Node Status service will be part of the upgrade tooling and enabled by default in Pre-Upgrade release with the stop-slots ([3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3)). This feature will allow for a safe upgrade by monitoring the amount of upgraded active stake. Only non-sensitive data will be reported. If operators are not comfortable sharing their node version, they will have the option to disable the node version reports by using the appropriate node flag `--node-stats-type none` ### Block Producers and SNARK Workers 1. Review the [upgrade readiness checklist](https://docs.google.com/document/d/1rTmJvyaK33dWjJXMOSiUIGgf8z7turxolGHUpVHNxEU). 1. Provision servers that meet the minimum hardware requirements, including the new 32GB RAM requirement and support for _AVX_ and _BMI2_ CPU instructions. 1. Upgrade nodes to node version [3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3) ([3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3) has built-in stop slots). ### Archive Node Operators and Rosetta Operators - Two migration processes will be available to archive node operators: _trustless_ and _trustful_. If the archive node operator wants to perform the _trustless_ migration, they should follow these steps; otherwise, proceed to the Upgrade phase. The _trustful_ migration will rely on o1Labs database exports and Docker images to migrate the archive node database and doesn’t require any actions at this stage. 1. Trustless migration: - Perform the initial archive node migration. Since Mainnet is a long-lived network, the initial migration process can take up to 48 hours, depending on your server specification and infrastructure. - If your Mina Daemon, archive node, or PostgreSQL database runs on different machines, the migration performance will be greatly impacted. - For more information on the archive node migration process, please refer to the [Archive Migration](/network-upgrades/berkeley/archive-migration) section. 2. Upgrade all nodes to the latest stable version [3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3). 3. Provision servers that meet the minimum hardware requirements, primarily the new 32GB RAM requirement. 4. Upgrade their nodes to the version that includes built-in stop slots before the pre-defined _stop-transaction-slot_. ### Exchanges 1. Make sure to test your system integration with Berkeley's new features. Pay special attention to: - If you use the **o1labs/client-sdk** library to sign transactions, you should switch to **[mina-signer](https://www.npmjs.com/package/mina-signer)**. o1labs/client-sdk was **deprecated** some time ago and will be **unusable** once the network has been upgraded. Please review the migration instructions in [Appendix](/network-upgrades/berkeley/appendix). - If you rely on the archive node SQL database tables, please review the schema changes in Appendix 1 of this document. 2. Upgrade all nodes to the latest stable version [3.0.3](https://github.com/MinaProtocol/mina/releases/tag/3.0.3). 3. Provision servers that meet the minimum hardware requirements, particularly the new 32GB RAM requirement. 4. Upgrade your nodes to the version that includes built-in stop slots before the pre-defined _stop-transaction-slot_. *** ## State Finalization - Between the predefined _stop-transaction-slot_ and _stop-network-slot_, a stabilization period of 100 slots will occur. During this phase, the network consensus will not accept new blocks with transactions on them, including coinbase transactions. The state finalization period ensures all nodes reach a consensus on the latest network state before the upgrade. - During the state finalization slots, it is crucial to maintain a high block density. Therefore, block producers and SNARK workers shall continue running their nodes to support the network's stability and security. - Archive nodes should also continue to execute to ensure finalized blocks are in the database and can be migrated, preserving the integrity and accessibility of the network's history. ### Block Producers and SNARK Workers 1. It is crucial for the network's successful upgrade that all block producers and SNARK workers maintain their block-producing nodes up and running throughout the state finalization phase. 2. If you are running multiple daemons like is common with many operators, you can run one single node at this stage. 3. If you are a Delegation Program operator, remember that your uptime data will continue to be tracked during the state finalization phase and will be considered for the delegation grant in the following epoch. ### Archive Node Operators and Rosetta Operators **If you plan to do the _trustful_ migration, you can skip this step.** If you are doing the trustless migration, then: 1. Continue to execute the archive node to ensure finalized blocks are in the database and can be migrated. 2. Continue to run incremental archive node migrations until after the network stops at the stop-network slot. 3. For more information on the archive node migration process, please refer to the [Archive Migration](/network-upgrades/berkeley/archive-migration) section ### Exchanges Exchanges shall disable MINA deposits and withdrawals during the state finalization period (the period between _stop-transaction-slot_ and _stop-network-slot_) since any transactions after the _stop-transaction-slot_ will not be part of the upgraded chain. Remember that although you might be able to submit transactions, the majority of the block producers will be running a node that discards any blocks with transactions. *** ## Upgrade - Starting at the _stop-network-slot_ the network will not produce nor accept new blocks, resulting in halting the network. During the upgrade period, o1Labs will use automated tooling to export the network state based on the block at the slot just before the _stop-transaction-slot_. The exported state will then be baked into the new Berkeley build, which will be used to initiate the upgraded network. It is during the upgrade windows that the Berkeley network infrastructure will be bootstrapped, and seed nodes will become available. o1Labs will also finalize the archive node migration and publish the PostgreSQL database dumps for import by the archive node operators who wish to bootstrap their archives in a trustful manner. - There is a tool available to validate that the Berkeley node was built from the pre-upgrade network state. To validate, follow the instructions provided in this [location](https://github.com/MinaProtocol/mina/blob/berkeley/docs/upgrading-to-berkeley.md) ### Block Producers and SNARK Workers 1. During the upgrade phase (between _stop-network-slot_ and the publishing of the Berkeley release), block producers can shut down their nodes. 2. After the publication of the Berkeley node release, block producers and SNARK workers should upgrade their nodes and be prepared for block production at the genesis timestamp, which is the slot when the first Berkeley block will be produced. 3. It is possible to continue using the same libp2p key after the upgrade. Remember to adjust the new flag to pass the libp2p key to the node. ### Archive Node Operators and Rosetta Operators 1. Upon publishing the archive node Berkeley release, archive node operators and Rosetta operators should upgrade their systems. There will be both Docker images and archive node releases available to choose from. 2. Depending on the chosen migration method: - _Trustless_ - Operators should direct their Berkeley archive process to the previously migrated database. - _Trustful_ - Operators shall import the SQL dump file provided by o1Labs to a freshly created database. - Operators should direct their Berkeley archive process to the newly created database. **Please note:** both the _trustless_ and _trustful_ migration processes will discard all Mainnet blocks that are not canonical. If you wish to preserve the entire block history, i.e. including non-canonical blocks, you should maintain the Mainnet archive node database for posterior querying needs. ### Exchanges 1. Exchanges shall disable MINA deposits and withdrawals during the entirety of the upgrade downtime, since the _stop-transaction-slot_ until the Mainnet Berkeley network is operational. 2. After the Berkeley releases are published, exchanges should upgrade their nodes and prepare for the new network to start block production. *** ## Post-Upgrade - At approximately 1 hour after the publishing of the Berkeley node release, at a predefined slot (Berkeley genesis timestamp), block production will start, and the network is successfully upgraded. - Node operators can monitor their nodes and provide feedback to the technical team in case of any issues. Builders can start deploying zkApps. - **Please note:** The Node Status service will not be enabled by default in the Berkeley release. If you wish to provide Node Status and Error metrics and reports to Mina Foundation, helping monitor the network in the initial phase, please use the following flags when running your nodes: - `--node-stats-type [full|simple]` - `--node-status-url https://nodestats.minaprotocol.com/submit/stats` - `--node-error-url https://nodestats.minaprotocol.com/submit/stats` - The error collection service tries to report any node crashes before the node process is terminated ### Block Producers and SNARK Workers 1. Ensure that all systems have been upgraded and prepared for the start of block production. 2. Monitor nodes and network health, and provide feedback to the engineering team in case of any issues. ### Archive Node Operators and Rosetta Operators 1. Ensure that all systems have been upgraded and prepared for the start of block production. 2. Monitor nodes and network health, and provide feedback to the engineering team in case of any issues. ### Exchange and Builders 1. After the predefined Berkeley genesis timestamp, block production will commence, and MINA deposits and withdrawals can be resumed. 2. Ensure that all systems have been upgraded and prepared for the start of block production. 3. Monitor nodes and network health, and provide feedback to the engineering team in case of any issues. --- url: /network-upgrades --- # Network Upgrades Mina protocol evolves through network upgrades (hard forks) that introduce new features and improvements. Each upgrade requires node operators to update their software to remain compatible with the network. :::tip Mesa preflight hard fork completed The Mesa preflight network hard-forked at **2026-04-27 13:00 UTC**. The post-fork chain is now running the Mesa release **`4.0.0-preflight-3f038cb`**, which raises the **transaction protocol version to 5.0.0**. Operators must run **`4.0.0-preflight-3f038cb`** to remain on the preflight network. Earlier builds — including the stop-slot release `4.0.0-preflight-stop-2967b39` — are no longer compatible with the post-fork chain. zkApp developers must update to **`o1js@3.0.0-mesa.698ca`**, which targets transaction protocol v5.0.0; earlier o1js releases will produce transactions that the post-fork network rejects. See [Preflight Network](/network-upgrades/mesa/preflight-network) for the full upgrade path. ::: | Upgrade | Status | Date | Key Changes | |---------|--------|------|-------------| | [Berkeley](/network-upgrades/berkeley/requirements) | Completed | June 2024 | zkApp programmability, recursive proofs, new transaction model, archive database migration | | [Mesa](/network-upgrades/mesa/preflight-network) | Preflight hard fork completed | 2026-04-27 13:00 UTC (preflight) | Transaction protocol v5.0.0, automode upgrades, simplified archive migration | --- url: /network-upgrades/mesa/archive-upgrade --- # Archive Upgrade This guide describes the general procedure for upgrading a Mina archive database from Berkeley to Mesa. The same steps apply to every Mesa deployment (preflight, devnet, mainnet) — only the archive package version differs. :::tip Mesa preflight hard fork completed The Mesa preflight network hard-forked at **2026-04-27 13:00 UTC**. The post-fork chain runs **`4.0.0-preflight-3f038cb`**, which raises the **transaction protocol version to 5.0.0**. Pre-fork builds — including the stop-slot release `4.0.0-preflight-stop-2967b39` — are no longer compatible. When upgrading a preflight archive database, install the matching `mina-archive-mesa=4.0.0-preflight-3f038cb` package so the archive node speaks the new transaction protocol. ::: :::info Choosing the Mesa archive version The commands below use `` as a placeholder for the archive build you want to install. Substitute the tag that matches your target network: - **Preflight network** — use `4.0.0-preflight-3f038cb` (post-hard-fork; transaction protocol v5.0.0). See [Preflight Network](./preflight-network) for the full release matrix. - **Devnet / mainnet** — use the Mesa release tag published for that network when it is announced. ::: To successfully upgrade the archive database to Mesa, you must ensure that your environment meets the foundational requirements. ## Migration host - PostgreSQL database for database server - If you use Docker, then any of the supported OS by Mina (bullseye, focal, noble, bookworm or jammy) with at least 32 GB of RAM - gsutil application from Google Cloud Suite in version 5 or later - (Optional) Docker in version 23.0 or later ## Archive database One of the most obvious prerequisites is a Mainnet database. If you don't have an existing database with Devnet/Mainnet archive data, you can always download it from the O1Labs Google Cloud bucket. ## Upgrade process ### Upgrade script Assuming that you have a PostgreSQL database with Mainnet archive data, in order to upgrade it to Mesa version, you need to run SQL upgrade script. We put all efforts to make the upgrade process as smooth as possible. Script can be run on archive node which is online or offline. Script can be run multiple times, it will skip steps that were already completed. It also performs sanity checks before each step to ensure that the upgrade process is successful. Finally it creates new table (version) in the database to keep track of the upgrade process. #### Getting the script You can find the SQL upgrade script in the Mina repository on GitHub. Make sure to download the latest version of the script before proceeding. You can download the script directly using the following command: ```bash curl -O https://raw.githubusercontent.com/MinaProtocol/mina/refs/heads/mesa/src/app/archive/upgrade_to_mesa.sql ``` We also ship the script in the Mina archive Docker image and Debian package. ```bash docker run --rm gcr.io/o1labs-192920/mina-archive:-bookworm-mesa cat /etc/mina/archive/upgrade-to-mesa.sql > upgrade-to-mesa.sql ``` ```bash # Setup the Mina repository and install the archive package. # Repository setup (apt sources, GPG key, channel) is network-specific — # see Preflight Network for the preflight pin, or your network's release notes. apt-get install mina-archive-mesa= # View the upgrade and downgrade scripts cat /etc/mina/archive/upgrade-to-mesa.sql cat /etc/mina/archive/downgrade-to-berkeley.sql ``` #### Running the script :::caution Database Backup Before running the upgrade script, **backup your archive database**. The upgrade modifies the database schema. ```bash pg_dump -U > berkeley-archive-backup.sql ``` ::: To run the upgrade script, execute the following command: ```bash psql -U -d -f upgrade-to-mesa.sql ``` Make sure to replace `` and `` with your actual PostgreSQL username and database name. #### Rollback You can rollback the upgrade process by restoring the database from a backup taken before running the upgrade script. Another is to run rollback script which is part of the upgrade script. It will drop all tables and other database objects created by the upgrade script. It will also update the version table to reflect the rollback. ##### Running the rollback script To run the rollback script, you need to execute the following command: ```bash psql -U -d -f /etc/mina/archive/downgrade-to-berkeley.sql ``` Make sure to replace `` and `` with your actual PostgreSQL username and database name. ### Post-upgrade steps After successfully running the upgrade script, you DO NOT need to restart your archive node or Rosetta API. Changes in upgrade script are backward compatible and will be picked up by the archive node and Rosetta API automatically. ### Verification To verify that the upgrade was successful, you can check the version table in the PostgreSQL database. You can do this by running the following command: ```bash psql -U -d -c "SELECT * FROM version;" ``` Make sure to replace `` and `` with your actual PostgreSQL username and database name. If the upgrade was successful, you should see the new version number in the output. We put a lot of effort into making the upgrade process as smooth as possible. However, if you encounter any issues or need assistance, please reach out to the Mina community on [Discord](https://discord.gg/minaprotocol) or [GitHub Discussions](https://github.com/MinaProtocol/mina/discussions). ## Appendix: Database Schema Changes Below we present details of what was changed in the archive node database schema between Berkeley and Mesa versions. ### Zkapp_state_nullable Additional Columns The `zkapp_state_nullable` table has been modified to include new columns `element8` through `element31` which are nullable and can store additional state information for zkApps. ```sql , element8 int REFERENCES zkapp_field(id) ... , element31 int REFERENCES zkapp_field(id) ); ``` This expansion allows zkApps to store up to 31 state elements instead of the previous 8, significantly increasing the state storage capacity for complex smart contracts. ### Version Table We also introduced a new table `version` to keep track of the database schema version. The purpose of this table is to help with future database migrations. The table tracks which migration scripts were applied and when. Ultimately it helps to determine the current version of the database schema and helps to avoid applying the same migration script multiple times. This table is created if it does not exist already. Rollback and upgrade scripts will insert a new row with the version number and timestamp when the script was applied. ```sql CREATE TABLE IF NOT EXISTS version ( version_num INT PRIMARY KEY, applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); ``` The version table provides: - **Migration tracking**: Records which migrations have been applied - **Timestamp tracking**: Shows when each migration was executed - **Idempotency**: Prevents duplicate migration runs - **Version identification**: Easily identify the current database schema version --- url: /network-upgrades/mesa/preflight-network --- # Connect to Mesa Preflight Network The Mesa preflight network is a testing environment for validating the Mesa upgrade before deployment to devnet and mainnet. This network allows node operators and developers to test their infrastructure and applications with the new Mesa release. :::tip Mesa preflight hard fork completed The Mesa preflight network hard-forked at **2026-04-27 13:00 UTC**. The post-fork chain is now running the Mesa release **`4.0.0-preflight-3f038cb`**, which bumps the **transaction protocol version to 5.0.0**. The transaction protocol bump is a breaking wire-format change: any node still running a pre-fork build (including the stop-slot release `4.0.0-preflight-stop-2967b39` and the original preflight build `4.0.0-preflight1-b649c79`) will reject the new transaction format and is no longer compatible with the network. Upgrade to **`4.0.0-preflight-3f038cb`** to resume participation. zkApp developers must rebuild and redeploy against **`o1js@3.0.0-mesa.698ca`** — the first o1js release that targets transaction protocol v5.0.0. Transactions produced by earlier o1js versions will be rejected by post-fork nodes. A dedicated **Upgrade Steps** page covering the post-fork operator checklist will be linked from the Mesa Upgrade sidebar once it ships. ::: :::caution Preflight Network Notice The preflight network is intended for testing purposes only. This network may experience instability, breaking changes, and unexpected behavior. Data on this network should not be considered persistent or reliable. ::: ## Available Build Versions The Mesa preflight network uses the following build versions: **Current version (install this):** `4.0.0-preflight-3f038cb` — post-hard-fork release. Implements transaction protocol version **5.0.0** and is the only build compatible with the post-fork chain. **Compatible o1js release:** `o1js@3.0.0-mesa.698ca` — the matching SDK for transaction protocol v5.0.0. Install with `npm install o1js@3.0.0-mesa.698ca` (or the equivalent for your package manager) when developing or redeploying zkApps against the post-fork preflight network. **Previous versions (historical, do not install on new nodes):** - `4.0.0-preflight-stop-2967b39` — stop-slot release used to carry nodes up to the fork. Pre-fork transaction protocol; incompatible with the post-fork chain. - `4.0.0-preflight1-b649c79` — original preflight build. Listed for reference only. ### Docker Images Docker images are available for both `amd64` and `arm64` architectures, on the `bookworm` and `noble` base distributions: - **Mina Daemon:** `gcr.io/o1labs-192920/mina-daemon:4.0.0-preflight-3f038cb-bookworm-mesa` - **Archive Node:** `gcr.io/o1labs-192920/mina-archive:4.0.0-preflight-3f038cb-bookworm-mesa` - **Rosetta:** `gcr.io/o1labs-192920/mina-rosetta:4.0.0-preflight-3f038cb-bookworm-mesa` For `noble`, swap `bookworm` for `noble` in the tag (e.g. `mina-daemon:4.0.0-preflight-3f038cb-noble-mesa`). ### Debian Packages Debian packages are available from the unstable repository: **Repository:** `unstable.apt.packages.minaprotocol.com` **Channel:** `preflight` **Codenames:** `bookworm`, `noble` Available packages (each at version `4.0.0-preflight-3f038cb`): - `mina-mesa` - `mina-archive-mesa` - `mina-rosetta-mesa` For detailed information about the Debian repository structure and configuration, please refer to the [Debian Repository documentation](https://unstable.apt.packages.minaprotocol.com/). ## Connecting to the Network To connect your node to the Mesa preflight network, you must use the preflight network seed peer list. ### Required Parameter Add the following parameter to your mina daemon command: ```bash --peer-list-url https://storage.googleapis.com/o1labs-gitops-infrastructure/mina-mesa-network/mina-mesa-network-seeds.txt ``` ### Example: Running with Docker To start a Mina daemon node using Docker: ```bash docker run --name mina-mesa-preflight -d \ -p 8302:8302 \ --restart=always \ gcr.io/o1labs-192920/mina-daemon:4.0.0-preflight-3f038cb-bookworm-mesa \ daemon \ --peer-list-url https://storage.googleapis.com/o1labs-gitops-infrastructure/mina-mesa-network/mina-mesa-network-seeds.txt ``` For production deployments, you'll want to mount configuration directories and add additional flags: ```bash docker run --name mina-mesa-preflight -d \ -p 8302:8302 \ --restart=always \ -v $(pwd)/.mina-config:/root/.mina-config \ gcr.io/o1labs-192920/mina-daemon:4.0.0-preflight-3f038cb-bookworm-mesa \ daemon \ --peer-list-url https://storage.googleapis.com/o1labs-gitops-infrastructure/mina-mesa-network/mina-mesa-network-seeds.txt \ --libp2p-keypair /root/.mina-config/keys/libp2p-key ``` ### Example: Running with Debian Package First, install dependencies and configure the repository: ```bash # Step 1: Install dependencies sudo apt-get install -y lsb-release ca-certificates wget gnupg # Step 2: Import the GPG key wget -q https://unstable.apt.packages.minaprotocol.com/repo-signing-key.gpg \ -O /etc/apt/trusted.gpg.d/minaprotocol.gpg # Step 3: Add the unstable repository with preflight channel echo "deb https://unstable.apt.packages.minaprotocol.com $(lsb_release -cs) preflight" | \ sudo tee /etc/apt/sources.list.d/mina-preflight.list # Step 4: Update and install sudo apt-get update sudo apt-get install -y mina-mesa=4.0.0-preflight-3f038cb ``` Then start the daemon: ```bash mina daemon \ --peer-list-url https://storage.googleapis.com/o1labs-gitops-infrastructure/mina-mesa-network/mina-mesa-network-seeds.txt \ --libp2p-keypair ~/.mina-config/keys/libp2p-key ``` ### Running Archive Node :::info Upgrading from Berkeley to Mesa If you have an existing Berkeley archive database that you want to upgrade to Mesa, please refer to the comprehensive [Archive Upgrade](archive-upgrade) guide for detailed instructions on: - Migration prerequisites and requirements - Running the upgrade script - Rollback procedures - Database schema changes - Verification steps ::: #### Installing and Running Mesa Archive Node An archive node stores the full history of the blockchain and provides a GraphQL API for querying historical data. It requires a PostgreSQL database. **Installation with Debian:** ```bash # Step 1: Install dependencies sudo apt-get install -y lsb-release ca-certificates wget gnupg postgresql postgresql-contrib # Step 2: Import the GPG key wget -q https://unstable.apt.packages.minaprotocol.com/repo-signing-key.gpg \ -O /etc/apt/trusted.gpg.d/minaprotocol.gpg # Step 3: Add the repository echo "deb https://unstable.apt.packages.minaprotocol.com $(lsb_release -cs) preflight" | \ sudo tee /etc/apt/sources.list.d/mina-preflight.list # Step 4: Install mina-archive-mesa sudo apt-get update sudo apt-get install -y mina-archive-mesa=4.0.0-preflight-3f038cb # Step 5: Create PostgreSQL database sudo -u postgres createdb archive sudo -u postgres createuser archive_user sudo -u postgres psql -c "ALTER USER archive_user WITH PASSWORD 'your-secure-password';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE archive TO archive_user;" # Step 6: Start the archive node mina-archive run \ --postgres-uri postgresql://archive_user:your-secure-password@localhost:5432/archive \ --server-port 3086 ``` **Using Docker:** ```bash # Start the archive node (assumes you have a PostgreSQL server running) docker run --name mina-archive-mesa -d \ -p 3086:3086 \ --restart=always \ gcr.io/o1labs-192920/mina-archive:4.0.0-preflight-3f038cb-bookworm-mesa \ mina-archive run \ --postgres-uri postgresql://archive_user:your-secure-password@postgres-host:5432/archive \ --server-port 3086 ``` **Connecting Mina Daemon to Archive:** Configure your mina daemon to send blocks to the archive node: ```bash mina daemon \ --peer-list-url https://storage.googleapis.com/o1labs-gitops-infrastructure/mina-mesa-network/mina-mesa-network-seeds.txt \ --archive-address localhost:3086 ``` ### Installing and Running Rosetta Rosetta is a standardized API for blockchain integration. The Rosetta API requires both a mina daemon and an archive node. **Installation with Debian:** ```bash # Step 1: Install dependencies (if not already done) sudo apt-get install -y lsb-release ca-certificates wget gnupg # Step 2: Import the GPG key (if not already done) wget -q https://unstable.apt.packages.minaprotocol.com/repo-signing-key.gpg \ -O /etc/apt/trusted.gpg.d/minaprotocol.gpg # Step 3: Add the repository (if not already done) echo "deb https://unstable.apt.packages.minaprotocol.com $(lsb_release -cs) preflight" | \ sudo tee /etc/apt/sources.list.d/mina-preflight.list # Step 4: Install mina-rosetta-mesa sudo apt-get update sudo apt-get install -y mina-rosetta-mesa=4.0.0-preflight-3f038cb # Step 5: Start Rosetta # Rosetta connects to both the mina daemon and archive node mina-rosetta \ --port 3087 \ --archive-uri http://localhost:3086/graphql \ --graphql-uri http://localhost:3085/graphql ``` **Using Docker:** ```bash docker run --name mina-rosetta-mesa -d \ -p 3087:3087 \ --restart=always \ gcr.io/o1labs-192920/mina-rosetta:4.0.0-preflight-3f038cb-bookworm-mesa \ --port 3087 \ --archive-uri http://archive-host:3086/graphql \ --graphql-uri http://mina-daemon-host:3085/graphql ``` **Note:** Rosetta requires: - A running mina daemon (GraphQL endpoint, typically port 3085) - A running archive node (GraphQL endpoint, typically port 3086) - Both must be fully synced for Rosetta to function properly ## Nightly Builds In addition to the preflight release builds, nightly builds are also available for testing the latest changes. **Repository:** `nightly.apt.packages.minaprotocol.com` Nightly builds are available for both Debian packages and Docker images. These builds represent the latest development state and may be even more unstable than preflight releases. For more information about nightly builds and repository configuration, see the [Debian Repository documentation](https://nightly.apt.packages.minaprotocol.com/). ## Verification After starting your node, verify connectivity to the preflight network: ### Check Node Status ```bash # For Docker docker exec -it mina-mesa-preflight mina client status # For Debian installation mina client status ``` ### Monitor Logs ```bash # For Docker docker logs -f mina-mesa-preflight # For systemd service (Debian) journalctl -u mina -f ``` ## Support and Feedback If you encounter issues or have feedback about the Mesa preflight network: 1. Check the [Mina Protocol Discord](https://discord.gg/minaprotocol) for community support 2. Report issues on the [Mina GitHub repository](https://github.com/MinaProtocol/mina/issues) 3. Join the Mesa upgrade discussions in the community channels ## Next Steps - Explore additional Mesa upgrade documentation - Test your applications and infrastructure against the preflight network - Provide feedback to help improve the Mesa upgrade process --- url: /node-developers/bip44 --- # BIP44 Information | index | hexa | symbol | coin | |:------|:-----------|:-------|:----------------------------------| | 12586 | 0x8000312a | MINA | [Mina](https://minaprotocol.com/) | Mina uses the 5 level [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) path format specified in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) ``` m / purpose' / coin_type' / account' / change / address_index ``` Keypairs are derived by varying only the ``account`` while keeping the ``change`` and ``address_index`` zero. # BIP32 path format ``` m / 44' / 12586' / account' / 0 / 0 ``` # Examples | account | path | |:--------|:------------------------| | 0 | m/44'/12586'/0'/0/0 | | 271 | m/44'/12586'/271'/0/0 | --- url: /node-developers/code-review-guidelines --- # Code Review Guidelines A good pull request: - Does about one thing (new feature, bug fix, etc) - Adds tests and documentation for any new functionality - When fixing a bug, adds or fixes test that would have caught said bug ## OCaml things - Are the [style guidelines](./style-guide) being followed? - Do the signatures make sense? Are they minimal and reusable? - Does anything need to be functored over? - Are there any error cases that aren't handled correctly? - Are calls to `_exn` functions justified? Are their preconditions for not throwing an exception met? Is the exception it throws useful? - There shouldn't be commented out code. - No stray debug code lying around. - Any logging is appropriate. All `Logger.trace` logs should be inessential, because they won't be shown to anyone by default. - Should this code live in its library? Should it live in a different library? - Does the code confuse you? Maybe there should be a comment, or it should be structured differently. - Does a behavior change break assumptions other code makes? --- url: /node-developers/codebase-overview --- # Codebase Overview The Mina Protocol is written in OCaml, a statically typed, functional programming language. For OCaml beginners, it may help to skim through [Real World OCaml](https://realworldocaml.org/) for a good introduction to the language, and some deep dives into specific topics if you're interested. Assuming basic familiarity with OCaml, here's some more info on how it is used in the Mina Protocol. ## Code Structure See the [Repository Structure page](/node-developers/repository-structure). ## Compilation The OCaml compiler can target bytecode and native compilation. The code statically links with some libraries so it can't compile to bytecode. The code doesn't play well with the REPL. Dune, the build system, has a concept of folders that represent modules and files that a module. If the folder has a file with the same name, it's essentially equivalent to `index.js` in Node. Interface files in OCaml with the `.mli` extension contain type signatures and structures for a module. The corresponding implementation must have the same file name with the `.ml` extension. Only the things defined in the interface are available from other modules. If an interface file does not exist for a module, everything is exposed by default. The same convention and rules apply to files with the `.rei` and `.re` extensions. For the linking step, `dune` uses `ldd` under the hood. You can also use things like `-O3` for optimization. For debugging, you can use `gdb`. ## Open-source Library Documentation There are multiple libraries for OCaml. One challenge with learning OCaml is locating and reading documentation for the various libraries. For example, the Jane Street `Core` library has the following structure: ``` Base | Core_kernel -> Async_kernel | | Unix <- Core -> Async ``` In general, the source code of an installed library is not available, so follow these tips to find the documentation. To review the docs for Core, a standard library overlay. Core is a popular alternative to the OCaml standard library. First, go to the [Core](https://github.com/janestreet/core) codebase on GitHub and then locate the correct documentation. If you don't see the module you're looking for, go to next to `Core_kernel`. If that fails, then look for `Base`. To use the find capability in GitHub, expand the sections. Most documentation is published in HTML. However, you can use the an IDE to find and review code and documentation, like the Merlin editor service that provides modern IDE features for OCaml. Merlin provides type hints and code navigation, like Go To Definition. Note that Merlin works only if your code compiles. OPAM, the source-based package manager for OCaml, usually ships documentation with libraries that you can access using Merlin. ## Extensions OCaml uses the ppx meta-programming system that generates code at compile time. For example, consider this ppx extension on a type signature: ``` type t = | A | B [@ to_yojson f] [@@ deriving yojson] ``` The single `@` scopes an extension to a single expression. The `@@` denotes the extension is expanded in the scope of the calling context. For an extension on a structure or a value, use the following syntax. `%` returns a value/expression. `%%` injects a statement ``` let x = [% ...] [%% ...] let y = let%... z = ... in match%... ... with | ... | ... in [%% if x] let x = y [%% else] let x = z [%% endif] ``` **TL;DR** Anytime you see `[@ ...]` `[@@ ...]` `[% ...]` `[%% ...]` it's an OCaml language extension. ## Monads Functional design patterns that allows you to write computation in a very generic way, that removes the need for boilerplate code. Monads allow us to abstract up to a higher level of computation, while taking care of all the glue for us. In other words, monads are programmable semicolons. For example consider the following imperative example: ``` function example(x) { if ( x == null ) return null; x = x + 1; if ( !isEven(x) ) return null; return x; } ``` This can expressed similarly in functional programming using a monad, using option: ``` type a' option = | None | Some of 'a let return x = Some x (* Bind infix operation, applies f to m *) let (>>=) m f = match m with | Some x -> f x | None -> None (** Map infix operation Essentially the same as bind, but the inner function unwraps the value. **) let (>>|) m f = m >>= (fun x -> return (f x)) ``` Now we an use these primitives to reimplement the imperative example above as follows. ``` let add_one = ((+) 1) let bind_even : int -> int option = fun x -> if x mod 2 = 0 then Some x else None let example x = x >>| add_one >>= bind_even; ``` OCaml has a `ppx` that makes writing monads much easier to follow, using the let syntax. ``` let%bind x = y in f x (* This compiles down to the following *) y >>= (fun x -> f x) ``` Essentially, this syntax takes the value from the let statement and places it on the left of the bind infix call, and puts the assignment into a lambda. ## Async Under the hood, async uses Monads. However, ivars are the low-level async primitive. `'a Ivar.t` is essentially a mutex that can only be filled once. After the value from a computation returns, it then fills the ivar. The rest of the syntactic sugar takes the ivar and passes them through `Deferred` monads. A `yield` function exists, but avoid using it since it has some weird behavior. Instead, operate on the wrapped values that happen in between `Deferred` bindings. ## Custom Helpers Use these custom helpers: - `Strict_pipe` - wraps pipe and gives certain guarantees around how it can be used. - `Broadcast_pipe` - allows a single pipe to be hooked up to multiple downstream pipes. Do not use: - `Async.Pipe` operates essentially like a buffer and is unsafe since it has unlimited buffering by default (memory overflow) and some funky behavior around which end of the pipe should do what. - `Linear_pipe` - deprecated in favor of `Strict_pipe` and `Broadcast_pipe`. --- url: /node-developers/contributing --- # Contributing to Mina Mina is an open-source project with a mission to build an inclusive and sustainable community-driven protocol. As such, Mina welcomes contributions. The protocol is in development and is always improving. You can make contributions in many ways, including writing code, user testing, documentation, and community support. For specific instructions for contributing in each of these domains, see the codebase repositories or ask in [Mina Protocol Discord](https://discord.gg/minaprotocol). For general questions on getting involved, reach out to the Mina community on the [Mina Protocol Discord](https://discord.gg/minaprotocol) server. ## Developers Mina is entirely open source, and the code is distributed under the terms of the [Apache License 2.0](https://github.com/MinaProtocol/mina/blob/master/LICENSE). ## Docs Mina Docs are also open source. We love our community. Help us make the docs better, contributions are welcome and appreciated. - For a quick fix, click **EDIT THIS PAGE**. - For a more substantial contribution, see the [Docs Contributing Guidelines](https://github.com/o1-labs/docs2/blob/main/CONTRIBUTING.md). ## Mina Grants Grants are rewarded for certain projects related to the development of Mina. See [Mina Grants](https://minaprotocol.com/grants) for details. The projects are mostly programming focused, but the areas of design and community development are included. Reach out in the [#grants](https://discord.com/channels/484437221055922177/727960609832042607) channel on Mina Protocol Discord for questions about the grant program. ## Reporting Issues If you notice Code of Conduct violations, please follow the Reporting Guidelines in [Code of Conduct](https://github.com/MinaProtocol/mina/blob/develop/CODE_OF_CONDUCT.md) to file a report and alert the community to ensure a safe space for everyone. If you encounter critical bugs or vulnerabilities in the protocol, report them to security@minaprotocol.com. For minor bugs and issues, create an issue on GitHub. --- url: /node-developers/graphql-api --- # GraphQL API :::caution - Mina APIs are still under construction, so these endpoints may change. - By default, the GraphQL port is bound to localhost. Exposing the GraphQL API to the internet allows anyone to send Mina from the accounts known to the daemon. ::: The Mina daemon exposes a [GraphQL API](https://graphql.org/) used to request information from and submit commands to a running node. To use the GraphQL API, connect your GraphQL client to `http://localhost:3085/graphql` or open in your browser to use the [GraphiQL IDE](https://github.com/graphql/graphiql). - By default, an HTTP server runs on port `3085`. You can configure a different port, use the `-rest-port` flag with the daemon startup command. - The default security permits only connections from `localhost`. To listen on all interfaces, add the `-insecure-rest-server` flag to the daemon startup command. In addition to information about the running node, the GraphQL API can return data about the network's latest blocks. However, as the blockchain's historical state is not persisted in Mina, only blocks in the node's transition frontier are returned, i.e., the last `k` blocks. For other historical data, use the [Archive Node](/node-operators/archive-node/getting-started) that is designed to retain and retrieve historical data. The full Mina GraphQL schema is available [https://github.com/MinaProtocol/mina/blob/develop/graphql_schema.json](https://github.com/MinaProtocol/mina/blob/develop/graphql_schema.json). ### Queries The Mina GraphQL API has a number of [queries](/node-operators/validator-node/querying-data) to extract data from a running node. [GraphQL queries](https://graphql.org/learn/queries/) allow specifying the data to be returned in the response. For example, to get the latest block and creator information known to the daemon: ``` query { bestChain(maxLength: 1) { creator stateHash protocolState { consensusState { blockHeight } previousStateHash } transactions { coinbase } } } ``` The following query requests all pending transactions in the transaction pool together with their fees. This query can be used to generate an estimate of a suggested fee for a transaction: ``` query { pooledUserCommands { id, fee } } ``` :::tip The memo field returned for a transaction is [Base58Check encoded](https://en.bitcoin.it/wiki/Base58Check_encoding). ::: ``` query { account(publicKey: "") { balance { total } delegate nonce } } ``` You can submit GraphQL requests from the command line of a node. For example, to use cURL to get the last ten block creators known to the node: ``` curl -d '{"query": "{ bestChain(maxLength: 10) { creator } }"}' -H 'Content-Type: application/json' http://localhost:3085/graphql ``` ### Mutations GraphQL mutations modify the running node in some way. For example, mutations may be used to send a payment, create a new account, or to add additional peers. Consult the GraphQL schema for all available mutations. Adding a new peer: ``` mutation { addPeers(peers:{ libp2p_port:10511, host:"34.73.68.198", peer_id:"12D3KooWSJB2gZWi3ruVmtTF9JBCEBpCrJfuWCWzzRr8mMQWFQ9U" }) } ``` Update a SNARK worker to use a fee of 0.1 MINA: ``` mutation { setSnarkWorkFee(input: {fee: "100000000"}) } ``` ### Subscriptions A GraphQL subscription allows a GraphQL client to have data pushed to it when an event occurs. In Mina, there are subscriptions for: - _newSyncUpdate_ - occurs when the sync status of the node changes. - _newBlock_ - occurs when a new block is received. - chainReorganisation - occurs when the best tip of the node changes in a non-trivial way. For example, to subscribe to all new blocks produced: ``` subscription { newBlock { creator stateHash protocolState { consensusState { blockHeight } previousStateHash } } } ``` The new block subscription can also be limited to return only new blocks created by a defined public key with the `publicKey` argument. ### GraphQL API and public Internet Exposing the GraphQL endpoint with full API support to the public Internet **is not** recommended. However, you can start the Mina Daemon node with the `--open-limited-graphql-port` and `--limited-graphql-port ` CLI arguments to expose the GraphQL endpoint with limited API support. ### Resources - [5-minute introduction video on Mina GraphQL API](http://bit.ly/GraphQLAPIin5) Coda - [First steps with the Mina GraphQL API](https://garethtdavies.com/crypto/first-steps-with-coda-graphql-api.html) - [Introduction to GraphQL](https://graphql.org/learn/) --- url: /node-developers --- # Node Developers Explore the codebase on [GitHub](https://github.com/MinaProtocol/mina). To start contributing code to Mina, see the [Contributing Guide](/node-developers/contributing). The [protocol](https://github.com/MinaProtocol/mina/tree/master/src) and [CLI](https://github.com/MinaProtocol/mina/tree/master/src/app/cli) are written in OCaml. All levels of experience in any or all of these tools is welcome. Other documents relevant to contributing code include: - [Style Guide](/node-developers/style-guide) - [Code Review Guidelines](/node-developers/code-review-guidelines) - [Repository Structure](/node-developers/repository-structure) - [BIP44 Information](/node-developers/bip44) Mina is entirely open source. The code is distributed under the terms of the [Apache License 2.0](https://github.com/MinaProtocol/mina/blob/master/LICENSE). --- url: /node-developers/repository-structure --- # Repository Structure The file structure of the [Mina repository](https://github.com/minaprotocol/mina)the roles various files play: - `dockerfiles/` Contains Docker-related scripts - `docs/` Documentation for the code and processes for contributing are here. The documentation website with the walkthrough docs lives in `frontend/website/docs`. - `frontend/` All code related to Mina frontend UIs and products - `wallet/` Source code for the Mina wallet - `website/` Code for https://minaprotocol.com - `posts/` Markdown docs for blog posts - `src/` Source code for the website - `static/` Static files like images, etc. - `rfcs/` This directory contains all accepted RFCs (or "requests for comments") made according to the [RFC process](https://github.com/MinaProtocol/mina/blob/master/CONTRIBUTING.md#rfcs). - `scripts/` - `src/` All protocol source code, both application and library code, is in this directory. - `*.opam` These files are needed for our `dune` build system. There must be one for each library in `lib`. When you create a library `lib/foo_lib` with a `dune` file giving the library's name as `foo_lib`, you must create a `foo_lib.opam` file. - `config/` Build time config - these .mlh files define compile time constants and their values. - `app/` Applications live here. - `cli/` This is the mina client/daemon. It is what you use to run a staker, a snarker, or a simple client for sending and receiving transactions. - `website/` Soon to be deprecated directory for the website - most of the code has migrated over to `frontend/website/` - `reformat/` This program runs `ocamlformat` on most of the files in the source tree, with a few exceptions. - `logproc/` This utility reads from `stdin` and can filter and pretty print the log messages emitted by the mina daemon. - `libp2p_helper/` This program uses go-libp2p to implement the peer-to-peer plumbing that Mina daemons need. - `external/` Local copies of external libraries which we've had to make some tweaks to. - `lib/` Libraries powering mina. The libraries here basically fall into two categories. 1. General purpose data-types and functionality. This includes `snarky`, `fold_lib`, `vrf_lib`, `sgn`, and others. 2. Application specific functionality, structured as a library. This includes `syncable_ledger`, `staged_ledger`, `transaction_snark`, and others. --- url: /node-developers/sandbox-node --- # Sandbox Node The Mina Sandbox Node enables you to test and get familiar with core features of the protocol and build tooling in a stable environment -- it's a single-node private network that uses the same configuration as the live testnet. This sandbox supports multiple accounts, sending transactions between them, and also supports performing SNARK work, delegating, and staking. In fact since it's a single node network, you earn all the block rewards! :::info The sandbox does **NOT** connect you to a live network. ::: ## Installation [Docker](https://www.docker.com) is a tool for portably running applications. The Mina Sandbox is packaged with Docker, and now built-in to our daemon containers. It’s easy to install--we suggest the [Docker Desktop](https://www.docker.com/products/docker-desktop). After you have Docker installed run the following command to spin up the Mina Sandbox. ``` docker run \ --publish 3085:3085 \ -d \ --name mina \ -e RUN_DEMO=true \ -e MINA_PRIVKEY_PASS='' \ minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet ``` This command starts a daemon inside the docker container and exposes the GraphQL port (3085) to your computer. This port is used for communication with the client. This daemon automatical runs in the background with a block producer and SNARK worker. You can view logs by executing. ``` docker logs --follow mina ``` And stop mina by running. ``` docker stop mina ``` You can use the Mina CLI to interact with the sandbox node. The following command opens a shell inside the docker container from where you can issue any of the available [cli commands](/node-operators/reference/mina-cli-reference). ``` docker exec -it mina bash ``` ### Account details The container has one account with this public key: ``` B62qiZfzW27eavtPrnF6DeDSAKEjXuGFdkouC3T5STRa6rrYLiDUP2p ``` The password for this account is the empty string (there's no password -- you can leave the password field blank). ## How to use the sandbox There are a few things you can do with your sandbox now that you have it running: - [Install Mina](/node-operators/validator-node/installing-on-ubuntu-and-debian) as usual and use many of the client commands. Since the daemon is already running in the container, you don't need to run `mina daemon`! - Install the GUI Wallet app to use a graphical interface to your node. Enter '127.0.0.1' as the host of your node during setup. - Head over to [http://localhost:3085/graphql](http://localhost:3085/graphql) to play with the GraphQL API directly. --- url: /node-developers/style-guide --- # Style Guide ## Ocaml [ocaml]: #ocaml ### General [ocaml-general]: #ocaml-general Our style guidelines are an extension of a couple of existing style guidelines. The first is ocamlformat, and it acts as the source of truth for most of our coding style. In fact, ocamlformat is a blocker on CI, so your code must be formatted by it's guidelines in order to be merged into master. Ocamlformat does not handle all important cases of style, however, as it is only defining and enforcing how code should be spaced out and indented. For anything which ocamlformat does not cover, the [Jane Street styleguide](https://opensource.janestreet.com/standards/) should be referenced. This styleguide we define here is intended to be an extension of the janestreet styleguide, with more attention to detail in concern to a few specific constructs we use regularly throughout our codebase. ### Mli Files [ocaml-mli]: #ocaml-mli A `*.mli` file should not be included for a `*.ml` file if the `*.ml` file's automatically derived interface is different. Many `*.ml` files in our codebase consist of only signatures and a functor. In the case of those files, there is not purpose to redefining the `*.mli` file because there is no new or restricted information in that file. If a `*.ml` file contains implementations in the root structure, then a `*.mli` file should most likely be created. ### Modules [ocaml-modules]: #ocaml-modules #### Prefer Standardized Shortnames The names `t`, `T`, and `S` are common shortnames used in modules to signify specific things. The name `t` is used to represent the root type of a module. For instance, if there is a module `Account` which contains types and values related to accounts, then `Account.t` is the type of an account. The name `t` can also be used as a value iff there is only intended to be one value of the root type of the module. As an example, if you wanted to have a single global logger in a `Logger` module, the type `Logger.t` could be the type of a logger, and the value `Logger.t` could be the global logger value of type `Logger.t`. The module name `T` is used to encapsulate the root type and basic definitions regarding a root type of a module. It is a common practice used when you want to instantiate some functors for a module's root type and have the instantiations appear in the module itself. As an example, it is common to call the `Comparable.Make` functor in order to derive various helper values/modules from a comparable type. In this case, if we had a module `Account` again, and we wanted to derive the `Comparable.S` signature, then we would define a module `T` in `Account` which defines a root type `t` and the required functions for the `Comparable.Make` functor argument (in this case, `compare`). With this `T` module, we can then `include T` and `include Comparable.Make (T)` in the `Account` module to bring in all related values/modules for the `Account.t` type. Here is a full example of that: ``` module Account = struct module T = struct type t = ... [@@deriving compare] end include T include Comparable.Make (T) end ``` The module type name `S` is used for defining the root signature of a module. This is most commonly used when you have a module which contains a functor. In this case, we typically call the functor `Make` and declare the functor returns the type `S`, putting both of these values in the same module. Looking back at our previous example, `Core_kernel`'s `Comparable` module follows this pattern: `Comparable.Make` is a functor which returns a `Comparable.S`. #### Prefer One Type Per Module [ocaml-modules-singleton-types]: #ocaml-modules-singleton-types As a general rule of thumb, each module should be scoped to a single type. This pattern helps isolate concerns and, in turn, allows value names to be shorter, as they are located by context. Take, for example, a `Merkle_tree` module. This module will need a type `Merkle_tree.t` which represents the entire merkle tree (or a node of it). A `Merkle_tree` will also want to have a `path` type. It is preferable to place this `path` type into it's own nested module (`Merkle_tree.Path.t` instead of `Merkle_tree.path`). To help understand why this is preferable, imagine we did put path in `Merkle_tree.path`. Now, `Merkle_tree` contains values (functions) that relate not only to the merkle tree type itself, but also the a path of a merkle tree. For clarity, it would be natural to prepend all of the value names related to a path with `path_` (`path_map`, `path_length`, etc...). By isolating `Path` to it's own module, we can shorten these names while keep the context of values clear. Additionally, if we choose to in the future, we may encapsulate the implementation details of `Path` by applying a restrictive signature to it, which would make the separation of concerns more clear via compiler enforcement. #### No Monkeypatching [ocaml-modules-monkeypatching]: #ocaml-modules-monkeypatching Monkeypatching of modules is explicitly disallowed in our codebase. Monkeypatching is defined as the act of taking an existing module and redefining it with extended or modified values. More simply, it's anything of the form. ``` module A = struct module M = struct let x = ... end end module M = struct include A.M let y = ... (* or `let x = ...` *) end ``` Monkeypatching may be the easiest path to getting code to compile sometimes, but in general, it creates confusion and/or technical debt in the codebase. If you need to monkeypatch a module, you should have a good reason as to why. #### Functor Signature Equalities [ocaml-modules-functor-patterns]: #ocaml-modules-functor-patterns Signature `with` statements for signatures of modules generated by functors should be limited to the form `S with module M1 = M2` whenever possible. Replacement equalities `:=` should be limited to `include` statements where portions of the signature need to be limited (for example, when a nested module in the signature is already defined at the current structure scope). The form `S with type t = ...` is also not preferred as it scales poorly as the number of common dependencies between signatures involved with a functor increases. Note that this places increased importance on the janestreet styleguide rule "Prefer standard signature includes to hand-written interfaces". #### Functor Arity [ocaml-modules-functor-arity]: #ocaml-modules-functor-arity Functor can have a maximum arity of 3 (arity is the number of arguments; in this case, the number of nested functors - functors returning functors). If a functor requires more than 3 modules as arguments, then the required modules should all be nested into one module. The standard pattern for this is to define a signature `Inputs_intf` for your functor, which will, in turn, define the module arguments to the functor. See below for a simple example. ``` module type Inputs_intf = sig module A : A.S module B : B.S module C : C.S module D : D.S end module type S = sig include Inputs_intf (* ... *) end module Make (Inputs : Inputs_intf) : S with module A = Inputs.A and module B = Inputs.B and module C = Inputs.C and module D = Inputs.D = struct open Inputs (* ... *) end ``` # Code Idiosyncrasies We use a particular style of OCaml. Here's some of the important things. ## Parameterized records ```ocaml type ('payload, 'pk, 'signature) t_ = {payload: 'payload; sender: 'pk; signature: 'signature} [@@deriving eq, sexp, hash] type t = (Payload.t, Public_key.t, Signature.t) t_ [@@deriving eq, sexp, hash] (* ... *) type var = (Payload.var, Public_key.var, Signature.var) t_ ``` We're defining a base type `t_` with type variables for all types of record fields. Then we define the record using these type variables. Finally, we instantiate the record with `type t`, this is the OCaml type. And also `type var` this is the type of this value in a SNARK circuit. We'll cover this more later. Whenever we want something to be programmable from within a SNARK circuit we define it in this manner so we can reuse the record definition across both types. There is some talk of moving to OCaml object types to do this sort of thing so we don't need to deal with positional arguments. Perhaps I (@bkase) will write up an RFC for that at some point. ### Ppx_deriving ```ocaml type t = int [@@deriving sexp, eq] ``` This is the first time we've seen a macro. Here we use `sexp` from [ppx_jane](https://github.com/janestreet/ppx_jane) and `eq` from [ppx_deriving](https://github.com/ocaml-ppx/ppx_deriving). ### Stable.V1 ```ocaml module Stable : sig module V1 : sig type t = (* ... *) [@@deriving bin_io, (*...*)] end end ``` Whenever a type is serializable, it's important for us to maintain backwards compatibility once we have a stable release. Ideally, we wouldn't define `bin_io` on any types outside of `Stable.V1`. When we change the structure of the datatype we would create a `V2` under `Stable`. ### Property based tests [Core](https://opensource.janestreet.com/core/) has an implementation of [QuickCheck](https://blog.janestreet.com/quickcheck-for-core/) that we use whenever we can in unit tests. Here is an example signature for a `Quickcheck.Generator.t` of payments. ```ocaml (* Generate a single payment between * $a, b \in keys$ * for fee $\in [0,max_fee]$ * and an amount $\in [1,max_amount]$ *) val gen : keys:Signature_keypair.t array -> max_amount:int -> max_fee:int -> t Quickcheck.Generator.t ``` ### Typesafe invariants (help with naming this section) In Mina, very important checks are frequently performed on certain pieces of data. For example, we need to confirm that the signature is valid on a user-command we receive over the network. Such checks can be expensive, so we only want to do them once, but we want to remember that we've done them. ```ocaml (* inside user_command.mli *) module With_valid_signature : sig type nonrec t = private t [@@deriving sexp, eq] (*...*) end val check : t -> With_valid_signature.t option ``` Here we define `With_valid_signature` (usage will be `User_command.With_valid_signature.t`) using `type nonrec t = private t` to allow upcasting to a `User_command.t`, but prevent downcasting. The _only_ way to turn a `User_command.t` into a `User_command.With_valid_signature.t` is to `check` it. Now the compiler will catch our mistakes. ### Unit Tests We use [ppx_inline_test](https://github.com/janestreet/ppx_inline_test) for unit testing. Of course whenever we can, we combine that with `QuickCheck`. ```ocaml let%test_unit = Quickcheck.test ~sexp:[%sexp_of: Int.t] Int.quickcheck_generator ~f:(fun x -> assert (Int.equal (f_inv (f x)) x)) ``` ### Functors We are in the process of migrating to using module signature equalities -- see [the above section](#functor-signature-equalities) and [the rfc for rationale](https://github.com/MinaProtocol/mina/blob/master/rfcs/0004-style-guidelines.md), but we still have a lot of code using type substitutions (`with type foo := bar`). First we define the resulting module type of the functor, keeping all types we'll be functoring in abstract. ```ocaml module type S = sig type boolean_var type curve type curve_var (*...*) end ``` Then we define the functor: ```ocaml module Schnorr (Impl : Snark_intf.S) (Curve : sig (*...*) end) (Message : Message_intf with type boolean_var := Impl.Boolean.var (*...*)) : S with type boolean_var := Impl.Boolean.var and type curve := Curve.t and type curve_var := Curve.var (*...*) = struct (* here we implement the signature described in S *) end ``` ### Custom SNARK circuit logic This is also the first time we see custom SNARK circuit logic. A pattern we've been using is to scope all operations that you'd want to run inside a SNARK under a submodule `module Checked`. For example, inside [sgn.mli](https://github.com/MinaProtocol/mina/blob/master/src/lib/sgn/sgn.mli) we see: ```ocaml (* ... *) val negate : t -> t module Checked : sig val negate : var -> var end ``` `negate` is the version of the function that runs in OCaml, and `Checked.negate` is the one that runs inside of a SNARK circuit. --- url: /node-operators/archive-node/archive-redundancy --- # Archive Redundancy The [archive node](/node-operators/archive-node/getting-started) stores its data in a PostgreSQL database that node operators host on a provider of their choice, including self-hosting. For redundancy, archive node data can also be stored to an object storage like [Google Cloud Storage](#upload-block-data-to-google-cloud-storage); soon S3 and others) or to a [`mina.log`](#save-block-data-from-logs) file that reside on your computer or be streamed to any typical logging service, for example, LogDNA. Archive data is critical for applications that require historical lookup. On the protocol side, archive data is important for disaster recovery to reconstruct a certain state. A single [archive node](/node-operators/archive-node/getting-started) set up might not be sufficient. If the daemon that sends blocks to the archive process or if the archive process itself fails for some reason, there can be missing blocks in the database. To minimize the risk of archive data loss, employ redundancy techniques. A single archive node setup has a daemon sending blocks to an archive process that writes them to the database. To connect multiple daemons to the archive process, specify the address of an archive process in multiple daemons to reduce the dependency on a single daemon to provide blocks to the archive process. For example, the server port of an archive process is 3086. The daemons can connect to that port using the flag `archive-address` ``` mina daemon \ ..... --archive-address :3086\ ``` Similarly, it is possible to have multiple archive processes write to the same database. In this case, the `postgres-uri` passed to the archive process is the same across multiple archive processes. However, multiple archive processes concurrently writing to a database could cause data inconsistencies (explained in https://github.com/MinaProtocol/mina/issues/7567). To avoid this, set the transaction isolation level of the archive database to `Serializable` with the following query: ALTER DATABASE `` SET DEFAULT_TRANSACTION_ISOLATION TO SERIALIZABLE ; Set the transaction level after you create the [database](/node-operators/archive-node/getting-started) and before you connect an archive process to it. ## Back up block data To ensure that archive data can be restored, use the following features to back up and restore block data. A mechanism for logging a high-fidelity machine-readable representation of blocks using JSON includes some opaque information deep within. These logs are used internally to quickly replay blocks to get to certain chain states for debugging. This information suffices to recreate exact states of the network. Some of the internal data look like this: ```json {"data":["Signed_command",{"payload":{"common":{"fee":"100","fee_token":"1","fee_payer_pk":"B62qixbmBBmCmv1xH5SeF1hw6EqwSNVPi9B28epa3phqVMSyuZk9EoH","nonce":"340","valid_until":"4294967295","memo":"E4YM2vTHhWEg66xpj52JErHUBU4pZ1yageL4TVDDpTTSsv8mK6YaH"},"body":["Payment",{"source_pk":"B62qixbmBBmCmv1xH5SeF1hw6EqwSNVPi9B28epa3phqVMSyuZk9EoH","receiver_pk":"B62qm2GCuGCEK79mEjeyaeiFoukThuZLJCHGe9HAzuAnfbtS5FHtPnP","token_id":"1","amount":"100000000"}]},"signer":"B62qixbmBBmCmv1xH5SeF1hw6EqwSNVPi9B28epa3phqVMSyuZk9EoH","signature":"7mXGz8Df1gu92HVWGue24wcrGxDWkgQrDK59xQGXc627PKFQvVAPSzZn7JMkHtfdBUXavDHcgLBZy4iR4UmA5seRCPMkFDci"}],"status":["Applied",{"fee_payer_account_creation_fee_paid":null,"receiver_account_creation_fee_paid":null,"created_token":null},{"fee_payer_balance":"31866000100000","source_balance":"31866000100000","receiver_balance":"34099000000"}]}],"coinbase":["One",null],"internal_command_balances":[["Coinbase",{"coinbase_receiver_balance":"75477804514901","fee_transfer_receiver_balance":null}],["Fee_transfer",{"receiver1_balance":"65266376010003","receiver2_balance":"78601129170700"}],["Fee_transfer",{"receiver1_balance":"66001820000000","receiver2_balance":"76870784414900"}],["Fee_transfer",{"receiver1_balance":"71158365898775","receiver2_balance":"59264207944722"}],["Fee_transfer",{"receiver1_balance":"68546088449962","receiver2_balance":"66721919100000"}],["Fee_transfer",{"receiver1_balance":"67700798001000","receiver2_balance":"66372760000000"}],["Fee_transfer",{"receiver1_balance":"85383891400000","receiver2_balance":"107174952265469"}],["Fee_transfer",{"receiver1_balance":"65879310000000","receiver2_balance":"66282230000000"}]]}]},"delta_transition_chain_proof":["jxLZWooV57gKCmanzCHHt1CDbHfUpMu6MkynUdqN9ZkBUJi7B1W",[]]} ``` This JSON evolves as the format of the block and transaction payloads evolve in the network. ### Upload block data to Google Cloud Storage The daemon generates a file for each block with the name `-.json` . These files are called precomputed blocks and have all the fields of a block. To specify a daemon to upload block data to Google Cloud Storage, pass the flag `--upload-blocks-to-gcloud`. Set the following environment variables: - `GCLOUD_KEYFILE`: Key file for authentication - `NETWORK_NAME`: Network name to use in the filename to easily distinguish between blocks in different networks (Mainnet and Testnets) - `GCLOUD_BLOCK_UPLOAD_BUCKET`: Google Cloud Storage bucket where the files are uploaded ### Save block data from logs The daemon logs the block data if the flag `-log-precomputed-blocks` is passed. The log to look for is `Saw block with state hash $state_hash` that contains `precomputed_block` in the metadata and has the block information. These precomputed blocks contain the same information that gets uploaded to Google Cloud Storage. ### Generate block data from another archive database From a fully synced archive database, you can generate block data for each block using the `mina-extract-blocks` tool. The `mina-extract-blocks` tool generates a file for each block with name `.json`. The tool takes an `--archive-uri`, an `--end-state-hash`, and an optional `--start-state-hash`, and writes all the blocks in the chain starting from start-state-hash and ending at end-state-hash (including start and end). If only the end hash is provided, then the tool generates blocks starting with the unparented block closest to the end block. This would be the genesis block if there are no missing blocks in between. The block data in these files are called extensional blocks. Since these blocks are generated from the database, they have only the data stored in the archive database and do not contain any other information pertaining to a block (for example, blockchain SNARK) like the precomputed blocks and can only be used to restore blocks in the archive database. Provide the flag `--all-blocks` to write out all blocks contained in the database. ## Identify missing blocks To determine any missing blocks in an archive database, use the `mina-missing-block-auditor` tool. The tool outputs a list of state hashes of all the blocks in the database that are missing a parent. You can use this list to monitor the archive database for any missing blocks. To specify the URI of the PostgreSQL database, use the `--archive-uri` flag. ## Restore blocks When you have block data (precomputed or extensional) available from [Back up block data](/node-operators/archive-node/archive-redundancy#back-up-block-data), you can restore missing blocks in an archive database using the tool `mina-archive-blocks`. 1. Restore precomputed blocks from: - [Upload block data to Google Cloud Storage](/node-operators/archive-node/archive-redundancy#upload-block-data-to-google-cloud-storage) - [Save block data from logs](/node-operators/archive-node/archive-redundancy#save-block-data-from-logs) ``` mina-archive-blocks --precomputed --archive-uri FILES ``` 2. For extensional blocks: (Generated from option [3](#generate-block-data-from-another-archive-database)) ``` mina-archive-blocks --extensional --archive-uri FILES ``` ## Staking ledgers Staking ledgers are used to determine slot winners for each epoch. Mina daemon stores staking ledger for the current and the next epoch after it is finalized. When transitioning to a new epoch, the "next" staking ledger from the previous epoch is used to determine slot winners of the new epoch and a new "next" staking ledger is chosen. Since staking ledgers for older epochs are no longer accessible, you can still keep them around for reporting or other purposes. Export these ledgers using the mina cli command: mina ledger export [current-staged-ledger|staking-epoch-ledger|next-epoch-ledger] Epoch ledger transition happens once every 14 days (given slot-time = 3mins and slots-per-epoch = 7140). The window to backup a staking ledger is ~27 days considering "next" staking ledger is finalized after k (currently 290) blocks in the current epoch and therefore is available for the rest of the current epoch and the entire next epoch. --- url: /node-operators/archive-node/docker-compose --- # Docker Compose Archive This example demonstrates how to run a Mina archive node using Docker Compose for the Mainnet network. This Docker Compose setup includes a Postgres database, a bootstrap database with the latest SQL Dump available, an archive node, a Mina node and a Missing Blocks Guardian script to monitor and populate the gaps in the archive database Copy and paste the provided configuration into a `docker-compose.yml` file. Then run `docker compose up -d` to start the services, and use `docker compose logs -f` to monitor the logs. ```yaml services: postgres: image: postgres:17 restart: always environment: POSTGRES_PASSWORD: postgres POSTGRES_DB: archive healthcheck: test: ["CMD-SHELL", "psql -U postgres -d archive -tAc \"SELECT COUNT(*) FROM pg_database WHERE datname='archive';\" | grep -q '^1$'"] interval: 5s timeout: 10s retries: 10 volumes: - './archive/postgresql/data:/var/lib/postgresql/data' ports: - '5432:5432' bootstrap_db: image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet command: > bash -c ' curl -O https://storage.googleapis.com/mina-archive-dumps/mainnet-archive-dump-$(date +%F_0000).sql.tar.gz; tar -zxvf mainnet-archive-dump-$(date +%F_0000).sql.tar.gz; psql postgres://postgres:postgres@postgres:5432/archive -c " ALTER SYSTEM SET max_connections = 500; ALTER SYSTEM SET max_locks_per_transaction = 100; ALTER SYSTEM SET max_pred_locks_per_relation = 100; ALTER SYSTEM SET max_pred_locks_per_transaction = 5000; " psql postgres://postgres:postgres@postgres:5432/archive -f mainnet-archive-dump-$(date +%F_0000).sql; ' # For Devnet Network, replace "mainnet" references with "devnet" in the block above depends_on: postgres: condition: service_healthy missing_blocks_guardian: image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet command: > bash -c ' curl -O https://raw.githubusercontent.com/MinaFoundation/helm-charts/main/mina-archive/scripts/missing-blocks-guardian-command.sh; export GUARDIAN_PRECOMPUTED_BLOCKS_URL=https://673156464838-mina-precomputed-blocks.s3.us-west-2.amazonaws.com/mainnet; export MINA_NETWORK=mainnet; export PG_CONN=postgres://postgres:postgres@postgres:5432/archive; while true; do bash missing-blocks-guardian-command.sh; sleep 600; done ' # For Devnet Network, replace "mainnet" references with "devnet" in the block above depends_on: bootstrap_db: condition: service_completed_successfully mina_archive: image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet' restart: always command: - mina-archive - run - --postgres-uri - postgres://postgres:postgres@postgres:5432/archive - --server-port - "3086" volumes: - './archive/data:/data' depends_on: bootstrap_db: condition: service_completed_successfully mina_node: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet restart: always entrypoint: [] command: > bash -c ' mina daemon --archive-address mina_archive:3086 \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --insecure-rest-server \ --rest-port 3085 ' # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet ports: - '3085:3085' - '8302:8302' depends_on: bootstrap_db: condition: service_completed_successfully ``` Once the services are running, you can access the Mina node graphql endpoint at `http://localhost:3085/graphql` and the postgres database using `psql postgres://postgres:postgres@localhost:5432/archive`. To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` --- url: /node-operators/archive-node/getting-started --- # Archive Nodes Getting Started Mina nodes are succinct by default, so they don't need to maintain historical information about the network, block, or transactions. For some use cases, it is useful to maintain this historical data on an archive node. :::tip A zkApp can retrieve events and actions from one or more Mina archive nodes. If your smart contract needs to fetch events and actions from an archive node, see [How to Fetch Events and Actions](/zkapps/writing-a-zkapp/feature-overview/fetch-events-and-actions). ::: An archive node is a regular mina daemon that is connected to a running `mina-archive` process using the `--archive-address` flag. The daemon regularly sends blockchain data to the archive process that stores it in a [PostgreSQL](https://www.postgresql.org/) database. ## Archive Node Requirements **Software**: Supported environments include macOS, Linux (Debian 10, 11 and Ubuntu 20.04 LTS), and any host machine with Docker. **Processor**: Only x86-64 CPU architecture is supported. **Hardware**: Running an archive node does not require any special hardware. In addition to the [PostgreSQL](https://www.postgresql.org/) database requirements, running an archive node on the Mina network requires at least: - 8-core processor - 32 GB of RAM - 64 GB of free storage Running an archive node requires some knowledge of managing a PostgreSQL database instance. You must set up a database, run the archive node, connect it to a daemon, and run queries on the data. ## Install Mina, PostgreSQL, and the archive node package 1. Install the latest version of Mina. You must upgrade to the latest version of the daemon. Follow the steps in [Getting Started](../block-producer-node/getting-started). 1. Download and install [PostgreSQL](https://www.postgresql.org/download/). 1. Install the archive node package. - Ubuntu/Debian: ``` sudo apt-get install mina-archive=3.3.0-8c0c2e6 ``` - Docker: ``` minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet ``` ## Set up the archive node These steps might be different for your operating system, if you're connecting to a cloud instance of PostgreSQL, if your deployment uses Docker, or if you want to run these processes on different machines. :::caution Using the `--config` parameter ensures genesis accounts are inserted into the database, which is important to avoid gaps in account balances since the archive node stores only incremental changes. However, inserting genesis accounts can take significant time and resources. You can skip `--config` if you're connecting to devnet or mainnet and starting from an existing archive database dump rather than an empty archive. *Never* use it on long lived network such as mainnet or devnet ::: For production, run the archive database in the background, use your operating system service manager (like systemd) to run it for you, or use a postgres service hosted by a cloud provider. To run a local archive node in the foreground for testing: 1. Start a local postgres server and connect to port 5432: ```sh postgres -p 5432 -D /usr/local/var/postgres ``` For macOS: ```sh brew services start postgres ``` 1. Create a local postgres database called `archive`: ```sh psql -p 5432 --h localhost -c "create database archive" ``` 1. Load the mina archive schema into the archive database, (create_schema.sql and zkapp_tables.sql): ```sh psql -h localhost -p 5432 -d archive -f <(curl -Ls https://raw.githubusercontent.com/MinaProtocol/mina/release/3.0.2/src/app/archive/create_schema.sql) ``` 1. Start the archive process on port 3086 and connect to the postgres database that runs on port 5432: ```sh mina-archive run \ --postgres-uri postgres://localhost:5432/archive \ --server-port 3086 ``` 1. Start the mina daemon and connect it to the archive process that you started on port 3086: ``` mina daemon \ ..... --archive-address 3086 ``` To connect to an archive process on another machine, specify a hostname with `` i.e. `154.97.53.97:3086`. 1. Install Docker on your machine. For more information, see [Docker](https://docs.docker.com/get-docker/). 2. Pull the archive node image from Docker Hub. ```sh docker pull minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet ``` 3. Pull and install the postgres image from Docker Hub. ```sh docker pull postgres ``` 4. Start the postgres container and expose its networking to other containers. ```sh docker run --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d postgres ``` 5. Create a local postgres database called `archive`. ```sh docker exec -it postgres createdb -U postgres archive ``` 6. Load the mina archive schemas into the archive database, (create_schema.sql and zkapp_tables.sql.) ```sh curl -Ls https://raw.githubusercontent.com/MinaProtocol/mina/1551e2faaa246c01636908aabe5f7981715a10f4/src/app/archive/create_schema.sql | docker exec -i postgres psql -U postgres -d archive curl -Ls https://raw.githubusercontent.com/MinaProtocol/mina/1551e2faaa246c01636908aabe5f7981715a10f4/src/app/archive/zkapp_tables.sql | docker exec -i postgres psql -U postgres -d archive ``` 7. Create a local directory to store the archive node data. ```sh mkdir -p /tmp/archive ``` 8. Start the archive node. ```sh docker run \ --name archive \ -p 3086:3086 \ -v /tmp/archive:/data \ minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet \ mina-archive run \ --postgres-uri postgres://postgres:postgres@postgres:5432/archive \ --server-port 3086 ``` 9. Start the mina daemon and connect it to the archive process that you started on port 3086: ``` mina daemon \ ..... --archive-address 3086 ``` To connect to an archive process on another machine, specify a hostname with `` i.e. `154.97.53.97:3086`. Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services. Then, with a single command, you create and start all the services from your configuration. 1. Install Docker and Docker Compose on your machine. For more information, see [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/). 2. Pull the required images: ```sh docker pull minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet docker pull postgres ``` 3. Create a local directory to store the archive node data. ```sh mkdir -p /tmp/archive ``` 4. Create a `docker-compose.yml` file with the following contents: ```yml services: postgres: image: postgres:17 environment: POSTGRES_PASSWORD: postgres volumes: - './postgres-data:/var/lib/postgresql/data' ports: - '5432:5432' archive: image: 'minaprotocol/mina-archive:3.3.0-8c0c2e6-bullseye-mainnet' command: >- mina-archive run --postgres-uri postgres://postgres:postgres@postgres:5432/archive --server-port 3086 volumes: - '/tmp/archive:/data' ports: - '3086:3086' depends_on: - postgres ``` 5. Start the archive node. ```sh docker compose up ``` 6. Start the mina daemon and connect it to the archive process that you started on port 3086: ``` mina daemon \ ..... --archive-address 3086 ``` To connect to an archive process on another machine, specify a hostname with `` i.e. `154.97.53.97:3086`. ## Using the Archive Node Take a look at the tables in the database. To list the tables, run the `\dt` command in psql. The output will look like this: ``` List of relations Schema | Name | Type | Owner --------+-------------------------------+-------+------- public | account_identifiers | table | mina public | accounts_accessed | table | mina public | accounts_created | table | mina public | blocks | table | mina public | blocks_internal_commands | table | mina public | blocks_user_commands | table | mina public | blocks_zkapp_commands | table | mina public | epoch_data | table | mina public | internal_commands | table | mina public | protocol_versions | table | mina public | public_keys | table | mina public | snarked_ledger_hashes | table | mina public | timing_info | table | mina public | token_symbols | table | mina public | tokens | table | mina public | user_commands | table | mina public | voting_for | table | mina public | zkapp_account_precondition | table | mina public | zkapp_account_update | table | mina public | zkapp_account_update_body | table | mina public | zkapp_account_update_failures | table | mina public | zkapp_accounts | table | mina public | zkapp_action_states | table | mina public | zkapp_amount_bounds | table | mina public | zkapp_balance_bounds | table | mina public | zkapp_commands | table | mina public | zkapp_epoch_data | table | mina public | zkapp_epoch_ledger | table | mina public | zkapp_events | table | mina public | zkapp_fee_payer_body | table | mina public | zkapp_field | table | mina public | zkapp_field_array | table | mina public | zkapp_global_slot_bounds | table | mina public | zkapp_length_bounds | table | mina public | zkapp_network_precondition | table | mina public | zkapp_nonce_bounds | table | mina public | zkapp_permissions | table | mina public | zkapp_states | table | mina public | zkapp_states_nullable | table | mina public | zkapp_timing_info | table | mina public | zkapp_token_id_bounds | table | mina public | zkapp_updates | table | mina public | zkapp_uris | table | mina public | zkapp_verification_key_hashes | table | mina public | zkapp_verification_keys | table | mina (45 rows) ``` Use the `\d table_name` to look at the structure of a table in the database. For example to see the structure of the user_commands table, run the `\d user_commands` command in psql. The output will look like this: ``` Table "public.user_commands" Column | Type | Collation | Nullable | Default --------------+-------------------+-----------+----------+------------------------------------------- id | integer | | not null | nextval('user_commands_id_seq'::regclass) command_type | user_command_type | | not null | fee_payer_id | integer | | not null | source_id | integer | | not null | receiver_id | integer | | not null | nonce | bigint | | not null | amount | text | | | fee | text | | not null | valid_until | bigint | | | memo | text | | not null | hash | text | | not null | Indexes: "user_commands_pkey" PRIMARY KEY, btree (id) "user_commands_hash_key" UNIQUE CONSTRAINT, btree (hash) Foreign-key constraints: "user_commands_fee_payer_id_fkey" FOREIGN KEY (fee_payer_id) REFERENCES public_keys(id) "user_commands_receiver_id_fkey" FOREIGN KEY (receiver_id) REFERENCES public_keys(id) "user_commands_source_id_fkey" FOREIGN KEY (source_id) REFERENCES public_keys(id) Referenced by: TABLE "blocks_user_commands" CONSTRAINT "blocks_user_commands_user_command_id_fkey" FOREIGN KEY (user_command_id) REFERENCES user_commands(id) ON DELETE CASCADE ``` Review the full schema at [/archive/create_schema.sql](https://github.com/minaProtocol/mina/blob/master/src/app/archive/create_schema.sql) and [/archive/zkapp_tables.sql](https://github.com/MinaProtocol/mina/blob/berkeley/src/app/archive/zkapp_tables.sql) ## Query the database Now that you know the structure of the data, try some queries. **Example 1:** Find all blocks that were created by your public key: ``` SELECT * FROM blocks AS b INNER JOIN public_keys AS pk1 ON b.creator_id = pk1.id WHERE value = 'MY_PK' ``` **Example 2:** Find all payments received by your public key: ``` SELECT * FROM user_commands AS uc JOIN blocks_user_commands AS buc ON uc.id = buc.user_command_id JOIN public_keys AS pk ON uc.receiver_id = pk.id WHERE value = 'MY_PK' AND type = 'payment' ``` **Example 3:** Find the block at height 12 on the canonical chain: ``` WITH RECURSIVE chain AS ( (SELECT ... FROM blocks b WHERE height = (select MAX(height) from blocks) ORDER BY timestamp ASC LIMIT 1) UNION ALL SELECT ... FROM blocks b INNER JOIN chain ON b.id = chain.parent_id AND chain.id <> chain.parent_id ) SELECT ..., pk.value as creator FROM chain c INNER JOIN public_keys pk ON pk.id = c.creator_id WHERE c.height = 12 ``` **Example 3:** List the counts of blocks created by each public key and sort them in descending order" ``` SELECT p.value, COUNT(*) FROM blocks INNER JOIN public_keys AS p ON creator_id = ip.id GROUP BY p.value ORDER BY count DESC; ``` **Example 4:** List the counts of applied payments created by each public key and sort them in descending order: ``` SELECT p.value, COUNT(*) FROM user_commands INNER JOIN public_keys AS p ON source_id = p.id WHERE status = 'applied' AND type = 'payment' GROUP BY p.value ORDER BY count DESC; ``` **Example 5** Get the latest block: ``` SELECT height as blockheight, global_slot_since_genesis as globalslotsincegenesis, global_slot_since_hard_fork as globalslot, state_hash as statehash, parent_hash as parenthash, ledger_hash as ledgerhash, to_char(to_timestamp(cast ("timestamp" as bigint) / 1000) AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS') || '.' || LPAD(((cast("timestamp" as bigint) % 1000)::text), 3, '0') || 'Z' as datetime FROM blocks WHERE id in (SELECT MAX(id) FROM blocks); ``` **Example 6** Identify blocks with missing parents, between blockheight 500 and blockheight 5000 ``` SELECT height FROM blocks WHERE parent_id is null AND height >= 500 AND height <= 5000 and height > 1; ``` --- url: /node-operators/archive-node --- # About Archive Nodes Mina nodes are succinct by default, so they don't need to maintain historical information about the network, block, or transactions. An archive node is a Mina node that stores the historical chain data to a persistent data source, PostgreSQL, so it can later be retrieved. For some use cases, it is useful to maintain this historical data on an archive node. :::tip A zkApp can retrieve events and actions from one or more Mina archive nodes. If your smart contract needs to fetch events and actions from an archive node, see [How to Fetch Events and Actions](../../zkapps/writing-a-zkapp/feature-overview/fetch-events-and-actions). ::: An archive node is a regular mina daemon that is connected to a running `mina-archive` process. The mina daemon regularly sends blockchain data to the `mina-archive` process that then stores it in a [PostgreSQL](https://www.postgresql.org/) database. Running an archive node requires some knowledge of managing a PostgreSQL database instance. You must set up a database, run the archive node, connect it to a daemon, and run queries on the data. # Archive Node This section describes how to set up and run an Archive node within the Mina protocol. - [Getting Started with Archive Nodes](archive-node/getting-started) - A beginner's guide to launching an Archive Node. - [Ensuring Archive Redundancy](archive-node/archive-redundancy) - Strategies to mitigate the risk of losing archived data. --- url: /node-operators/block-producer-node/docker-compose --- # Docker Compose Block Producer This example demonstrates how to run a Mina Block Producer node using Docker Compose for the Mainnet network. The Docker Compose setup includes a Mina Block Producer node, and another script to generate a wallet key. Copy and paste the provided configuration into a `docker-compose.yml` file. Then run `docker compose up -d` to start the services, and use `docker compose logs -f` to monitor the logs. ```yaml services: generate_wallet_key: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet environment: MINA_PRIVKEY_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key chmod -R 0700 /root/.mina-config/keys chmod -R 0600 /root/.mina-config/keys/wallet-key ' volumes: - './node/mina-config:/root/.mina-config' mina_block_producer: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet restart: always environment: MINA_PRIVKEY_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --block-producer-key /root/.mina-config/keys/wallet-key ' # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet volumes: - './node/mina-config:/root/.mina-config' ports: - '8302:8302' depends_on: generate_wallet_key: condition: service_completed_successfully ``` --- url: /node-operators/block-producer-node/getting-started --- # Block Producer Getting Started :::note Before following this guide, complete the Validator Node setup — from [Requirements](/node-operators/validator-node/requirements) through [Connect to Mainnet or Devnet](/node-operators/validator-node/connecting-to-the-network). You should have a synced node and a [key pair](/node-operators/validator-node/generating-a-keypair) before proceeding. ::: ## Start the daemon Run the daemon with the `--block-producer-key` flag pointing to your wallet key: ```sh mina daemon --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --block-producer-key ~/keys/my-wallet ``` To send block rewards to a different account (e.g. a cold wallet), add the `--coinbase-receiver` flag: ```sh mina daemon --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --block-producer-key ~/keys/my-wallet \ --coinbase-receiver $RECEIVER_PUBLICKEY ``` ## Verify block production Run `mina client status` and check the `Block producers running` field: ```text Block producers running: 1 (B62q...) Coinbase receiver: Block producer Next block will be produced in: in 7.077h for slot: ... ``` --- url: /node-operators/block-producer-node/hot-cold-block-production --- # Hot and Cold Block Production Block production requires a node connected to the internet, which means the block producer's private key is exposed on an online machine. To mitigate this risk, Mina supports a hot/cold wallet pattern: - A **[hot wallet](/glossary#hot-wallet)** has its private key on an internet-connected machine. It is used to run the block producer node but should hold minimal funds. - A **[cold wallet](/glossary#cold-wallet)** has its private key stored offline (e.g. generated on an air-gapped laptop or a hardware wallet like [Ledger](https://shop.ledger.com/)). It holds the majority of your stake. By delegating from your cold wallet to your hot wallet, you can produce blocks — and earn all associated rewards — while keeping the bulk of your funds in cold storage. ## Setup You need at least two accounts: one cold wallet and one hot wallet. See [Generating a Key Pair](/node-operators/validator-node/generating-a-keypair) for key generation instructions. ### 1. Create a hot wallet Generate a key pair on your block producer machine. Do **not** use a Ledger or other hardware security module (HSM) for this key — the private key must be accessible to the mina daemon. Take note of your hot wallet public key. ### 2. Fund the hot wallet Your hot wallet must be present in the consensus ledger before it can be used for staking. - If your hot wallet address is present in the genesis ledger, no further action is needed. - Otherwise, send at least enough MINA to cover the account creation fee to your hot wallet address. ### 3. Create a cold wallet Generate a key pair using the most secure method available — preferably on a machine disconnected from the internet, or on a hardware wallet. ### 4. Fund the cold wallet Your cold wallet must be present in the consensus ledger before its stake can be counted when delegated to your hot wallet. - If your cold wallet address is present in the genesis ledger, no further action is needed. - Otherwise, send enough MINA to meaningfully participate in consensus to your cold wallet address. ### 5. Delegate from cold to hot Delegate your cold wallet's stake to your hot wallet: ```sh mina client delegate-stake \ --sender $COLD_PUBLIC_KEY \ --receiver $HOT_PUBLIC_KEY ``` If your cold wallet is on a Ledger, follow the delegate instructions in the [Mina Ledger app README](https://github.com/jspada/ledger-app-mina/tree/v1.0.0-beta.2). ### 6. Start producing blocks Follow the [Getting Started](/node-operators/block-producer-node/getting-started) guide using your hot wallet key as the `--block-producer-key`. ## Why can't I use an HSM directly? You may wonder why Mina can't let you produce blocks directly from a secure enclave or HSM. Two components of block production require the private key in ways that make this impractical: ### Finding eligible slots A block producer determines slot eligibility by evaluating a VRF (verifiable random function) with their private key. The VRF must be evaluated for your account and every account that delegates to you, for all slots within an epoch. ### Creating the blockchain SNARK When a block producer wins a slot, they must create a SNARK proof that the new block is a valid extension of the existing chain. This proof embeds VRF information using the private key — replacing the simple signature that other protocols use. Creating this proof is computationally expensive and relies on advanced cryptography that is extremely difficult, and likely impossible, to perform quickly enough inside today's secure hardware. --- url: /node-operators/block-producer-node --- # About Block Producers The role of a block producer in Mina is to achieve [consensus](https://minaprotocol.com/blog/what-is-ouroboros-samasika) and provide security to the blockchain. The block producer is responsible for creating new blocks that include recent transactions broadcast on the network and a blockchain proof that proves the current state of the chain is valid. In Mina, anyone can become a block producer. There is an unbounded number of participants with the chance of producing a block proportional to the funds staked. Funds are not locked and are not subject to slashing. In return for staking funds and generating the required blockchain proofs, blocks that are produced and included in the canonical chain are rewarded in the form of a coinbase and transaction fees, less any fees paid to purchase required [transaction SNARK work](/node-operators/snark-workers). To successfully produce a block, a block producer must have the current state of the blockchain. A block producer must have enough available compute to produce a blockchain SNARK within the slot time and be connected to peers to broadcast the generated block within an acceptable delay as defined by the network consensus parameters. ## Block Producers This section describes how to run a Block Producer on the Mina protocol. - [Getting Started](block-producer-node/getting-started) - How to install and get started running a block producer. - [Hot and Cold Block Production ](block-producer-node/hot-cold-block-production) - How to get started running a block producer. --- url: /node-operators/block-producer-node/staking-service-guidelines --- # Staking Service Guidelines The important parts of running a staking service are predicting/determining winning slots in which you can produce blocks and paying out participants. The Mina protocol does not automatically payout rewards to delegates, so part of running a staking service is manually paying out participants by [sending many transactions](#sending-many-transactions). This document aims to explain the different components that you should think about when managing those payouts. Specifically, this document provides an understanding of odds of winning blocks, gathering data from the ledger for later use, and computing relevant staking payout information from this data. ## Staking Rewards The coinbase reward for producing a block is 720 tokens. ## Dumping Staking Ledgers In order to compute odds of winning a block for a given epoch, or to retroactively compute the coinbase reward a given account would receive, you need to have the staking ledger from that epoch. Mina daemons only keep around the staking ledger for the current epoch and the staking ledger for the next epoch, so if you want to capture a staking ledger for an epoch, you need to do it before or during that epoch. The `mina ledger export` command can be used to export ledgers from a running daemon: ``` Print the specified ledger (default: staged ledger at the best tip). Note: Exporting snarked ledger is an expensive operation and can take a few seconds mina ledger export STAGED-LEDGER|SNARKED-LEDGER|STAKING-EPOCH-LEDGER|NEXT-EPOCH-LEDGER === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--plaintext] Use plaintext input or output (default: JSON) (alias: -plaintext) [--state-hash STATE-HASH] State hash, if printing a staged ledger (default: state hash for the best tip) (alias: -state-hash) [-help] print this help text and exit (alias: -?) ``` It requires an argument to identifier of the ledger you wish to export. The table below describes what each of these identifiers represent.
| Identifier | Description | |----------------------|-----------------------------------------------------------------| | staking-epoch-ledger | The staking ledger for the current epoch. | | next-epoch-ledger | The staking ledger for the next epoch (epoch after current). | | staged-ledger | The most recent staged ledger (from the best tip of that node). | | snarked-ledger | The most recent snarked ledger (from the best tip of that node).|
In order to ensure you always have each staking ledger available for use after epochs have expired, we recommend exporting the staking-epoch-ledger every (7140 × 3) ÷ 60 = 357 hours (there are 7140 slots in an epoch, and each slot is 3 minutes long). By default, ledgers are exported as json data. See `mina ledger export -help` for documentation of flags which will enable other formats. When output as json, the ledger will be represented as an array of account objects. Below is an example of what an account object in json looks like. ```json { "pk": "B62qrwZRsNkU39TrGpFwDdpRS2JaCB2yFZKMFNqLFYjcqGE5G5fWA8p", "balance": "17000", "delegate": "B62qrwZRsNkU39TrGpFwDdpRS2JaCB2yFZKMFNqLFYjcqGE5G5fWA8p", "token": "1", "token_permissions": {}, "receipt_chain_hash": "2mzbV7WevxLuchs2dAMY4vQBS6XttnCUF8Hvks4XNBQ5qiSGGBQe", "voting_for": "3NK2tkzqqK5spR2sZ7tujjqPksL45M3UUrcA4WhCkeiPtnugyE2x", "permissions": { "stake": true, "edit_state": "signature", "send": "signature", "set_delegate": "signature", "set_permissions": "signature", "set_verification_key": "signature" } } ``` For a running staking service, you are interested in the accounts which you control and the accounts which are staking to accounts you control. As an example, if we only had one account in our staking service, we could grab all the accounts we are interested in for a ledger using a command like: ```sh mina ledger export staking-epoch-ledger | jq "$(cat < A standardized API for blockchain integration — query historical data, build transactions, and integrate with exchanges. [Rosetta API](https://www.rosetta-api.org/) (rebranded as [Mesh](https://docs.cdp.coinbase.com/mesh/docs/welcome/) by Coinbase) is an open-source specification and set of tools that make deploying and interacting with blockchains quick and easy. Mina implements a subset of the Rosetta specification — not all endpoints defined in the spec are available. Mina's Rosetta implementation is primarily used by exchanges to integrate MINA deposits, withdrawals, and balance queries. :::note The Rosetta API is auxiliary to Mina's existing [GraphQL API](/node-operators/reference/mina-cli-reference) and [Archive Node](/node-operators/archive-node). While GraphQL provides access to current network state, historical and persistence data requires the Archive database. Rosetta bundles both data sources behind a standardized interface and exists primarily to satisfy exchange integration requirements. ::: ## Architecture The Rosetta stack consists of four components that work together: | Component | Default Port | Description | |---|---|---| | **Mina Daemon** | 8302 (P2P), 3085 (GraphQL) | Syncs with the network, produces/validates blocks | | **Archive Node** | 3086 | Stores historical block data in PostgreSQL | | **PostgreSQL** | 5432 | Database backend for the archive node | | **Rosetta API** | 3087 (online), 3088 (offline) | Translates Mina data into the Rosetta specification | All ports listed above are defaults and can be overridden via configuration. When using Docker, these are the ports inside the container — map them to your desired host ports with `-p`. ## Installation There are three ways to run Rosetta, depending on your needs. ### Option 1: All-in-One Docker Image (Recommended for getting started) The all-in-one image bundles the daemon, archive node, PostgreSQL, and Rosetta API into a single container. It automatically initializes the archive database from public o1Labs backups. **Requirements:** Docker with at least 12 GB RAM allocated (16 GB recommended). #### Mainnet ```bash docker run -it --rm --name rosetta \ --entrypoint=./docker-start.sh \ -p 8302:8302 -p 3085:3085 -p 3086:3086 -p 3087:3087 \ minaprotocol/mina-rosetta:3.3.1-7b34378-noble-mainnet ``` #### Devnet ```bash docker run -it --rm --name rosetta \ --entrypoint=./docker-start.sh \ -p 8302:8302 -p 3085:3085 -p 3086:3086 -p 3087:3087 \ -e MINA_NETWORK=devnet \ -e PEER_LIST_URL=https://bootnodes.minaprotocol.com/networks/devnet.txt \ minaprotocol/mina-rosetta:3.2.0-97ad487-bookworm-devnet ``` Initial sync typically takes between 20 minutes and 1 hour depending on your hardware and network connection. You can check sync status with: ```bash docker exec rosetta mina client status ``` #### Environment Variables The all-in-one image supports the following environment variables for customization: | Variable | Default | Description | |---|---|---| | `MINA_NETWORK` | `mainnet` | Network to connect to (`mainnet` or `devnet`) | | `PEER_LIST_URL` | Network-specific seed list | URL for the peer list | | `LOG_LEVEL` | `Debug` | Log level (`Info`, `Debug`, `Warn`, `Error`) | | `MINA_GRAPHQL_PORT` | `3085` | GraphQL API port | | `MINA_ARCHIVE_PORT` | `3086` | Archive node port | | `MINA_ROSETTA_ONLINE_PORT` | `3087` | Rosetta online API port | | `MINA_ROSETTA_OFFLINE_PORT` | `3088` | Rosetta offline API port | | `POSTGRES_USERNAME` | `pguser` | PostgreSQL username | | `POSTGRES_DBNAME` | `archive` | PostgreSQL database name | | `POSTGRES_DATA_DIR` | `/data/postgresql` | PostgreSQL data directory | | `MINA_ARCHIVE_DUMP_URL` | `https://storage.googleapis.com/mina-archive-dumps` | Base URL for archive database dumps | | `MINA_CONFIG_DIR` | `/data/.mina-config` | Mina configuration directory | ### Option 2: Docker Compose (Recommended for production) For production deployments, use Docker Compose to run each component as a separate container. This gives you more control over resource allocation, logging, and restarts. For production deployments, a complete Docker Compose configuration with all four services (PostgreSQL, archive node, Mina daemon, and Rosetta API) is available in the [Rosetta Docker Compose guide](/node-operators/rosetta/docker-compose). ### Option 3: Debian Packages (Manual setup) You can install each component individually via Debian packages. This is useful if you already run a Mina daemon and archive node and only need to add the Rosetta API. ```bash # Add the Mina repository (if not already configured) echo "deb [trusted=yes] http://packages.o1test.net/ noble stable" | sudo tee /etc/apt/sources.list.d/mina.list sudo apt-get update # Install the Rosetta package for your network sudo apt-get install mina-rosetta-mainnet # or: sudo apt-get install mina-rosetta-devnet ``` Then run the Rosetta API pointing to your existing daemon and archive database: ```bash mina-rosetta \ --archive-uri postgres://:@:/ \ --graphql-uri http://localhost:3085/graphql \ --log-json \ --port 3087 ``` This requires a running [Mina daemon](/node-operators/block-producer-node) and [archive node](/node-operators/archive-node) with a populated PostgreSQL database. ## Offline Mode The Rosetta Construction API requires an "offline" endpoint that can build and sign transactions without network access. Use the standalone entrypoint for this: ```bash docker run -it --rm --name rosetta-offline \ --entrypoint=./docker-standalone-start.sh \ -p 3088:3088 \ minaprotocol/mina-rosetta:3.3.1-7b34378-noble-mainnet ``` This starts only the Rosetta API process — no daemon, archive, or database. Point your Construction API calls to this endpoint for offline operations. ## Demo Mode For development and testing, the demo mode launches a local sandbox with a simple genesis ledger and all components running inside a single container: ```bash docker run -it --rm --name rosetta-demo \ --entrypoint=./docker-demo-start.sh \ -p 3085:3085 -p 3087:3087 \ minaprotocol/mina-rosetta:3.3.1-7b34378-noble-mainnet ``` This creates an isolated network with no external connectivity — useful for developing integrations before connecting to mainnet or devnet. ## Available Images | Network | Image | Notes | |---|---|---| | **Mainnet (noble)** | `minaprotocol/mina-rosetta:3.3.1-7b34378-noble-mainnet` | amd64 | | **Mainnet (bookworm)** | `minaprotocol/mina-rosetta:3.3.1-7b34378-bookworm-mainnet` | Also available for arm64 | | **Devnet (bookworm)** | `minaprotocol/mina-rosetta:3.2.0-97ad487-bookworm-devnet` | Latest devnet | Images are published on [Docker Hub](https://hub.docker.com/r/minaprotocol/mina-rosetta/tags). ## Verifying the API Once your node is synced, verify the Rosetta API is working. **List available networks:** ```bash curl -s http://localhost:3087/network/list \ -H 'Content-Type: application/json' \ -d '{"metadata":{}}' | jq . ``` **Get network status:** ```bash curl -s http://localhost:3087/network/status \ -H 'Content-Type: application/json' \ -d '{"network_identifier": {"blockchain": "mina", "network": "mainnet"}}' | jq . ``` **Query an account balance:** ```bash curl -s http://localhost:3087/account/balance \ -H 'Content-Type: application/json' \ -d '{ "network_identifier": {"blockchain": "mina", "network": "mainnet"}, "account_identifier": {"address": ""} }' | jq . ``` ## Building Your Own Image For most users, the official images are sufficient. If you need to build a custom image, see the [Rosetta README](https://github.com/MinaProtocol/mina/blob/master/src/app/rosetta/README.md) in the Mina repository for build instructions. ## Questions and Support - Post questions in [Mina GitHub Discussions](https://github.com/MinaProtocol/mina/discussions) - Report bugs on [GitHub Issues](https://github.com/MinaProtocol/mina/issues) - Join the [Mina Discord](https://discord.gg/minaprotocol) for community support --- url: /node-operators/delegation-program/foundation-delegation-program --- # Mina Foundation Delegation Program How to Participate in the Mina Foundation Delegation Program Learn how to receive a delegation from Mina Foundation. :::info **PLEASE READ:** This affects the submission of uptime data and the Performance Score results for receiving a delegation. The sidecar tracking system was **discontinued on June 14th 2024**. Please use the **SNARK-work-based** uptime tracking system. - [Instructions for the SNARK-work-based uptime system](./uptime-tracking-system) Please follow the latest updates and post questions in the [#delegation-program](https://discord.com/channels/484437221055922177/808895957978447882) channel on Mina Protocol Discord. ::: This Delegation Program is an implementation of the Mina Foundation Delegation Policy, the official policy on the delegations of MINA tokens from the Mina Foundation (referred to as “Foundation” below). If you are a block producer looking to participate in the Mina Foundation Delegation Program, this page explains how the program works and how to send uptime data and pay back rewards. :::note There are two delegation programs in Mina's ecosystem — one from the Mina Foundation and [one from o1Labs](https://www.o1labs.org/blog/delegation-policy-2024#o1labs-delegation-program-policy), Mina's ecosystem partner. This page details the program only for the Mina Foundation. ::: ## Overview Mina Foundation is committed to decentralizing the governance of the Mina protocol. In order to delegate their voting power, Mina Foundation delegates its tokens to community members through the [Mina Foundation Delegation Program](https://minaprotocol.com/blog/mina-foundation-delegation-policy). In the Delegation Program, Mina Foundation delegates its tokens to a number of validators. As the validators earn staking rewards associated with the delegation, they must return the remaining rewards to Mina Foundation, **but can keep 8% of the staking rewards**. Block producers are selected on a quarterly basis, known as a delegation cycle, based on their Performance Scores (see below) and requirements outlined in the [Mina Foundation Delegation Policy](https://minaprotocol.com/blog/mina-foundation-delegation-policy). ## Eligibility Requirements ### How do I participate in the program? If you are new to the Mina Foundation Delegation Program, please make sure you have fulfilled the following requirements in order to be eligible for receiving a delegation from the Foundation's token allocation. #### Step 1: Complete the application Review the [Mina Foundation Delegation Policy](https://minaprotocol.com/blog/mina-foundation-delegation-policy) then complete [the application form](https://docs.google.com/forms/d/e/1FAIpQLSduM5EIpwZtf5ohkVepKzs3q0v0--FDEaDfbP2VD4V6GcBepA/viewform). You will be asked to share your public key for receiving a delegation in the application. #### Step 2: Run the Uptime Tracking System The uptime tracking system sends recent blockchain data from your block producer node's perspective to a service. This service verifies whether this recent data is synced with the chain. If it is synced, it means your node is online. Instructions for how to run the uptime tracking system: - [SNARK-based Uptime System](./uptime-tracking-system) #### Step 3: Pass the KYC/AML requirement (only if selected for delegation) In order to receive a delegation, you must also meet the KYC/AML requirements of Mina Foundation. If you have recently been selected as a validator who will be receiving a delegation, but have not yet completed any of the KYC/AML requirements, please look out for an email with further instructions. For more details on this requirement, please review the policies outlined in the [Mina Foundation Delegation Policy](https://minaprotocol.com/blog/mina-foundation-delegation-policy). :::note You can only complete this step if you’re receiving a delegation for the next cycle. When you are selected for a delegation, you will be contacted with instructions on how to proceed with completing the KYC/AML requirement. ::: ## Program Guidelines Now that you understand how to become eligible to participate in the program, please review the following guidelines to better understand how to receive a delegation and send back rewards. ### How do I get selected for a delegation? #### Measuring Uptime Performance Score The **Uptime Performance Score** is an important factor for selecting the public keys to receive a Mina Foundation Delegation Program delegation from a token provider. **Uptime** is the measurement of when your block producer node is online. In the Mina Foundation Delegation Program, uptime is measured in 20-minute windows. If your block producer node is online at any time within a given 20-minute window, you will be marked as online for that period. :::note You may run more than one node with the same block producer key if you want to increase your chances of remaining online. ::: :::tip To participate in the delegation program, your block producer node must stay online and connected to the network at all times. If you cannot maintain uptime, consider [delegating your stake](/node-operators/validator-node/staking-and-snarking) instead. ::: **Uptime Performance** is the percentage over a time period in which a block producer node is online and operational. The time period of Mina Foundation's delegation programs is 90 days. This percentage is based on all possible 20-minute windows over the last time period. ### How do I track my performance score? The **leaderboard** shows the ranking of block producers participating in the delegation program based on uptime performance. The sooner you fix issues with your nodes sending uptime data, the sooner you'll be rewarded with a better uptime and position on the leaderboard. Your position on this leaderboard is an important factor in your public key being selected to receive delegation from Mina Foundation. See the following uptime leaderboards for the latest uptime performance scores: - Official Leaderboard: https://uptime.minaprotocol.com - Community Leaderboards: - Minataur: https://minataur.net/uptime ### What happens after I receive a delegation? #### Payout Procedure As per the Mina Foundation Delegation policy, there is a mandatory requirement on delegatees to use the latest version of the [payout script](https://github.com/jrwashburn/mina-pool-payout) to manage the return of rewards. This payout script includes: - Mapping of delegating wallet addresses with the correct return wallet address - Calculation of the Reward amounts and paybacks of the remaining rewards to the delegators. - Specific memo which includes the md5 hash of Pool’s Public Key (MD5 hash) For more details and to review the script, see the [README](https://github.com/jrwashburn/mina-pool-payout/blob/main/README.md) file in the `mina-pool-payout` repository. #### Payout Addresses You must return rewards to the address specified in the [Mina Delegation Program Return Addresses](https://docs.google.com/spreadsheets/d/1Fm4XSS9Xu4eWAhpM06sdySUKvLClR5SculXfP5o5sSc/edit?usp=sharing) mapping document. This will be covered when running the script in managing reward payback. #### Payout Frequency Rewards must be distributed at least once for a given epoch. You must send one payment in the amount of your obligation to the correct address specified in the [Mina Delegation Program Return Addresses](https://docs.google.com/spreadsheets/d/1Fm4XSS9Xu4eWAhpM06sdySUKvLClR5SculXfP5o5sSc/edit?usp=sharing) mapping document and if applicable, send the correct amount to the burn address. Both payments should have a memo field with the md5 hash value of your block producer public key. This is the easiest method to avoid confusion in tracking payments and will reduce the likelihood you will be incorrectly flagged as delinquent. All the rewards for epoch N must be delivered (ie. accepted in a block, not just sent) no later than slot number 3,500 of the next epoch. This gives you about a week to sort out these payments. ### How do I calculate the reward payout? For reference, this explanation describes how reward returns are calculated. For details, see the [implementation](https://github.com/jrwashburn/mina-pool-payout/blob/main/src/core/payoutCalculator/PayoutCalculatorIsolateSuperCharge.ts) code. #### Reward Specifications You must send back at least the amount specified by this mechanism. At the end of each epoch, do all of the following: 1. Compute the total stake delegated to your account for the epoch 2. Compute the share of stake from the token provider (from both accounts) by dividing the token provider delegation by the total stake. (i.e. `provider_share = provider_delegation / total_stake`). The resulting share should be between 0 and 1. 3. For each block produced that has a non-zero block-reward on the canonical chain rewards must be calculated based on 720 MINA. 4. Calculate the Mina Foundation payout by multiplying the coinbase reward (equal to `720 MINA` ) by the provider share calculated in the previous step minus an 8% percent fee. (i.e. `payout = (provider_share * 0.92) * 720)`. 5. Send a transaction to the token provider accounts with the appropriate payout and memo - please follow the rules in the "Payout Attribution" section with your transaction. More details in the following source code parts: [PayoutCalculatorIsolateSuperCharge.ts](https://github.com/jrwashburn/mina-pool-payout/blob/7f00dbd9e693f76ea6a950c29862120a170625a9/src/core/payoutCalculator/PayoutCalculatorIsolateSuperCharge.ts#L126) and [ConfigurationManager.ts](https://github.com/jrwashburn/mina-pool-payout/blob/7f00dbd9e693f76ea6a950c29862120a170625a9/src/configuration/ConfigurationManager.ts#L21C15-L21C15). The block producer can keep all of the transaction fees or divide them equally amongst the other members of the pool. :::tip The canonical chain will be calculated as 12 blocks behind any tip at slot 3,500 of the next epoch. ::: #### Example of a Reward Payout Calculation Consider the following: - Account A has 2 million MINA - Account B is controlled by the Mina Foundation and has 6 million MINA which are delegated to Account A via the Delegation Program. - Account C is controlled by a third party and has 2 million MINA. This account also delegates to Account A and has also agreed to Account A retaining 8% of the staking rewards. In this example, the total amount of stake for Account A is 10 million calculated by adding up the balances from all the accounts. Now let's consider Epoch 5. The share of the stake from the Foundation is `6 million MINA / 10 million MINA = 0.6` or 60%. The share of the stake from Account B is `2 million MINA / 10 million MINA = 0.2` or 20%. 3 blocks are produced in this epoch that end up on the canonical chain. The blocks were won by Account A. 1. Account A retains, 0.2 x 720 MINA x 3 blocks = 432 MINA. 2. Mina Foundation, Account B, payout would be: (0.6 x 0.92) x 720 MINA x 3 blocks = 1,192.32 MINA. 3. Account A retains 8%, (0.6 x 0.08) x 720 MINA x 3 blocks = 103.68 MINA. 3. Account C payout would be: (0.2 x 0.92) x 720 MINA x 3 blocks = 397.44 MINA. 4. Account A retains 8%, (0.2 x 0.08) x 720 MINA x 3 blocks = 34.56 MINA ### Relevant Links - [Mina Foundation Delegation Policy](https://minaprotocol.com/blog/mina-foundation-delegation-policy) - [SNARK-based Uptime System](/node-operators/delegation-program/uptime-tracking-system) #### Need any help? Post your questions in the [#delegation-program](https://discord.com/channels/484437221055922177/808895957978447882) channel on the Mina Protocol Discord. --- url: /node-operators/delegation-program --- # Delegation Program The Mina Foundation Delegation Program enables block producers to receive token delegations from the Mina Foundation and earn staking rewards. :::info The sidecar tracking system was **discontinued on June 14th 2024**. Please use the **SNARK-work-based** uptime tracking system. See [Uptime Tracking System](/node-operators/delegation-program/uptime-tracking-system) for setup instructions. ::: - **[Foundation Delegation Program](/node-operators/delegation-program/foundation-delegation-program)** -- Eligibility requirements, performance scoring, payout procedures, and reward calculations. - **[Uptime Tracking System](/node-operators/delegation-program/uptime-tracking-system)** -- Instructions for the SNARK-based uptime tracking system used to measure node uptime. ## Related - [Staking and Snarking](/node-operators/validator-node/staking-and-snarking) -- How staking and delegation work on Mina - [Block Producers](/node-operators/block-producer-node) -- Getting started with block production --- url: /node-operators/delegation-program/uptime-tracking-system --- # Uptime Tracking System Instructions for the SNARK-based uptime tracking system. Learn how to set up the uptime tracking system for the Mina Foundation Delegation Program :::info **PLEASE READ:** This affects the submission of uptime data and the Performance Score results for receiving a delegation. The sidecar tracking system was **discontinued on June 14th 2024**. Please use the **SNARK-work-based** uptime tracking system. - [Instructions for the SNARK-work-based uptime system](./uptime-tracking-system) Please follow the latest updates and post questions in the [#delegation-program](https://discord.com/channels/484437221055922177/808895957978447882) channel on Mina Protocol Discord. ::: In order to maintain eligibility for various grants and the Mina Foundation Delegation Program, you must connect to our uptime tracking endpoint to run the SNARK-work-based uptime tracking system with your daemon to report node uptime. If you are required to keep your node online for a grant or specific program, you must run a small uptime tracking program that will report your daemon's uptime. This tutorial will walk you through the process of installing, configuring and running the uptime tracking system. :::note

We recommend that you save some of your SNARK work data logs. You can also share the logs with us if you’re interested in helping out with data checks.

::: ### Pre-requisites Make sure you updated your node to at least release (3.0.0+): ## How to set up the uptime system The SNARK-work-based uptime system is built into the mina daemon. The new uptime tracking system no longer requires importing your keypair and supports a new flag `--uptime-submitter-key`, which takes the path to your private key, just like `--block-producer-key`. To get started, pass in the following information to the daemon: - The path to the private key with the flag: `--uptime-submitter-key ` - The URL of our testing backend server with the flag: `--uptime-url https://uptime-backend.minaprotocol.com/v1/submit` - The password for the keypair associated with the given public key has the environment variable `UPTIME_PRIVKEY_PASS=`. If you are using a .mina-env file on Debian then this value should be on its own line, not included in `EXTRA_FLAGS=`. Here’s an example of what your .mina-env file should look like for Debian: ~~~ EXTRA_FLAGS="--block-producer-key /home/mina/my-wallet --uptime-submitter-key /home/mina/my-wallet --uptime-url https://uptime-backend.minaprotocol.com/v1/submit" UPTIME_PRIVKEY_PASS= MINA_PRIVKEY_PASS= LOG_LEVEL=Info FILE_LOG_LEVEL=Debug ~~~ ### Relevant Links - [Latest Release Notes for Mina Protocol](https://github.com/MinaProtocol/mina/releases) - [Mina Foundation Delegation Policy](https://minaprotocol.com/blog/mina-foundation-delegation-policy) - [Mina Docs: Mina Foundation Delegation Program](/node-operators/delegation-program) #### Need any help? Post your questions in the [#Delegation-Program](https://discord.gg/ywDzwmGABT) channel on Discord. --- url: /node-operators/downgrading-to-older-versions --- # Downgrading to Older Versions If you are running a Mina node on a version above 3.3.0 and need to roll back to 3.3.0 or below, you can convert the on-disk state in place using `mina-storage-converter`. This avoids a full rebootstrap from a remote S3 ledger bucket, which can save significant time. ## When is downgrading needed? Downgrading is typically necessary when a fork fails and there is a RocksDB version bump between the stop slot release and the pre-stop slot release. In such cases, the development team will notify node operators that a downgrade is required to continue operating on the correct chain. ## Debian/Ubuntu ### 1. Stop the Mina daemon Ensure your Mina node is fully shut down before proceeding: ```sh mina client stop daemon ``` Or however you normally stop your node process. Verify it is no longer running before continuing. ### 2. Install storage toolbox packages Install the required toolbox packages that provide `mina-storage-converter` and the RocksDB scanners: ```sh sudo apt-get install -y mina-daemon-storage-toolbox mina-daemon-recovery-storage-toolbox ``` ### 3. Convert on-disk state Run `mina-storage-converter` to convert the local database to the format expected by the older version. ```sh mina-storage-converter \ --node-dir ${NODE_DIR} \ --current-scanner /usr/lib/mina/storage/*/${SOURCE_VERSION}/mina-rocksdb-scanner \ --stable-scanner /usr/lib/mina/storage/*/${TARGET_VERSION}/mina-rocksdb-scanner ``` Where: - `NODE_DIR` is the path to your node's config directory. This is usually `~/.mina-config` if you haven't set it explicitly. - `SOURCE_VERSION` is the version you are downgrading from. - `TARGET_VERSION` is the version you are downgrading to (e.g. `3.3.0`). The `*` wildcard lets bash resolve the RocksDB version directory automatically, so you don't need to know which RocksDB version is bundled with each Mina release. The tool will prompt for confirmation before making changes. ### 4. Install the target version Install the older Mina package. For example, to install 3.3.0: ```sh sudo apt-get install --allow-downgrades -y mina-mainnet=3.3.0 ``` ### 5. Start the Mina daemon Start your node as usual: ```sh mina daemon ${YOUR_EXTRA_DAEMON_ARGS_HERE} ``` Your node should resume from the converted local state without needing to rebootstrap. ## Docker On-disk state conversion is only possible if your `mina-config` directory is persisted as a volume outside the container (e.g. via `--mount "type=bind,source=$(pwd)/.mina-config,dst=/root/.mina-config"`). :::caution If your `mina-config` is not persisted outside of the container, there is no way to convert the on-disk state. You will need to rebootstrap from scratch after switching to the older image. ::: Since the Docker image is a Debian/Ubuntu environment with the Mina Debian package installed, you can run the same conversion steps inside the container. The default `NODE_DIR` inside the container is `/root/.mina-config`. ### 1. Stop the running container Assume your mina daemon container is running with name `mina-node` ```sh docker stop mina-node ``` ### 2. Install toolbox packages and run the converter Use the current (newer) image to install the toolbox packages and run the conversion against your mounted `mina-config` volume: ```sh docker run -it --rm \ --entrypoint bash \ --mount "type=bind,source=$(pwd)/.mina-config,dst=/root/.mina-config" \ minaprotocol/mina-daemon:${SOURCE_VERSION}-bullseye-mainnet \ -c "apt-get update && apt-get install -y mina-daemon-storage-toolbox mina-daemon-recovery-storage-toolbox && mina-storage-converter --node-dir /root/.mina-config --current-scanner /usr/lib/mina/storage/*/${SOURCE_VERSION}/mina-rocksdb-scanner --stable-scanner /usr/lib/mina/storage/*/${TARGET_VERSION}/mina-rocksdb-scanner" ``` ### 3. Start a new container with the target version Remove the old container and start with the target image: ```sh docker rm mina-node docker run --name mina-node -d \ -p 8302:8302 \ --restart=always \ --mount "type=bind,source=$(pwd)/.mina-config,dst=/root/.mina-config" \ minaprotocol/mina-daemon:${TARGET_VERSION}-bullseye-mainnet \ daemon ${YOUR_EXTRA_DAEMON_ARGS_HERE} ``` Your node should resume from the converted local state without needing to rebootstrap. --- url: /node-operators/exchange-operators --- # Exchange Operators Exchange operators are node operators who run additional infrastructure for blockchain integration. To list MINA on your exchange, you need to run a Mina node with archive and Rosetta API support. This page provides an overview of the components involved and links to the relevant setup guides. ## Components ### Validator Node A Mina daemon connected to the network. This is the base requirement for any node operator. See [Validator Node](/node-operators/validator-node) for setup instructions. ### Archive Node An archive node stores the full history of the blockchain in a PostgreSQL database. Exchanges need this to query historical transactions and track deposits. - [Archive Node](/node-operators/archive-node) — set up and run an archive node ### Rosetta API [Rosetta](https://www.rosetta-api.org/) is a standardized API for blockchain integration. It is the recommended way to integrate MINA deposits, withdrawals, and balance queries. - [Rosetta API Overview](/node-operators/data-and-history/rosetta) — architecture and available endpoints - [Run with Docker](/node-operators/rosetta/run-with-docker) — quickest way to get started - [Docker Compose](/node-operators/rosetta/docker-compose) — production setup with all services - [Build from Sources](/node-operators/rosetta/build-from-sources) — build and run from source - [Code Samples](/node-operators/rosetta/samples) — example integrations for deposits, withdrawals, and block scanning ## FAQ See the [Exchange Integration FAQ](/node-operators/faq#exchange-integration) for answers to common questions about listing MINA, account creation fees, transaction memos, staking, and more. --- url: /node-operators/faq --- # FAQ ## General ### What is Mina Signer? The [Mina Signer](https://github.com/o1-labs/o1js/blob/main/src/mina-signer/README.md) NodeJS SDK allows you to sign strings, payments, and delegations using Mina's key pairs for various specified networks. The Mina Signer supersedes the deprecated Client SDK. ## SNARKs and SNARK Workers ### If I run a SNARK worker, how do I get paid for SNARKs that I generate? Block producers (the validators who add new blocks to the blockchain) are required to buy SNARKs from the network (called the snarketplace) and pay out some of their block reward as fees to the SNARK workers who generated SNARKs. This workflow creates a secondary incentive mechanism in the network to reward nodes that help compress transactions. ### Is generating SNARKs similar to Proof-of-Work (PoW) mining? No, they are different in several ways: - SNARK proof-of-work is deterministic, while PoW mining requires randomly calculating hashes to try and solve a puzzle. There is no luck element in SNARK work — if a SNARK worker wants to generate a SNARK of a transaction, they only need to generate the proof once. This means SNARK work is much less expensive and less environmentally wasteful, as the compute is all spent towards a productive goal. - There is no difficulty increase for SNARK work, as there is with PoW mining. In fact, as SNARK constructions, and proof generation times improve, the difficulty can actually decrease. - SNARK work is not directly involved in consensus. SNARK workers play no role in determining the next state of the blockchain. Their role is to simply generate SNARKs of transactions observed in the network - As a SNARK worker, there is no requirement for uptime. PoW miners need to run their rigs non-stop to ensure they don't miss out on a potential block. SNARK workers can come online and offline as they please — it is more like Uber, where there is always be work to be done, and nobody needs to say ahead of time when they want to work. ### Why have my SNARKs not been included? (A.K.A. How should I price my SNARKs?) Even though your SNARK worker might be producing SNARKs at a breakneck pace, if someone else produces a cheaper proof for a particular job you have already completed, their SNARK is preferred due to its lower fee. Pricing your SNARKs is a delicate balance between the cost of compute, the market environment (demand for SNARKs), your SNARK throughput, and the speed at which each of your SNARK worker processes can produce SNARKs. Sometimes, it might even be economically prudent to turn off your SNARK worker altogether until the market improves. ### Will SNARK workers require more storage and computing power over time? What about compared to Mina full nodes? SNARK workers will not need more storage or computing power over time. SNARK workers simply query the mempool for pending transactions requiring SNARK proofs, and then generate said proof -- this does not require syncing historical data. In addition, the underlying proving cost of SNARK work doesn't get more expensive with time. If we are comparing SNARK worker nodes with full nodes on Mina, then yes SNARK workers benefit from specialized hardware as generating SNARK proofs can be compute intensive. Again, however, with the explosion of SNARK research, this is likely to change and become more accessible to consumer hardware. ### What is the difference between a SNARK, a SNARK proof, and SNARK work? SNARKs are a very overloaded term. When you read **SNARK**, it could be referring to the concept of succinct non-interactive proof systems (for example, SNARKs vs Bulletproofs), the specific technical implementation of the proof system (for example, the construction, the circuit, or the prover), or the individual instance of the proof itself (for example, the blockchain SNARK). The general terminology is: - SNARK: the general concept of succinct, non-interactive zero knowledge proofs - SNARK circuit: the specific circuit and prover, as pertaining to an app - SNARK proof: an individual proof that is generated by a SNARK prover - SNARK work: a Mina protocol data structure that is a wrapper around one or two SNARK proofs and a price to be paid to the SNARK worker that generated the proof or proofs ### Is there any concern about a single large SNARK worker dumping work in the snarketplace, and then raising prices after monopolizing the market? In economics, there is a pricing strategy called [predatory pricing (or dumping)]() where one supplier of a product seeks to exhaust competing suppliers in the market by undercutting the market price. The supplier prices their goods much cheaper than the market rate in order to drive out competitors, even if it means incurring short-term losses. After the market has been cleared, the dominant supplier then increases prices [above competitive market rates](https://en.wikipedia.org/wiki/Supracompetitive_pricing), as competition has been extinguished. However, this strategy is effective only in markets where there are high barriers to entry. Meaning, competitors who were crowded out in the predation stage are unable to rejoin the market. This is not the case for SNARK work because the barriers to entry are low. Anyone who has spare compute can join the snarketplace and produce as little as one SNARK work and profit on that unit of work. The only barrier to entry is the initial capital expense on hardware, but hardware requirements are low so that users with spare equipment can come online and participate. If any SNARK worker succeeds in driving out the market and increases prices, newcomers are anticipated to reappear and drive prices back down. ### Does speed of producing SNARKs matter? If my computer is slower, will I be at a disadvantage? No, provided that the SNARK work produced is still required by block producers, it doesn't matter who produced it first — only the price matters to block producers. The caveat here is that earlier inclusion into the SNARK mempool is obviously beneficial, as block producers are likely to "see" the work earlier. However, you can envision a scenario where a set of SNARK workers are favored because they produced the most number of SNARK works that are profitable, and buying proofs from as few entities as possible would allow for more transactions to be included in any block. There is also a threshold at which time becomes a factor, but this scenario applies only to very underpowered devices. ### Will a full node need to store all intermediate SNARK proofs? Will the storage requirements grow linearly with blocks? No, when a new block is generated, Mina computes the proof recursively over the prior proof and the new block. This is the advantage of recursive composition -- at any given time, nodes need to store only the most recent proof. Intermediate proofs are not needed. For historical clarity on how this architecture emerged, see the [Using zkSNARKs to create a blockless blockchain](https://www.youtube.com/watch?v=eWVGATxEB6M) talk. ### How do you control or limit the number of threads that SNARK workers use? When you start the mina daemon, use the `-snark-worker-parallelism` flag. This flag is equivalent to setting `OMP_NUM_THREADS`, but doesn't affect block production. ## Exchange Integration #### Where can I find third-party audit reports for Mina? The latest third-party audit reports are publicly available here: - [https://research.nccgroup.com/2020/05/13/public-report-coda-cryptographic-review](https://research.nccgroup.com/2020/05/13/public-report-coda-cryptographic-review/) - [https://leastauthority.com/blog/audit-of-mina-ledger-application-for-o1-labs](https://leastauthority.com/blog/audit-of-mina-ledger-application-for-o1-labs/) - [https://research.nccgroup.com/2022/02/22/public-report-o1-labs-mina-client-sdk-signature-library-and-base-components-cryptography-and-implementation-review](https://research.nccgroup.com/2022/02/22/public-report-o1-labs-mina-client-sdk-signature-library-and-base-components-cryptography-and-implementation-review) :::note Any news and updates related to exchange listing shared by the Mina Foundation are on [www.minaprotocol.com](https://minaprotocol.com) or the official [Mina Protocol](https://x.com/MinaProtocol) X (Twitter). Mina Foundation cannot individually answer any listing questions. ::: #### Why do you recommend using Rosetta for integrating Mina to our exchange? Rosetta is an open-source specification that helps exchanges and developers integrate blockchains. Since Rosetta is actively maintained and specifically designed to enable simpler, faster, and more reliable blockchain integrations, we highly recommend using Rosetta to integrate Mina blockchain with your exchange. #### Is there an account creation fee? Yes, Mina Protocol charges a fee of 1 MINA when you create a new account. This fee helps protect the network from denial of service-type attacks. Over time, this fee can change. #### What is the maximum size of the mempool? How do we work around this? The max mempool size is 3,000. After it hits that size, transactions with the lowest fees are discarded. Set your fee to an amount higher than 0.001 MINA, the current average fee for transactions in the pool. You can view the fees for pending transactions and adjust your fees accordingly: [https://minascan.io/mainnet/txs/pending-txs](https://minascan.io/mainnet/txs/pending-txs). #### Why do some users appear to have lost their funds when sending to exchanges? :::tip While Mina and its SDKs do support the memo field when sending a transaction, the recommended best practice is do NOT require a memo for deposits. ::: To associate the deposit with the user's account, some exchanges require their users to include a unique memo field when sending MINA deposits to the exchange's address. If the user does not include this unique memo when sending their deposit, the receiving exchange may not be able to associate the deposit properly with the user's exchange account. These funds are NOT lost. The exchanges have received the funds at the exchange's address, but the exchange may not be able to automatically associate the deposit with the user's exchange account without such a memo. To prevent this issue, we recommend that exchanges do NOT require a memo for deposits. At the same time, exchanges and wallet creators are recommended to expose an optional memo field during a Mina send transaction. #### What is the maximum number of rollback blocks? The table in [Lifecycle of a Payment](/mina-protocol/lifecycle-of-a-payment) describes how many blocks you wait for a transaction to be confirmed. #### How should I calculate transaction fees? To calculate your transaction fees, use [https://fees.mina.tools](https://fees.mina.tools/). #### My Mina node gets stuck sometimes. How can I detect this and fix it? This is a known issue for some earlier releases. Restart your mina node whenever this issue is detected. You can use the following script to run a cron job every 3 minutes (the slot length) or more frequently: ``` MINA_STATUS=$($MINA client status --json) HIGHESTBLOCK="$(echo $MINA_STATUS | jq .highest_block_length_received)" HIGHESTUNVALIDATEDBLOCK="$(echo $MINA_STATUS | jq .highest_unvalidated_block_length_received)" # Calculate difference between validated and unvalidated blocks. # If block height is more than 4 block behind, something is likely wrong. DELTAVALIDATED="$(($HIGHESTUNVALIDATEDBLOCK-$HIGHESTBLOCK))" if [[ "$DELTAVALIDATED" -gt 4 ]]; then $MINA client stop fi ``` :::tip Be sure your Mina daemon is monitored by something such as systemd, so it can auto-restart. ::: #### My archive node is missing block information after a restart. How can I recover the data? Archive node operators often choose to run redundant archive nodes to store block data to one or more locations of their choice (for example, PostgreSQL, GCP, local files, or a logging service) and to backfill any missed block data if needed. For convenience, [mina_network_block_data](https://console.cloud.google.com/storage/browser/mina_network_block_data) from the archive node is available to help others in the community backfill any missing information. This bucket contains blocks from various Mina networks — for example, Mainnet and the most recent Devnet `devnet2`. Filter by filename for the network you want. Note that this bucket contains blocks for various other networks too, such as QAnet, which is not recommended for your testing. QAnet is used by o1Labs during targeted iterative development. Filenames contain the network name, block height, and state hash of the block. Blocks older than height 25,705 include only the network name and state hash in the filename. Example filenames: (Recent) ``` mainnet-30627-3NLfKanQ53X2MRKx5ZRvb9nVCEB9eJpcnssGCTpT3J1cojhB5M19.json ``` (Older) ``` mainnet-3NKUBmkc7UZ7ik5JyCM4WNzkN1HG5heMB5zNDUkf3Kgta1MFY6LY.json ``` You can download a specific block using curl: ``` curl https://mina_network_block_data.storage.googleapis.com/ ``` You can import this file using the mina archive blocks tool. The command for it is: ``` mina-archive-blocks --precomputed --archive-uri FILE. ``` #### How do I query for the canonical block at a certain height from the archive node? Use a recursive query. See [Query the database](/node-operators/archive-node/getting-started#query-the-database) examples in the Archive Node docs. #### Why am I getting this error message: "Not able to connect to the network"? This error message usually occurs due to a chain ID mismatch from running a Devnet build on Mainnet, or vice versa. To check whether you are running a devnet or mainnet build, run `Mina client status`. Next, compare the output's chain ID of your node to the expected chain ID of the network you are trying to connect to. You can find required information for comparison within the [GitHub announcements](https://github.com/MinaProtocol/mina/discussions/categories/announcements) or [Discord](https://discord.com/channels/484437221055922177/601171209287368715) server. #### Are there any official broadcast nodes that can be used? No, there are no official broadcast nodes at this time. However, you can broadcast transactions using [https://minascan.io/mainnet/broadcast/payment](https://minascan.io/mainnet/broadcast/payment). Use this method as a backup, the recommended method is to broadcast transactions yourself. #### Should I be staking my funds? Since Mina is a Proof of Stake (PoS) consensus network without lockup for staked tokens, it is recommended to stake these funds to support the quality of the Mina network. Additionally, by not staking, you are missing out on staking rewards that you can otherwise be receiving from the Mina blockchain. You can look into staking this wallet, either by running your own block production node or just by delegating your funds to a staking pool on the network. Delegating to a staking pool is simpler to set up. :::note Newly staked accounts incur a delay of 18 to 29 days before you start receiving rewards. ::: #### Why is there a delay for staking to take effect? For purposes of ensuring consensus, there is a delay between when delegations are sent on the blockchain and when they take effect with respect to staking on the network. The staking ledger always operates between 18 to 29 days behind the live ledger. #### How long is the delay and when is the next staking snapshot? The timing of the next staking snapshot varies. Since the timing is based on a combination of consensus timing (epochs) and snarketplace throughput, it is difficult to determine exactly how long this delay can be. A conservative estimate is that delegations sent 3 days before the epoch transition can take effect in the upcoming epoch. This means that, for any given delegation, there is an average of 18 to 29 days delay before this delegation updates block production. You can use this Delegation Calculator tool built by Carbonara to see the next staking ledger cutoff: [https://epoch.mina.tools](https://epoch.mina.tools/). #### What is the best way to test tooling and integration with Mina? Test tooling and integrations on Devnet before going live on Mainnet. The Devnet network is dedicated for developers building on top of the Mina protocol and is designed for testing and experimentation. Be sure to simulate expected Mainnet conditions, such as transaction volume and frequency, to help identify and solve potential issues ahead of time. See [Connect to Devnet](/node-operators/validator-node/connecting-to-the-network). --- url: /node-operators --- # Introduction The [Mina Protocol](/mina-protocol) is a layer 1 blockchain that is secured by [proof of stake consensus](/mina-protocol/proof-of-stake). Node operators are people who run Mina nodes. Mina node operators participate in consensus to create new blocks and help compress data by generating zk-SNARKs. ## Mina Node Roles A node is a machine running the [Mina daemon](/glossary#daemon). Different nodes fulfill different roles within the Mina network: 1. Validator - A plain Mina daemon node that participates in network consensus and can be used for operations such as sending and signing payments. 2. [Block Producer](/glossary#block-producer) - A node that participates in a process to determine what blocks it is allowed to produce and then produces blocks containing transactions that can be broadcast to the network. People who run [block producer](https://docs.minaprotocol.com/mina-protocol/block-producers) nodes are also called block producers. 3. [SNARK Coordinators](/glossary#snark-coordinator) - A role on a Mina node in the Mina network that distributes work to a series of SNARK workers in parallel to block production. 4. [SNARK Workers](https://docs.minaprotocol.com/glossary#snark-worker) - SNARK workers create [zk-SNARKs](https://minaprotocol.com/blog/what-are-zk-snarks) for each transaction. These zk-SNARKs are used to create recursive zk-SNARKs that prove the correctness of a block, and in turn, these zk-SNARKs are used to create recursive zk-SNARKs that prove the correctness of the network. These zk-SNARKs help provide the Mina Protocol with succinctness. 5. [Archive Nodes](/node-operators/archive-node) - A regular mina daemon that is connected to a running `mina-archive` process. The daemon regularly sends blockchain data to the archive process that stores it in a [PostgreSQL](https://www.postgresql.org/) database. 6. [Seed Nodes](https://docs.minaprotocol.com/glossary#seed-nodes) - Keep a record of nodes in the network and enable nodes joining the network to connect to peer nodes. ## Operating a Node Node operators are network participants who run Mina nodes on a Mina network. This section describes how to run each node role and where to find the operational references. ### Validators - [Requirements](/node-operators/validator-node/requirements) - Hardware, software, and network requirements - [Generating a Key Pair](/node-operators/validator-node/generating-a-keypair) - How to generate key pairs - [Querying Data](/node-operators/validator-node/querying-data) - Query blockchain data via GraphQL - [Staking and Snarking](/node-operators/validator-node/staking-and-snarking) - How to stake your MINA - [Logging](/node-operators/validator-node/logging) - Log files, levels, and export ### Specialized Node Types - [Block Producers](/node-operators/block-producer-node) - Running a Block Producer - [SNARK Coordinator & Workers](/node-operators/snark-workers) - Running SNARK coordinator and worker roles - [Archive Nodes](/node-operators/archive-node) - Running an Archive Node - [Seed Node](/node-operators/seed-peers) - Running a Seed Node ### Data and Programs - [Data and History](/node-operators/data-and-history) - Rosetta API and blockchain integration - [Delegation Program](/node-operators/delegation-program) - The Mina Foundation Delegation Program for Block Producers ### Reference - [Mina CLI Reference](/node-operators/reference/mina-cli-reference) - Guide to CLI interactions with Mina networks - [Mina Signer](/node-operators/mina-signer) - Key generation and transaction signing ### Support - [Troubleshooting](/node-operators/troubleshooting) - Solutions to common problems - [FAQ](/node-operators/faq) - Frequently asked questions ## Exchange Integration [Exchange Operators](/node-operators/exchange-operators) describes how exchanges can integrate with the Mina blockchain using Rosetta API, archive nodes, and validator nodes. --- url: /node-operators/mina-signer --- # Mina Signer [Mina Signer](/mina-signer) is a NodeJS/Browser-compatible library for signing transactions and generating keys. The Rosetta stack also ships an offline signer CLI tool. Both can be used to sign transactions offline for later submission via the [Construction API](/node-operators/rosetta/samples/send-transactions). ## Migration from o1labs/client-sdk The signing library `o1labs/client-sdk` is deprecated and will stop working after the Mina mainnet upgrade. All users should migrate to [mina-signer](https://www.npmjs.com/package/mina-signer). When migrating: 1. Adjust the `nonce` to the correct nonce on the sender account 2. Update the `url` variable with an existing Mina Node GraphQL endpoint See [Broadcasting a Signed Payment](/mina-signer#broadcasting-a-signed-payment) for a complete example. ## Generating a key pair with mina-signer See [Generating Keys](/mina-signer#generating-keys) for full details. A quick example: ```ts const mina = new Client({network: 'testnet'}) const keypair = mina.genKeys() ``` ## Generating a key pair with signer CLI In a native build, the signer is at `_build/default/src/app/rosetta/ocaml-signer/signer.exe`. In Docker, it's at `/rosetta/app/mina-ocaml-signer`. Examples below use `signer` as an alias. Generate a private key: ```bash signer generate-private-key ``` Derive the public key and account address: ```bash signer derive-public-key --private-key ``` ## Signing a transaction with mina-signer ```ts mina.signRosettaTransaction(payload, privateKey) ``` :::note We recommend using `mina.rosettaCombinePayload` to sign and prepare a payload for the `/construction/combine` request. See [Sending Transactions](/node-operators/rosetta/samples/send-transactions) for the full flow. ::: ## Signing a transaction with signer CLI ```bash signer sign --private-key --unsigned-transaction ``` Replace `` with the unsigned transaction string from the `/construction/payloads` endpoint. See [Sending Transactions](/node-operators/rosetta/samples/send-transactions) for the full flow. --- url: /node-operators/reference --- # Reference - **[Mina CLI Reference](/node-operators/reference/mina-cli-reference)** -- Complete reference for the `mina` command line interface. - **[Mina Signer](/node-operators/mina-signer)** -- Key generation and transaction signing for node operators. - **[Troubleshooting](/node-operators/troubleshooting)** -- Solutions to common problems when running a Mina node. - **[FAQ](/node-operators/faq)** -- Frequently asked questions about node operations, SNARKs, and the Mina network. --- url: /node-operators/reference/mina-cli-reference --- # Mina CLI Reference The Mina CLI (Command Line Interface) is the primary way for users to interact with the Mina network. It provides standard client functionality to create accounts, send transactions, and participate in consensus. There are also advanced client and daemon commands for power users. The Mina CLI is installed when you [install Mina](/node-operators/validator-node/installing-on-ubuntu-and-debian). :::tip Mina APIs are always improving. See `mina help` for the most up-to-date version. ::: ## mina ``` Mina mina SUBCOMMAND === subcommands === accounts Client commands concerning account management daemon Mina daemon client Lightweight client commands advanced Advanced client commands ledger Ledger commands libp2p Libp2p commands internal Internal commands parallel-worker internal use only transaction-snark-profiler transaction snark profiler version print version information help explain a given subcommand (perhaps recursively) ``` ## mina accounts ``` Client commands concerning account management mina accounts SUBCOMMAND === subcommands === list List all owned accounts create Create new account import Import a password protected private key to be tracked by the daemon. Set MINA_PRIVKEY_PASS environment variable to use non-interactively (key will be imported using the same password). export Export a tracked account so that it can be saved or transferred between machines. Set MINA_PRIVKEY_PASS environment variable to use non-interactively (key will be exported using the same password). unlock Unlock a tracked account lock Lock a tracked account help explain a given subcommand (perhaps recursively) ``` ### mina accounts list ``` List all owned accounts mina accounts list === flags === [--config-directory DIR] Configuration directory (alias: -config-directory) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts create ``` Create new account mina accounts create === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts import ``` Import a password protected private key to be tracked by the daemon. Set MINA_PRIVKEY_PASS environment variable to use non-interactively (key will be imported using the same password). mina accounts import === flags === --privkey-path FILE File to read private key from (alias: -privkey-path) [--config-directory DIR] Configuration directory (alias: -config-directory) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts export ``` Export a tracked account so that it can be saved or transferred between machines. Set MINA_PRIVKEY_PASS environment variable to use non-interactively (key will be exported using the same password). mina accounts export === flags === --privkey-path FILE File to write private key into (public key will be FILE.pub) (alias: -privkey-path) --public-key PUBLICKEY Public key of account to be exported (alias: -public-key) [--config-directory DIR] Configuration directory (alias: -config-directory) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts unlock ``` Unlock a tracked account mina accounts unlock === flags === --public-key PUBLICKEY Public key to be unlocked (alias: -public-key) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts lock ``` Lock a tracked account mina accounts lock === flags === --public-key PUBLICKEY Public key of account to be locked (alias: -public-key) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina accounts help ``` explain a given subcommand (perhaps recursively) mina accounts help [SUBCOMMAND] === flags === [-expand-dots] expand subcommands in recursive help [-flags] show flags as well in recursive help [-recursive] show subcommands of subcommands, etc. [-help] print this help text and exit (alias: -?) ``` ## mina client ``` Lightweight client commands mina client SUBCOMMAND === subcommands === get-balance Get balance associated with a public key get-tokens Get all token IDs that a public key has accounts for send-payment Send payment to an address delegate-stake Delegate your stake to another public key cancel-transaction Cancel a transaction -- this submits a replacement transaction with a fee larger than the cancelled transaction. set-snark-worker Set key you wish to snark work with or disable snark working set-snark-work-fee Set fee reward for doing transaction snark work export-logs Export daemon logs to tar archive export-local-logs Export local logs (no daemon) to tar archive stop-daemon Stop the daemon status Get running daemon status help explain a given subcommand (perhaps recursively) ``` ### mina client get-balance ``` Get balance associated with a public key mina client get-balance === flags === --public-key PUBLICKEY Public key for which you want to check the balance (alias: -public-key) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [--token TOKEN_ID] The token ID for the account (alias: -token) [-help] print this help text and exit (alias: -?) ``` ### mina client get-tokens ``` Get all token IDs that a public key has accounts for mina client get-tokens === flags === --public-key PUBLICKEY Public key for which you want to find accounts (alias: -public-key) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client send-payment ``` Send payment to an address mina client send-payment === flags === --amount VALUE Payment amount you want to send (alias: -amount) --receiver PUBLICKEY Public key to which you want to send money (alias: -receiver) --sender PUBLICKEY Public key from which you want to send the transaction (alias: -sender) [--fee FEE] Amount you are willing to pay to process the transaction (default: 0.25) (minimum: 0.001) (alias: -fee) [--memo STRING] Memo accompanying the transaction (alias: -memo) [--nonce NONCE] Nonce that you would like to set for your transaction (default: nonce of your account on the best ledger or the successor of highest value nonce of your sent transactions from the transaction pool ) (alias: -nonce) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client delegate-stake ``` Delegate your stake to another public key mina client delegate-stake === flags === --receiver PUBLICKEY Public key to which you want to delegate your stake (alias: -receiver) --sender PUBLICKEY Public key from which you want to send the transaction (alias: -sender) [--fee FEE] Amount you are willing to pay to process the transaction (default: 0.25) (minimum: 0.001) (alias: -fee) [--memo STRING] Memo accompanying the transaction (alias: -memo) [--nonce NONCE] Nonce that you would like to set for your transaction (default: nonce of your account on the best ledger or the successor of highest value nonce of your sent transactions from the transaction pool ) (alias: -nonce) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client cancel-transaction ``` Cancel a transaction -- this submits a replacement transaction with a fee larger than the cancelled transaction. mina client cancel-transaction === flags === --id ID Transaction ID to be cancelled (alias: -id) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client set-snark-worker ``` Set key you wish to snark work with or disable snark working mina client set-snark-worker === flags === [--address PUBLICKEY] Public-key address you wish to start snark-working on; null to stop doing any snark work. Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -address) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client set-snark-work-fee ``` Set fee reward for doing transaction snark work mina client set-snark-work-fee FEE === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina client export-logs ``` Export daemon logs to tar archive mina client export-logs === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [--tarfile STRING] Basename of the tar archive (default: date_time) (alias: -tarfile) [-help] print this help text and exit (alias: -?) ``` ### mina client export-local-logs ``` Export local logs (no daemon) to tar archive mina client export-local-logs === flags === [--config-directory DIR] Configuration directory (alias: -config-directory) [--tarfile STRING] Basename of the tar archive (default: date_time) (alias: -tarfile) [-help] print this help text and exit (alias: -?) ``` ### mina client stop-daemon ``` Stop the daemon mina client stop-daemon === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina client status ``` Get running daemon status mina client status === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [--performance] Include performance histograms in status output (default: don't include) (alias: -performance) [-help] print this help text and exit (alias: -?) ``` ### mina client help ``` explain a given subcommand (perhaps recursively) mina client help [SUBCOMMAND] === flags === [-expand-dots] expand subcommands in recursive help [-flags] show flags as well in recursive help [-recursive] show subcommands of subcommands, etc. [-help] print this help text and exit (alias: -?) ``` ## mina daemon ``` Mina daemon mina daemon === flags === [--all-peers-seen-metric true|false] whether to track the set of all peers ever seen for the all_peers metric (default: false) (alias: -all-peers-seen-metric) [--archive-address HOST:PORT/LOCALHOST-PORT] Daemon to archive process communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 3086, 154.97.53.97:3086) (alias: -archive-address) [--archive-rocksdb] Stores all the blocks heard in RocksDB (alias: -archive-rocksdb) [--background] Run process on the background (alias: -background) [--bind-ip IP] IP of network interface to use for peer connections (alias: -bind-ip) [--block-producer-key DEPRECATED:] Use environment variable `MINA_BP_PRIVKEY` instead. Private key file for the block producer. Providing this flag or the environment variable will enable block production. You cannot provide both `block-producer-key` and `block-producer-pubkey`. (default: use environment variable `MINA_BP_PRIVKEY`, if provided, or else don't produce any blocks) Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -block-producer-key) [--block-producer-password PASSWORD] Password associated with the block-producer key. Setting this is equivalent to setting the MINA_PRIVKEY_PASS environment variable. Be careful when setting it in the commandline as it will likely get tracked in your history. Mainly to be used from the daemon.json config file (alias: -block-producer-password) [--block-producer-pubkey PUBLICKEY] Public key for the associated private key that is being tracked by this daemon. You cannot provide both `block-producer-key` (or `MINA_BP_PRIVKEY`) and `block-producer-pubkey`. (default: don't produce blocks) Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -block-producer-pubkey) [--client-port PORT] local RPC-server for clients to interact with the daemon (default: 8301) (alias: -client-port) [--coinbase-receiver PUBLICKEY] Address to send coinbase rewards to (if this node is producing blocks). If not provided, coinbase rewards will be sent to the producer of a block. Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -coinbase-receiver) [--config-directory DIR] Configuration directory (alias: -config-directory) [--config-file PATH] ... path to a configuration file (overrides MINA_CONFIG_FILE, default: /daemon.json). Pass multiple times to override fields from earlier config files (alias: -config-file) [--contact-info contact] info used in node error report service (it could be either email address or discord username), it should be less than 200 characters (alias: -contact-info) [--demo-mode] Run the daemon in demo-mode -- assume we're "synced" to the network instantly (alias: -demo-mode) [--direct-peer /ip4/IPADDR/tcp/PORT/p2p/PEERID] ... Peers to always send new messages to/from. These peers should also have you configured as a direct peer, the relationship is intended to be symmetric (alias: -direct-peer) [--disable-node-status] Disable reporting node status to other nodes (default: enabled) (alias: -disable-node-status) [--enable-flooding true|false] Publish our own blocks/transactions to every peer we can find (default: false) (alias: -enable-flooding) [--enable-peer-exchange true|false] Help keep the mesh connected when closing connections (default: false) (alias: -enable-peer-exchange) [--external-ip IP] External IP address for other nodes to connect to. You only need to set this if auto-discovery fails for some reason. (alias: -external-ip) [--external-port PORT] Port to use for all libp2p communications (gossip and RPC) (default: 8302) (alias: -external-port) [--file-log-level LEVEL] Set log level for the log file (Internal|Spam|Trace|Debug|Info|Warn|Error|Faulty_peer|Fatal, default: Trace) (alias: -file-log-level) [--file-log-rotations Number] of file log rotations before overwriting old logs (default: 50) [--gc-stat-interval INTERVAL] in mins for collecting GC stats for metrics (Default: 15.000000) (alias: -gc-stat-interval) [--generate-genesis-proof true|false] Deprecated. Passing this flag has no effect (alias: -generate-genesis-proof) [--genesis-ledger-dir DIR] Directory that contains the genesis ledger and the genesis blockchain proof (default: ) (alias: -genesis-ledger-dir) [--hardfork-handling keep-running|migrate-exit] Internal flag, controlling how the daemon handles an upcoming hard fork. Exposed for testing purposes. Currently it only causes the daemon to maintain migrated versions of the root and epoch ledger databases alongside the stable databases. (default: keep-running). (alias: -hardfork-handling) [--insecure-rest-server] Have REST server listen on all addresses, not just localhost (this is INSECURE, make sure your firewall is configured correctly!) (alias: -insecure-rest-server) [--internal-tracing] Enables internal tracing into $config-directory/internal-tracing/internal-trace.jsonl (alias: -internal-tracing) [--isolate-network true|false] Only allow connections to the peers passed on the command line or configured through GraphQL. (default: false) (alias: -isolate-network) [--libp2p-keypair KEYFILE] Keypair (generated from `mina libp2p generate-keypair`) to use with libp2p discovery (alias: -libp2p-keypair) [--libp2p-metrics-port PORT] libp2p metrics server for scraping via Prometheus (default no libp2p-metrics-server) (alias: -libp2p-metrics-port) [--limited-graphql-port PORT] GraphQL-server for limited daemon interaction (alias: -limited-graphql-port) [--log-block-creation true|false] Log the steps involved in including transactions and snark work in a block (default: true) (alias: -log-block-creation) [--log-json] Print log output as JSON (default: plain text) (alias: -log-json) [--log-level LEVEL] Set log level (Internal|Spam|Trace|Debug|Info|Warn|Error|Faulty_peer|Fatal, default: Info) (alias: -log-level) [--log-precomputed-blocks true|false] Include precomputed blocks in the log (default: false) (alias: -log-precomputed-blocks) [--log-snark-work-gossip true|false] Log snark-pool diff received from peers (default: false) (alias: -log-snark-work-gossip) [--log-txn-pool-gossip true|false] Log transaction-pool diff received from peers (default: false) (alias: -log-txn-pool-gossip) [--max-connections NN] max number of connections that this peer will have to neighbors in the gossip network. Tuning this higher will strengthen your connection to the network in exchange for using more RAM (default: 50) (alias: -max-connections) [--metrics-port PORT] metrics server for scraping via Prometheus (default no metrics-server) (alias: -metrics-port) [--min-connections NN] min number of connections that this peer will have to neighbors in the gossip network (default: 20) (alias: -min-connections) [--minimum-block-reward AMOUNT] Minimum reward a block produced by the node should have. Empty blocks are created if the rewards are lower than the specified threshold (default: No threshold, transactions and coinbase will be included as long as the required snark work is available and can be paid for) (alias: -minimum-block-reward) [--node-error-url URL] of the node error collection service (alias: -node-error-url) [--node-status-url URL] of the node status collection service (alias: -node-status-url) [--open-limited-graphql-port] Have the limited GraphQL server listen on all addresses, not just localhost (this is INSECURE, make sure your firewall is configured correctly!) (alias: -open-limited-graphql-port) [--peer /ip4/IPADDR/tcp/PORT/p2p/PEERID] ... initial "bootstrap" peers for discovery (alias: -peer) [--peer-list-file PATH] path to a file containing "bootstrap" peers for discovery, one multiaddress per line (alias: -peer-list-file) [--peer-list-url URL] URL of seed peer list file. Will be polled periodically. (alias: -peer-list-url) [--peer-protection-rate float] Proportion of peers to be marked as protected (default: 0.2) (alias: -peer-protection-rate) [--precomputed-blocks-file PATH] Path to write precomputed blocks to, for replay or archiving (alias: -precomputed-blocks-file) [--proof-level full|check|none] Internal, for testing. Start or connect to a network with full proving (full), snark-testing with dummy proofs (check), or dummy proofs (none) (alias: -proof-level) [--proposed-protocol-version NN.NN.NN] Proposed protocol version to signal other nodes (alias: -proposed-protocol-version) [--rest-port PORT] local REST-server for daemon interaction (default: 3085) (alias: -rest-port) [--run-snark-coordinator PUBLICKEY] Run a SNARK coordinator with this public key (ignored if the run-snark-worker is set). Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -run-snark-coordinator) [--run-snark-worker PUBLICKEY] Run the SNARK worker with this public key. Warning: If the key is from a zkApp account, the account's receive permission must be None. (alias: -run-snark-worker) [--seed] Start the node as a seed node (alias: -seed) [--simplified-node-stats whether] to report simplified node stats (default: true) (alias: -simplified-node-stats) [--snark-worker-fee FEE] Amount a worker wants to get compensated for generating a snark proof (default: 100000000) (alias: -snark-worker-fee) [--snark-worker-parallelism NUM] Run the SNARK worker using this many threads. Equivalent to setting OMP_NUM_THREADS, but doesn't affect block production. (alias: -snark-worker-parallelism) [--start-filtered-logs LOG-FILTER] ... Include filtered logs for the given filter. May be passed multiple times [--stop-time UPTIME] in hours after which the daemon stops itself (only if there were no slots won within an hour after the stop time) (Default: 168) (alias: -stop-time) [--stop-time-interval UPTIME] An upper bound (inclusive) on the random number of hours added to the stop-time. Setting it to zero disables this randomness. (Default: 9) (alias: -stop-time-interval) [--tracing] Trace into $config-directory/trace/$pid.trace (alias: -tracing) [--upload-blocks-to-gcloud true|false] upload blocks to gcloud storage. Requires the environment variables GCLOUD_KEYFILE, NETWORK_NAME, and GCLOUD_BLOCK_UPLOAD_BUCKET (alias: -upload-blocks-to-gcloud) [--uptime-send-node-commit-sha] true|false Whether to send the commit SHA used to build the node to the uptime service. (default: false) (alias: -uptime-send-node-commit-sha) [--uptime-submitter-key KEYFILE] Private key file for the uptime submitter. You cannot provide both `uptime-submitter-key` and `uptime-submitter-pubkey`. (alias: -uptime-submitter-key) [--uptime-submitter-pubkey PUBLICKEY] Public key of the submitter to the Mina delegation program, for the associated private key that is being tracked by this daemon. You cannot provide both `uptime-submitter-key` and `uptime-submitter-pubkey`. (alias: -uptime-submitter-pubkey) [--uptime-url URL] URL of the uptime service of the Mina delegation program (alias: -uptime-url) [--validation-queue-size NN] size of the validation queue in the p2p network used to buffer messages (like blocks and transactions received on the gossip network) while validation is pending. If a transaction, for example, is invalid, we don't forward the message on the gossip net. If this queue is too small, we will drop messages without validating them. If it is too large, we are susceptible to DoS attacks on memory. (default: 150) (alias: -validation-queue-size) [--work-reassignment-wait WAIT-TIME] in ms before a snark-work is reassigned (default: 420000ms) (alias: -work-reassignment-wait) [--work-selection seq|rand|roffset] Choose work sequentially (seq), randomly (rand), or sequentially with a random offset (roffset) (default: rand) (alias: -work-selection) [--working-dir PATH] path to chdir into before starting (useful for background mode, defaults to cwd, or / if -background) (alias: -working-dir) [-help] print this help text and exit (alias: -?) ``` ## mina advanced ``` Advanced client commands mina advanced SUBCOMMAND === subcommands === add-peers Add peers to the daemon Addresses take the format /ip4/IPADDR/tcp/PORT/p2p/PEERID archive-blocks Archive a block from a file. If an archive address is given, this process will communicate with the archive node directly; otherwise it will communicate through the daemon over the rest-server batch-send-payments Send multiple payments from a file client-trustlist Client trustlist management compile-time-constants Print a JSON map of the compile-time consensus parameters compute-receipt-chain-hash Compute the next receipt chain hash from the previous hash and transaction ID constraint-system-digests Print MD5 digest of each SNARK constraint dump-keypair Print out a keypair from a private key file generate-hardfork-config Generate reference hardfork configuration generate-keypair Generate a new public, private keypair get-nonce Get the current nonce for an account get-peers List the peers currently connected to the daemon get-public-keys Get public keys get-trust-status Get the trust status associated with an IP address get-trust-status-all Get trust statuses for all peers known to the trust system hash-transaction Compute the hash of a transaction from its transaction ID node-status Get node statuses for a set of peers object-lifetime-statistics Dump internal object lifetime statistics to JSON pending-snark-work List of snark works in JSON format that are not available in the pool yet pooled-user-commands Retrieve all the user commands that are pending inclusion pooled-zkapp-commands Retrieve all the zkApp commands that are pending inclusion print-signature-kind Print the signature kind that this binary is compiled with reset-trust-status Reset the trust status associated with an IP address runtime-config Compute the runtime configuration used by a running daemon send-rosetta-transactions Dispatch one or more transactions, provided to stdin in rosetta format set-coinbase-receiver Set the coinbase receiver snark-job-list List of snark jobs in JSON format that are yet to be included in the blocks snark-pool-list List of snark works in the snark pool in JSON format start-internal-tracing Start internal tracing to $config-directory/internal-tracing/internal-trace.jsonl start-tracing Start async tracing to $config-directory/trace/$pid.trace status-clear-hist Clear histograms reported in status stop-internal-tracing Stop internal tracing stop-tracing Stop async tracing test Testing-only commands thread-graph Return a Graphviz Dot graph representation of the internal thread hierarchy time-offset Get the time offset in seconds used by the daemon to convert real time into blockchain time validate-keypair Validate a public, private keypair validate-transaction Validate the signature on one or more transactions, provided to stdin in rosetta format verify-receipt Verify a receipt of a sent payment visualization Visualize data structures special to Mina vrf Commands for vrf evaluations wrap-key Wrap a private key into a private key file help explain a given subcommand (perhaps recursively) ``` ### mina advanced add-peers ``` Add peers to the daemon Addresses take the format /ip4/IPADDR/tcp/PORT/p2p/PEERID mina advanced add-peers PEER [PEER ...] === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [--seed true/false] Whether to add these peers as 'seed' peers, which may perform peer exchange. Default: true (alias: -seed) [-help] print this help text and exit (alias: -?) ``` ### mina advanced archive-blocks ``` Archive a block from a file. If an archive address is given, this process will communicate with the archive node directly; otherwise it will communicate through the daemon over the rest-server mina advanced archive-blocks [FILES ...] === flags === [--archive-address HOST:PORT/LOCALHOST-PORT] Daemon to archive process communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 3086, 154.97.53.97:3086) (alias: -archive-address) [--extensional] Blocks are in extensional JSON format (alias: -extensional) [--failed-files PATH] Appends the list of files that failed to be processed (alias: -failed-files) [--log-successful true/false] Whether to log messages for files that were processed successfully (alias: -log-successful) [--precomputed] Blocks are in precomputed JSON format (alias: -precomputed) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [--successful-files PATH] Appends the list of files that were processed successfully (alias: -successful-files) [-help] print this help text and exit (alias: -?) ``` ### mina advanced batch-send-payments ``` Send multiple payments from a file mina advanced batch-send-payments PAYMENTS-FILE === flags === --privkey-path FILE File to read private key from (alias: -privkey-path) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced client-trustlist ``` Client trustlist management mina advanced client-trustlist SUBCOMMAND === subcommands === add Add an IP to the trustlist list List the CIDR masks in the trustlist remove Remove a CIDR mask from the trustlist help explain a given subcommand (perhaps recursively) ``` ### mina advanced compile-time-constants ``` Print a JSON map of the compile-time consensus parameters mina advanced compile-time-constants === flags === [-help] print this help text and exit (alias: -?) ``` ### mina advanced compute-receipt-chain-hash ``` Compute the next receipt chain hash from the previous hash and transaction ID mina advanced compute-receipt-chain-hash === flags === --previous-hash HASH Previous receipt chain hash, Base58Check-encoded --transaction-id TRANSACTION_ID Transaction ID, Base64-encoded [--index NN] For a zkApp, 0 for fee payer or 1-based index of account update [--signature-kind mainnet|testnet|] Signature kind to use (default: value compiled into this binary) [-help] print this help text and exit (alias: -?) ``` ### mina advanced constraint-system-digests ``` Print MD5 digest of each SNARK constraint mina advanced constraint-system-digests === flags === [--signature-kind mainnet|testnet|] Signature kind to use (default: value compiled into this binary) [-help] print this help text and exit (alias: -?) ``` ### mina advanced dump-keypair ``` Print out a keypair from a private key file mina advanced dump-keypair === flags === --privkey-path FILE File to read private key from (alias: -privkey-path) [-help] print this help text and exit (alias: -?) ``` ### mina advanced generate-hardfork-config ``` Generate reference hardfork configuration mina advanced generate-hardfork-config === flags === --hardfork-config-dir DIR Directory to generate hardfork configuration, relative to the daemon working directory [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--generate-fork-validation BOOL] whether generating the fork validation folder. Defaults to true [-help] print this help text and exit (alias: -?) ``` ### mina advanced generate-keypair ``` Generate a new public, private keypair mina advanced generate-keypair === flags === --privkey-path FILE File to write private key into (public key will be FILE.pub) (alias: -privkey-path) [-help] print this help text and exit (alias: -?) ``` ### mina advanced get-nonce ``` Get the current nonce for an account mina advanced get-nonce === flags === --address PUBLICKEY Public-key address you want the nonce for (alias: -address) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--token TOKEN_ID] The token ID for the account (alias: -token) [-help] print this help text and exit (alias: -?) ``` ### mina advanced get-peers ``` List the peers currently connected to the daemon mina advanced get-peers === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced get-public-keys ``` Get public keys mina advanced get-public-keys === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [--with-details] Show extra details (eg. balance, nonce) in addition to public keys (alias: -with-details) [-help] print this help text and exit (alias: -?) ``` ### mina advanced get-trust-status ``` Get the trust status associated with an IP address mina advanced get-trust-status === flags === --ip-address IP An IPv4 or IPv6 address for which you want to query the trust status (alias: -ip-address) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [-help] print this help text and exit (alias: -?) ``` ### mina advanced get-trust-status-all ``` Get trust statuses for all peers known to the trust system mina advanced get-trust-status-all === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [--nonzero-only] Only show trust statuses whose trust score is nonzero (alias: -nonzero-only) [-help] print this help text and exit (alias: -?) ``` ### mina advanced hash-transaction ``` Compute the hash of a transaction from its transaction ID mina advanced hash-transaction === flags === --transaction-id ID ID of the transaction to hash [-help] print this help text and exit (alias: -?) ``` ### mina advanced node-status ``` Get node statuses for a set of peers mina advanced node-status === flags === [--daemon-peers] Get node statuses for peers known to the daemon (alias: -daemon-peers) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--peers CSV-LIST] Peer multiaddrs for obtaining node status (alias: -peers) [--show-errors] Include error responses in output (alias: -show-errors) [-help] print this help text and exit (alias: -?) ``` ### mina advanced object-lifetime-statistics ``` Dump internal object lifetime statistics to JSON mina advanced object-lifetime-statistics === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced pending-snark-work ``` List of snark works in JSON format that are not available in the pool yet mina advanced pending-snark-work === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced pooled-user-commands ``` Retrieve all the user commands that are pending inclusion mina advanced pooled-user-commands [PUBLIC-KEY] === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced pooled-zkapp-commands ``` Retrieve all the zkApp commands that are pending inclusion mina advanced pooled-zkapp-commands [PUBLIC-KEY] === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced print-signature-kind ``` Print the signature kind that this binary is compiled with mina advanced print-signature-kind === flags === [-help] print this help text and exit (alias: -?) ``` ### mina advanced reset-trust-status ``` Reset the trust status associated with an IP address mina advanced reset-trust-status === flags === --ip-address IP An IPv4 or IPv6 address for which you want to reset the trust status (alias: -ip-address) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [-help] print this help text and exit (alias: -?) ``` ### mina advanced runtime-config ``` Compute the runtime configuration used by a running daemon mina advanced runtime-config === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced send-rosetta-transactions ``` Dispatch one or more transactions, provided to stdin in rosetta format mina advanced send-rosetta-transactions === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced set-coinbase-receiver ``` Set the coinbase receiver mina advanced set-coinbase-receiver === flags === [--block-producer] Send coinbase rewards to the block producer's public key (alias: -block-producer) [--public-key PUBLICKEY] Public key of account to send coinbase rewards to (alias: -public-key) [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced snark-job-list ``` List of snark jobs in JSON format that are yet to be included in the blocks mina advanced snark-job-list === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced snark-pool-list ``` List of snark works in the snark pool in JSON format mina advanced snark-pool-list === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced start-internal-tracing ``` Start internal tracing to $config-directory/internal-tracing/internal-trace.jsonl mina advanced start-internal-tracing === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced start-tracing ``` Start async tracing to $config-directory/trace/$pid.trace mina advanced start-tracing === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced status-clear-hist ``` Clear histograms reported in status mina advanced status-clear-hist === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--json] Use JSON output (default: plaintext) (alias: -json) [--performance] Include performance histograms in status output (default: don't include) (alias: -performance) [-help] print this help text and exit (alias: -?) ``` ### mina advanced stop-internal-tracing ``` Stop internal tracing mina advanced stop-internal-tracing === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced stop-tracing ``` Stop async tracing mina advanced stop-tracing === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [-help] print this help text and exit (alias: -?) ``` ### mina advanced test ``` Testing-only commands mina advanced test SUBCOMMAND === subcommands === create-genesis Test genesis creation submit-to-archive Generate blocks with zkApp transactions and payments. Optionally submit to archive node or save to file for analysis. help explain a given subcommand (perhaps recursively) ``` ### mina advanced thread-graph ``` Return a Graphviz Dot graph representation of the internal thread hierarchy mina advanced thread-graph === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced time-offset ``` Get the time offset in seconds used by the daemon to convert real time into blockchain time mina advanced time-offset === flags === [--rest-server URI/LOCALHOST-PORT] graphql rest server for daemon interaction (examples: 3085 or http://localhost:3085/graphql, /dns4/peer1-rising-phoenix.o1test.net:3085/graphql) (default: 3085 or http://localhost:3085/graphql) (alias: -rest-server) [-help] print this help text and exit (alias: -?) ``` ### mina advanced validate-keypair ``` Validate a public, private keypair mina advanced validate-keypair === flags === --privkey-path FILE File to write private key into (public key will be FILE.pub) (alias: -privkey-path) [--signature-kind mainnet|testnet|] Signature kind to use (default: value compiled into this binary) [-help] print this help text and exit (alias: -?) ``` ### mina advanced validate-transaction ``` Validate the signature on one or more transactions, provided to stdin in rosetta format mina advanced validate-transaction === flags === [--signature-kind mainnet|testnet|] Signature kind to use (default: value compiled into this binary) [-help] print this help text and exit (alias: -?) ``` ### mina advanced verify-receipt ``` Verify a receipt of a sent payment mina advanced verify-receipt === flags === --address PUBLICKEY Public-key address of sender (alias: -address) --payment-path PAYMENTPATH File to read json version of verifying payment (alias: -payment-path) --proof-path PROOFFILE File to read json version of payment receipt (alias: -proof-path) [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--legacy] Use legacy json format (zkapp command with hashes) [--token TOKEN_ID] The token ID for the account (alias: -token) [-help] print this help text and exit (alias: -?) ``` ### mina advanced visualization ``` Visualize data structures special to Mina mina advanced visualization SUBCOMMAND === subcommands === registered-masks Produce a visualization of the registered-masks transition-frontier Produce a visualization of the transition-frontier help explain a given subcommand (perhaps recursively) ``` ### mina advanced vrf ``` Commands for vrf evaluations mina advanced vrf SUBCOMMAND === subcommands === batch-check-witness Check a batch of vrf evaluation witnesses read on stdin. Outputs the verified vrf evaluations (or no vrf output if the witness is invalid), and whether the vrf output satisfies the threshold values if given. The threshold should be included in the JSON for each vrf as the 'vrfThreshold' field, of format {delegatedStake: 1000, totalStake: 1000000000}. The threshold is not checked against a ledger; this should be done manually to confirm whether threshold_met in the output corresponds to an actual won block. batch-generate-witness Generate a batch of vrf evaluation witnesses from {"globalSlot": _, "epochSeed": _, "delegatorIndex": _} JSON message objects read on stdin generate-witness Generate a vrf evaluation witness. This may be used to calculate whether a given private key will win a given slot (by checking threshold_met = true in the JSON output), or to generate a witness that a 3rd account_update can use to verify a vrf evaluation. help explain a given subcommand (perhaps recursively) ``` ### mina advanced wrap-key ``` Wrap a private key into a private key file mina advanced wrap-key === flags === --privkey-path FILE File to write private key into (public key will be FILE.pub) (alias: -privkey-path) [-help] print this help text and exit (alias: -?) ``` ### mina advanced help ``` explain a given subcommand (perhaps recursively) mina advanced help [SUBCOMMAND] === flags === [-expand-dots] expand subcommands in recursive help [-flags] show flags as well in recursive help [-recursive] show subcommands of subcommands, etc. [-help] print this help text and exit (alias: -?) ``` ## mina ledger ``` Ledger commands mina ledger SUBCOMMAND === subcommands === currency Print the total currency for each token present in the ledger contained in the specified file export Print the specified ledger (default: staged ledger at the best tip). Note: Exporting snarked ledger is an expensive operation and can take a few seconds hash Print the Merkle root of the ledger contained in the specified file test Testing-only commands help explain a given subcommand (perhaps recursively) ``` ### mina ledger currency ``` Print the total currency for each token present in the ledger contained in the specified file mina ledger currency === flags === --ledger-file LEDGER-FILE File containing an exported ledger [--plaintext] Use plaintext input or output (default: JSON) (alias: -plaintext) [-help] print this help text and exit (alias: -?) ``` ### mina ledger export ``` Print the specified ledger (default: staged ledger at the best tip). Note: Exporting snarked ledger is an expensive operation and can take a few seconds mina ledger export STAGED-LEDGER|SNARKED-LEDGER|STAKING-EPOCH-LEDGER|NEXT-EPOCH-LEDGER === flags === [--daemon-port HOST:PORT/LOCALHOST-PORT] Client to local daemon communication. If HOST is omitted, then localhost is assumed to be HOST. (examples: 8301, 154.97.53.97:8301) (default: 8301) (alias: -daemon-port) [--plaintext] Use plaintext input or output (default: JSON) (alias: -plaintext) [--state-hash STATE-HASH] State hash, if printing a staged ledger or snarked ledger (default: state hash for the best tip) (alias: -state-hash) [-help] print this help text and exit (alias: -?) ``` ### mina ledger hash ``` Print the Merkle root of the ledger contained in the specified file mina ledger hash === flags === --ledger-file LEDGER-FILE File containing an exported ledger [--plaintext] Use plaintext input or output (default: JSON) (alias: -plaintext) [-help] print this help text and exit (alias: -?) ``` ### mina ledger test ``` Testing-only commands mina ledger test SUBCOMMAND === subcommands === apply Test ledger application generate-accounts Generate a ledger for testing help explain a given subcommand (perhaps recursively) ``` ### mina ledger help ``` explain a given subcommand (perhaps recursively) mina ledger help [SUBCOMMAND] === flags === [-expand-dots] expand subcommands in recursive help [-flags] show flags as well in recursive help [-recursive] show subcommands of subcommands, etc. [-help] print this help text and exit (alias: -?) ``` ## mina libp2p ``` Libp2p commands mina libp2p SUBCOMMAND === subcommands === dump-keypair Print an existing libp2p keypair generate-keypair Generate a new libp2p keypair and print out the peer ID help explain a given subcommand (perhaps recursively) ``` ### mina libp2p dump-keypair ``` Print an existing libp2p keypair mina libp2p dump-keypair === flags === --privkey-path FILE File to read private key from (alias: -privkey-path) [-help] print this help text and exit (alias: -?) ``` ### mina libp2p generate-keypair ``` Generate a new libp2p keypair and print out the peer ID mina libp2p generate-keypair === flags === --privkey-path FILE File to write private key into (public key will be FILE.pub) (alias: -privkey-path) [-help] print this help text and exit (alias: -?) ``` ### mina libp2p help ``` explain a given subcommand (perhaps recursively) mina libp2p help [SUBCOMMAND] === flags === [-expand-dots] expand subcommands in recursive help [-flags] show flags as well in recursive help [-recursive] show subcommands of subcommands, etc. [-help] print this help text and exit (alias: -?) ``` --- url: /node-operators/rosetta/build-from-sources --- # Building and running Rosetta from source code In [Running with Docker](run-with-docker), you learned that the Docker container runs the mina daemon, mina-archive, and Rosetta API. If you already have mina-archive up and running, you can also build and run the Rosetta API natively and wire it to the existing mina daemon and mina-archive. :::tip To run mina daemon and mina-archive natively, follow the [Archive Node page](/node-operators/archive-node/getting-started) instructions. ::: The easiest way to build Rosetta natively is to use the Nix development environment. 1. Clone the official [mina repository](https://github.com/MinaProtocol/mina.git) and switch to the `compatible` branch. 1. If you don't already have Nix on your machine, install it following the steps in the [nix/README.md](https://github.com/MinaProtocol/mina/blob/develop/nix/README.md). 1. Run the `./nix/pin.sh` script to enable submodules to be available to the build: ```shell ./nix/pin.sh ``` 1. Launch the development shell: ```shell nix develop mina ``` 1. Build Rosetta app: ```shell dune build --profile=mainnet src/app/rosetta ``` 1. After a successful build, the Rosetta app is available here: `_build/default/src/app/rosetta/rosetta.exe` You can run it with following command: ```shell MINA_ROSETTA_MAX_DB_POOL_SIZE=64 \ _build/default/src/app/rosetta/rosetta.exe --port 3087 \ --graphql-uri --archive-uri postgres://:@:/ ``` --- url: /node-operators/rosetta/docker-compose --- # Docker Compose Rosetta For production deployments, use Docker Compose to run each Rosetta component as a separate container. This gives you control over resource allocation, logging, and restarts. The full Docker Compose configuration — including `docker-compose.yml`, example environment files for mainnet and devnet, a `Makefile`, and a `README` — is maintained in the Mina repository: **[`mina/src/app/rosetta/docker-compose/`](https://github.com/MinaProtocol/mina/tree/compatible/src/app/rosetta/docker-compose)** ## Quick start :::tip Before running the commands below, review the [Configuration](#configuration) section to see all available options — including image tags, network selection, ports, and database settings. ::: ```bash git clone https://github.com/MinaProtocol/mina.git cd mina/src/app/rosetta/docker-compose # For mainnet cp example.mainnet.env .env # For devnet cp example.devnet.env .env # Edit .env — set MINA_LIBP2P_PASS and review POSTGRES_PASSWORD vi .env # Start all services docker compose up -d # Or use make shortcuts make mainnet # copies mainnet env and starts services make devnet # copies devnet env and starts services ``` ## Services overview The Docker Compose setup includes six services: | Service | Description | Default Port | |---------|-------------|--------------| | **postgres** | PostgreSQL 17 with health checks | 5432 (container), configurable host port | | **bootstrap_db** | One-shot: downloads and imports the latest daily archive dump | — | | **mina_archive** | Archive process, stores block data in PostgreSQL | 3086 | | **mina_node** | Mina daemon with GraphQL API | 3085 (GraphQL), 8302 (P2P) | | **mina_rosetta** | Rosetta API for exchange integration | 3087 | | **missing_blocks_guardian** | Monitors and recovers missing blocks between nightly dumps and chain tip | — | ## Configuration All configuration is done through a single `.env` file. Key variables: ### Docker images | Variable | Description | |----------|-------------| | `MINA_DAEMON_IMAGE` | Mina daemon Docker image | | `MINA_ARCHIVE_IMAGE` | Mina archive Docker image | | `MINA_ROSETTA_IMAGE` | Mina Rosetta Docker image | For mainnet, images are pulled from [Docker Hub](https://hub.docker.com/u/minaprotocol) (`minaprotocol/mina-*`). For devnet, images are pulled from the o1Labs GCR registry. ### Network | Variable | Description | |----------|-------------| | `MINA_NETWORK` | `mainnet` or `devnet` | | `MINA_PEERLIST_URL` | Bootstrap peers URL | | `MINA_LIBP2P_PASS` | Passphrase for the libp2p key (required) | ### Ports | Variable | Default | Description | |----------|---------|-------------| | `POSTGRES_PORT` | `5433` | Host port mapped to PostgreSQL | | `MINA_REST_PORT` | `3085` | GraphQL API port | | `MINA_P2P_PORT` | `8302` | P2P networking port | | `MINA_ARCHIVE_PORT` | `3086` | Archive server port | | `MINA_ROSETTA_PORT` | `3087` | Rosetta API port | ### Archive bootstrap | Variable | Description | |----------|-------------| | `ARCHIVE_DUMP_BASE_URL` | Base URL for daily archive dumps | | `ARCHIVE_DUMP_PREFIX` | Dump filename prefix (`mainnet-archive-dump` or `devnet-archive-dump`) | | `GUARDIAN_PRECOMPUTED_BLOCKS_URL` | S3 bucket URL for precomputed blocks used by the missing blocks guardian | ## Data persistence Bind mounts preserve data across `docker compose down` / `up`: | Host path | Container path | Contents | |-----------|---------------|----------| | `./archive/postgresql/data` | `/var/lib/postgresql/data` | PostgreSQL data | | `./archive/data` | `/data` | Archive node data | | `./mina_node/.mina-config` | `/root/.mina-config` | Daemon config, keys, peers | | `./mina_rosetta/.mina-config` | `/root/.mina-config` | Rosetta config | ## Make targets | Command | Description | |---------|-------------| | `make devnet` | Copy devnet env and start services | | `make mainnet` | Copy mainnet env and start services | | `make stop` | Stop all services | | `make clean` | Stop services, remove volumes and all persisted data | | `make logs` | Follow logs for all services | | `make status` | Show container status | | `make health` | Check health of Postgres, GraphQL, and Rosetta endpoints | ## Verifying the deployment Once services are running and the node is synced: ```bash # Check container status make status # Run health checks make health # Check sync status docker compose exec mina_node mina client status # Query Rosetta API curl -s http://localhost:3087/network/list \ -H 'Content-Type: application/json' -d '{}' | jq . # Connect to archive database psql postgres://postgres:postgres@localhost:5433/archive ``` ## Clean start To wipe all data and start fresh: ```bash make clean docker compose up -d ``` --- url: /node-operators/rosetta/run-with-docker --- # Running with Docker :::info There is a known issue that you can't use the docker image on the Apple silicon chip. To run Mina Rosetta on Apple silicon, you can use the steps in [Building and running Rosetta from source code](build-from-sources). ::: 1. [Install Docker](https://www.docker.com/get-started) and check that your Docker configuration has at least 16 GB RAM (the recommended amount is 32 GB). 1. Check the latest release for Mainnet on the official [Mina GitHub releases](https://github.com/MinaProtocol/mina/releases) page. 1. Use the Mina Rosetta Docker image: :::note If you want to build your own docker image, you can find more details in [Mina's Rosetta repository](https://github.com/MinaProtocol/mina/blob/develop/src/app/rosetta/README.md). However, for most users, it's not necessary to build your own image in order to interact with the API. ::: The container in `/rosetta` includes three entrypoints, which each run a different set of services connected to a particular network. - **docker-start.sh** (default) - connects the mina node to a network (defaults to Mainnet) and initializes the archive database from publicly-available nightly O(1) Labs backups. This script runs a mina node, mina-archive, a postgresql DB, and mina-rosetta. The script also periodically checks for blocks that may be missing between the nightly backup and the tip of the chain and will fill in those gaps by walking back the linked list of blocks in the canonical chain and importing them one at a time. The script is configurable through environment variables. Take a look at the source for more information about what and how you can configure. - **docker-standalone-start.sh** - starts only the mina-rosetta API endpoint and any flags passed into the script go to mina-rosetta. You may use this for the "offline" part of the Construction API or if you want a setup with each service in its own container. - **docker-demo-start.sh** launches a mina node with a very simple 1-address genesis ledger as a sandbox for developing and playing around in. This script starts the full suite of tools (a mina node, mina-archive, a postgresql DB, and mina-rosetta), but for a demo network with all operations occurring inside this container and no external network activity. Run the container with following command (replace the image tag with one from dockerhub that's compatible with the network you are trying to connect to, also replace `--entrypoint` and any environment variable if needed): ``` docker run -it --rm --name rosetta \ --entrypoint=./docker-start.sh \ -p 10101:10101 -p 3085:3085 -p 3086:3086 -p 3087:3087 \ minaprotocol/mina-rosetta:3.3.0-8c0c2e6-bullseye-mainnet ``` You can also create a file with the environment variables and pass it to the docker run command with `--env-file` flag. For example, create a file named `mainnet.env` with the following content: ``` MINA_NETWORK=mainnet PEERS_LIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt MINA_ARCHIVE_DUMP_URL=https://storage.googleapis.com/mina-archive-dumps MINA_GENESIS_LEDGER_URL=https://storage.googleapis.com/o1labs-gitops-infrastructure/mainnet/mainnet.json BLOCKS_BUCKET=https://storage.googleapis.com/mina_network_block_data ``` Then run the container with the following command: ``` docker run -it --rm --name rosetta \ --entrypoint=./docker-start.sh \ -p 8302:8302 -p 3085:3085 -p 3086:3086 -p 3087:3087 \ --env-file mainnet.env \ minaprotocol/mina-rosetta: ``` Example environment files for public networks can be found in [this](https://github.com/MinaProtocol/mina/blob/develop/src/app/rosetta/scripts) directory of Mina's Rosetta repository. :::note - It can take 20 min to 1 hour for your node to sync - Port 8302 is the default P2P port and must be exposed to the open internet - The GraphQL API runs on port 3085 (accessible via localhost:3085/graphql) - PostgreSQL runs on port 3086 - Rosetta runs on port 3087 ::: --- url: /node-operators/rosetta/samples --- # Code Samples These samples use `curl` and [`jq`](https://jqlang.github.io/jq/) to interact with the Rosetta API. They assume a running Rosetta instance on `localhost:3087`. Set these shell variables before running the examples: ```bash ROSETTA_URL="http://localhost:3087" NETWORK='{"blockchain":"mina","network":"mainnet"}' ``` All endpoints except `/network/list` require a `network_identifier` parameter. The samples include it in each request body. :::tip Replace `mainnet` with `devnet` if you are testing against a devnet instance. ::: --- url: /node-operators/rosetta/samples/requests --- # Requests and Responses The Rosetta API specification defines high-level descriptions of request and response objects. Exact JSON layouts differ between blockchains. This page covers Mina-specific objects and shows how to query each endpoint with curl. All examples assume the shell variables from the [Code Samples](/node-operators/rosetta/samples) setup. ## Network endpoints List available networks: ```bash curl -s "$ROSETTA_URL/network/list" \ -H 'Content-Type: application/json' \ -d '{"metadata":{}}' | jq . ``` Sample response: ```json {"network_identifiers":[{"blockchain":"mina","network":"mainnet"}]} ``` You must pass the `network_identifier` object as a parameter to all other endpoints. In Mina's Rosetta implementation, it exists only for the network you run Rosetta for, so this array always contains one object. Get network status (current block height, sync state, peers): ```bash curl -s "$ROSETTA_URL/network/status" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq . ``` Get supported options and operation types: ```bash curl -s "$ROSETTA_URL/network/options" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq . ``` ## Block and transaction queries Fetch a block by index: ```bash curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"index\":1000}}" | jq . ``` Fetch a block by hash: ```bash curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"hash\":\"BLOCK_HASH\"}}" | jq . ``` List pending transactions in the mempool: ```bash curl -s "$ROSETTA_URL/mempool" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq . ``` ## Account queries Query an account balance: ```bash curl -s "$ROSETTA_URL/account/balance" \ -H 'Content-Type: application/json' \ -d "{ \"network_identifier\":$NETWORK, \"account_identifier\":{\"address\":\"B62qr...\",\"token_id\":\"wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf\"} }" | jq . ``` Search for transactions by address: ```bash curl -s "$ROSETTA_URL/search/transactions" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"address\":\"B62qr...\"}" | jq . ``` Search for a specific transaction by hash: ```bash curl -s "$ROSETTA_URL/search/transactions" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"transaction_identifier\":{\"hash\":\"CkpY...\"}}" | jq . ``` Derive an account address from a public key: ```bash curl -s "$ROSETTA_URL/construction/derive" \ -H 'Content-Type: application/json' \ -d "{ \"network_identifier\":$NETWORK, \"public_key\":{\"hex_bytes\":\"PUBLIC_KEY_HEX\",\"curve_type\":\"pallas\"} }" | jq . ``` ## Operation object In Rosetta terminology, each transaction consists of one or more operations. In Mina's implementation, each operation has: - `operation_identifier` and `related_operations`: a mandatory index, and optional array of related operations - `type`: the operation type - `account`: the account identifier the operation relates to - `amount`: an object with `value` — a signed number representing the balance change
Sample operation JSON ```json { "operation_identifier": { "index": 2 }, "related_operations": [{ "index": 1 }], "type": "payment_receiver_inc", "account": { "address": "B62qqJ1AqK3YQmEEALdJeMw49438Sh6zuQ5cNWUYfCgRsPkduFE2uLU", "metadata": { "token_id": "1" } }, "amount": { "value": "90486110", "currency": { "symbol": "MINA", "decimals": 9 } } } ```
:::note All possible operation types are available from the `/network/options` endpoint. The most common types are `fee_payment`, `payment_source_dec`, and `payment_receiver_inc`. ::: ## Transfer transaction layout A MINA token transfer is represented by three operations (account updates): 1. Decrease fee payer balance (fee payer = sender) 2. Decrease sender balance by the transfer amount 3. Increase receiver balance by the transfer amount
Sample transfer transaction JSON ```json { "transaction_identifier": { "hash": "CkpYVELyYvzbyAwYcnMQryEeQ7Gd6Ws7mZNXpmF5kEAyvwoTiUfbX" }, "operations": [ { "operation_identifier": { "index": 0 }, "type": "fee_payment", "account": { "address": "B62qpLST3UC1rpVT6SHfB7wqW2iQgiopFAGfrcovPgLjgfpDUN2LLeg", "metadata": { "token_id": "1" } }, "amount": { "value": "-37000000", "currency": { "symbol": "MINA", "decimals": 9 } } }, { "operation_identifier": { "index": 1 }, "type": "payment_source_dec", "account": { "address": "B62qpLST3UC1rpVT6SHfB7wqW2iQgiopFAGfrcovPgLjgfpDUN2LLeg", "metadata": { "token_id": "1" } }, "amount": { "value": "-58486000", "currency": { "symbol": "MINA", "decimals": 9 } } }, { "operation_identifier": { "index": 2 }, "related_operations": [{ "index": 1 }], "type": "payment_receiver_inc", "account": { "address": "B62qkiF5CTjeiuV1HSx4SpEytjiCptApsvmjiHHqkb1xpAgVuZTtR14", "metadata": { "token_id": "1" } }, "amount": { "value": "58486000", "currency": { "symbol": "MINA", "decimals": 9 } } } ] } ```
This operations array is what you pass to `/construction/preprocess` and `/construction/payloads` when building a transfer. See [Sending Transactions](send-transactions) for the full flow. --- url: /node-operators/rosetta/samples/scan-blocks --- # Scanning Blocks To poll for new blocks, query `/network/status` for the current block height, then fetch each block sequentially. Get the current block height: ```bash curl -s "$ROSETTA_URL/network/status" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq '.current_block_identifier.index' ``` Fetch a specific block by index: ```bash BLOCK_INDEX=1000 curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"index\":$BLOCK_INDEX}}" | jq . ``` A simple polling loop that waits for new blocks: ```bash HEIGHT=$(curl -s "$ROSETTA_URL/network/status" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq '.current_block_identifier.index') while true; do BLOCK=$(curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"index\":$HEIGHT}}") if echo "$BLOCK" | jq -e '.block' > /dev/null 2>&1; then echo "Block $HEIGHT:" echo "$BLOCK" | jq '.block.transactions[] | .transaction_identifier.hash' HEIGHT=$((HEIGHT + 1)) else sleep 10 fi done ``` --- url: /node-operators/rosetta/samples/send-transactions --- # Sending Transactions :::info This flow follows the [Construction API Overview](https://docs.cloud.coinbase.com/rosetta/docs/construction-api-overview) from the official Rosetta documentation. ::: The steps to send a MINA payment: 1. Derive the account address from a public key 2. Build the unsigned transaction via preprocess → metadata → payloads 3. Sign offline with the [signer tool](/node-operators/mina-signer) 4. Combine the signature into a signed blob 5. Submit the signed transaction ## Prerequisites - A key pair generated with the [offline signer tool](/node-operators/mina-signer) - The account must have a balance (send test funds on devnet first) - Set the shell variables from the [Code Samples](/node-operators/rosetta/samples) setup Set your keys and transfer parameters: ```bash PUBLIC_KEY="YOUR_PUBLIC_KEY_HEX" SENDER="B62q..." RECEIVER="B62q..." TOKEN_ID="wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf" FEE=10000000 # 0.01 MINA in nanomina VALUE=1000000000 # 1 MINA in nanomina ``` ## Step 1: Derive account address ```bash curl -s "$ROSETTA_URL/construction/derive" \ -H 'Content-Type: application/json' \ -d "{ \"network_identifier\":$NETWORK, \"public_key\":{\"hex_bytes\":\"$PUBLIC_KEY\",\"curve_type\":\"pallas\"} }" | jq . ``` ## Step 2: Build the operations payload Construct the three operations that represent a MINA transfer (see [Requests and Responses](requests#transfer-transaction-layout) for details on the structure): ```bash OPERATIONS='[ { "operation_identifier":{"index":0}, "type":"fee_payment", "account":{"address":"'"$SENDER"'","metadata":{"token_id":"'"$TOKEN_ID"'"}}, "amount":{"value":"-'"$FEE"'","currency":{"symbol":"MINA","decimals":9}} }, { "operation_identifier":{"index":1}, "type":"payment_source_dec", "account":{"address":"'"$SENDER"'","metadata":{"token_id":"'"$TOKEN_ID"'"}}, "amount":{"value":"-'"$VALUE"'","currency":{"symbol":"MINA","decimals":9}} }, { "operation_identifier":{"index":2}, "related_operations":[{"index":1}], "type":"payment_receiver_inc", "account":{"address":"'"$RECEIVER"'","metadata":{"token_id":"'"$TOKEN_ID"'"}}, "amount":{"value":"'"$VALUE"'","currency":{"symbol":"MINA","decimals":9}} } ]' ``` ## Step 3: Preprocess ```bash PREPROCESS=$(curl -s "$ROSETTA_URL/construction/preprocess" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"operations\":$OPERATIONS}") echo "$PREPROCESS" | jq . ``` ## Step 4: Metadata ```bash METADATA=$(curl -s "$ROSETTA_URL/construction/metadata" \ -H 'Content-Type: application/json' \ -d "$(echo "$PREPROCESS" | jq -c ". + { \"network_identifier\":$NETWORK, \"public_keys\":[{\"hex_bytes\":\"$PUBLIC_KEY\",\"curve_type\":\"pallas\"}] }")") echo "$METADATA" | jq . ``` ## Step 5: Payloads (unsigned transaction) ```bash PAYLOADS=$(curl -s "$ROSETTA_URL/construction/payloads" \ -H 'Content-Type: application/json' \ -d "$(echo "$METADATA" | jq -c ". + { \"network_identifier\":$NETWORK, \"operations\":$OPERATIONS }")") echo "$PAYLOADS" | jq . UNSIGNED_TX=$(echo "$PAYLOADS" | jq -r '.unsigned_transaction') ``` ## Step 6: Sign offline Use the [signer CLI tool](/node-operators/mina-signer#signing-a-transaction-with-signer-cli): ```bash SIGNATURE=$(signer sign --private-key "$PRIVATE_KEY" --unsigned-transaction "$UNSIGNED_TX") ``` ## Step 7: Combine ```bash SIGNING_PAYLOAD=$(echo "$PAYLOADS" | jq -c '.payloads[0]') COMBINE=$(curl -s "$ROSETTA_URL/construction/combine" \ -H 'Content-Type: application/json' \ -d "{ \"network_identifier\":$NETWORK, \"unsigned_transaction\":\"$UNSIGNED_TX\", \"signatures\":[{ \"signing_payload\":$SIGNING_PAYLOAD, \"public_key\":{\"hex_bytes\":\"$PUBLIC_KEY\",\"curve_type\":\"pallas\"}, \"signature_type\":\"schnorr_poseidon\", \"hex_bytes\":\"$SIGNATURE\" }] }") SIGNED_TX=$(echo "$COMBINE" | jq -r '.signed_transaction') echo "$COMBINE" | jq . ``` ## Step 8: Get transaction hash ```bash curl -s "$ROSETTA_URL/construction/hash" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"signed_transaction\":\"$SIGNED_TX\"}" | jq . ``` ## Step 9: Submit ```bash curl -s "$ROSETTA_URL/construction/submit" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"signed_transaction\":\"$SIGNED_TX\"}" | jq . ``` After submission, you can monitor for confirmation using the [block scanning](scan-blocks) approach — poll blocks until your transaction hash appears. --- url: /node-operators/rosetta/samples/track-deposits --- # Tracking Deposits To track deposits, scan each block for `payment_receiver_inc` operations matching your deposit address. Fetch a block and filter for deposits to a specific address: ```bash DEPOSIT_ADDRESS="B62qr..." BLOCK_INDEX=1000 curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"index\":$BLOCK_INDEX}}" \ | jq --arg addr "$DEPOSIT_ADDRESS" ' .block.transactions[] | { tx_hash: .transaction_identifier.hash, deposits: [ .operations[] | select(.account.address == $addr and .type == "payment_receiver_inc") | { amount: .amount.value } ] } | select(.deposits | length > 0) ' ``` A continuous deposit monitoring loop: ```bash DEPOSIT_ADDRESS="B62qr..." HEIGHT=$(curl -s "$ROSETTA_URL/network/status" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK}" | jq '.current_block_identifier.index') while true; do BLOCK=$(curl -s "$ROSETTA_URL/block" \ -H 'Content-Type: application/json' \ -d "{\"network_identifier\":$NETWORK,\"block_identifier\":{\"index\":$HEIGHT}}") if echo "$BLOCK" | jq -e '.block' > /dev/null 2>&1; then echo "$BLOCK" | jq --arg addr "$DEPOSIT_ADDRESS" ' .block.transactions[] | { tx_hash: .transaction_identifier.hash, deposits: [ .operations[] | select(.account.address == $addr and .type == "payment_receiver_inc") | { amount: .amount.value } ] } | select(.deposits | length > 0) ' HEIGHT=$((HEIGHT + 1)) else sleep 10 fi done ``` --- url: /node-operators/seed-peers/docker-compose --- # Docker Compose Seed Peer This example demonstrates how to run a Mina Seed node using Docker Compose for the Mainnet network. This Docker Compose setup includes a Mina seed node, and a script to generate a libp2p key. Copy and paste the provided configuration into a `docker-compose.yml` file. Then run `docker compose up -d` to start the services, and use `docker compose logs -f` to monitor the logs. ```yaml services: generate_libp2p_key: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' environment: MINA_LIBP2P_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina libp2p generate-keypair -privkey-path /root/.mina-config/keys/libp2p-key chmod -R 0700 /root/.mina-config/keys chmod -R 0600 /root/.mina-config/keys/libp2p-key ' volumes: - './node/mina-config:/root/.mina-config' mina_node: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' # image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' # Use this image for Devnet restart: always environment: MINA_LIBP2P_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --libp2p-keypair /root/.mina-config/keys/libp2p-key \ --seed ' # use --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt for Devnet volumes: - './node/mina-config:/root/.mina-config' ports: - '8302:8302' depends_on: generate_libp2p_key: condition: service_completed_successfully ``` To retrieve the status of the Mina Node, run `docker compose exec mina_node mina client status` In the client status, you should also see the _Adresses and ports_ section. ```shell Addresses and ports: External IP: 35.197.32.58 Bind IP: 0.0.0.0 Libp2p PeerID: 12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 Libp2p port: 8302 Client port: 8301 ``` Base on the above output, you can build you "relay circuit" address as follows: ```shell /ip4/35.197.32.58/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 ``` If you prefer using a DNS instead of an IP address, you can use the following format: ```shell /dns4/seed.example.com/tcp/8302/p2p/12D3KooW9wsoTH3RvWJntT8CnQAMKAYgd1DztxumTaeH3TikQ6b3 ``` Finally, you can add the relay circuit address the official Mina Seed Peers list by submitting a pull request to the [MinaFoundation/seeds](https://github.com/MinaFoundation/seeds) repository --- url: /node-operators/seed-peers/generating-a-libp2p-keypair --- # Generating a libp2p Key Pair libp2p keypairs are gossip network identities. To ensure connectivity across the network, all seed nodes must start with a **stable** libp2p keypair so that other nodes can reliably connect. :::info libp2p keys are different from wallet keys. To generate a wallet key pair, see [Generating a Key Pair](/node-operators/validator-node/generating-a-keypair). ::: ## Generate the keypair Use the `mina libp2p generate-keypair` command: ```sh mina libp2p generate-keypair --privkey-path ~/keys/my-libp2p ``` :::caution Do not store libp2p keys in the same file as your wallet keys. ::: ## Use the keypair Pass the generated key to the Mina daemon with the `--libp2p-keypair` flag: ```sh mina daemon ... --libp2p-keypair ~/keys/my-libp2p ... ``` See [Seed Peers Getting Started](/node-operators/seed-peers/getting-started) for full seed node configuration. --- url: /node-operators/seed-peers/getting-started --- # Seed Peers Getting Started Seed peers are our helpful allies that make it easy for the rest of us to connect to the network. Most nodes connect to the Mina network using seed peers that are run explicitly as seed nodes. ## Running a Seed Node The two important things about seed nodes: 1. Their address should be static 2. They need high uptime and be able to support many connections -- thus they should avoid doing as much as possible other than "seeding" ### Enforcing and publishing a static address First of all, you need a static host where you'll be running your node. Preferably, you can use DNS and host your seed node at, for example: `seed.o1test.net`. Alternatively, you can also set up a static ipv4 address such as `82.230.217.200`. Secondly, you'll need to select the port that your node is running on. By default, it's on `8302`. Thirdly, you'll want to pregenerate your libp2p keypair -- this is used to identify you on the gossip network. See [Generating a libp2p Key Pair](/node-operators/seed-peers/generating-a-libp2p-keypair) for instructions. Then run your daemon with the `--libp2p-keypair ` and `--seed` flags: Finally you'd publish your DNS address like so: ``` /dns4/seed.o1test.net/tcp/8302/p2p/12D3KooWGDHtsPUS8dZk3x3FUgsXCWwpnSJ6W7EwkWZKBZXczkwC ``` Or a static IP one in this manner: ``` /ip4/82.230.217.200/tcp/8302/p2p/12D3KooWCE97fGwuDCicVNK3ZWF8fVzfNezp3uGjmSc8VrRFem6a ``` This address string can be used for folks to connect to you. ### Tuning your node for uptime and high connections Firstly, don't run block production or SNARK working on this node. Full stop. By doing neither of these things, the surface area for logic executing on this node reduces drastically. It would be preferable to run with a larger `--max-connection` flag. At least 100. You'll still be able to seed with more than 100 nodes in total, it's just that you'll only be able to maintain connections with 100 at once. ## Example Configuration Create a file called `~/.mina-env` to store your private configuration, passwords, etc. ``` MINA_LIBP2P_PASS="My_V3ry_S3cure_Password" LOG_LEVEL=Info FILE_LOG_LEVEL=Debug EXTRA_FLAGS=" --libp2p-keypair --seed --max-connection 100" PEERS_LIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt ``` Please note that `` could change in value depending on where you stored your libp2p keypair from the previous steps. In Docker, the keypath will always be `/keys/filename` due to where volumes are mounted. Follow along as normal with systemctl to start the mina service: ```sh systemctl --user daemon-reload systemctl --user start mina systemctl --user enable mina sudo loginctl enable-linger ``` Run the image with your config and keys mounted into the container: ``` cd ~ docker run --name mina-seed-node -d \ --restart always \ -p 8302:8302 \ -v "$(pwd)/keys:/root/keys:ro" \ -v "$(pwd)/.mina-config:/root/.mina-config" \ -v "$(pwd)/.mina-env:/entrypoint.d/mina-env:ro" \ minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet \ daemon ``` Make sure to create `~/.mina-env` as described above so that it can be mounted into the Docker container. ## Peers List There will be a peers list hosted with a handful of o1Labs nodes and another much larger handful of addresses from folks unaffiliated with o1Labs. This list is curated for nodes that should be great seed peers and will try their best to keep the list up-to-date as well. ## Alternate Peer Lists We have a decentralized network after all -- we encourage other members in the community to host seed lists. To create a list, please talk to those you trust and use their addresses as seed peers. To consume such alternate lists, you can swap the parameter `--peer-list-file` or `--peer-list-url` to point to another one. --- url: /node-operators/seed-peers --- # About Seed Peers Seed peer providers are an independent group of nodes that assist new nodes to find peers and connect to the Mina Protocol. Seed peers improve the onboarding experience for other nodes and make sure the nodes start bootstrapping as soon as possible. Mina's seed peers are considered to be leaders among the community. They are not compensated in any way - they perform their role as a service to the Mina community. For the full list of seed peers and information on how to contribute, please refer to the [Official Git Repository](https://github.com/MinaFoundation/seeds). - **Mainnet**: https://bootnodes.minaprotocol.com/networks/mainnet.txt - **Devnet**: https://bootnodes.minaprotocol.com/networks/devnet.txt ## Seed Peers This section describes how to run a seed peer on the Mina protocol. - [Getting Started](seed-peers/getting-started) - How to get started running a seed peer. --- url: /node-operators/snark-workers/docker-compose --- # Docker Compose SNARK Workers This example runs a SNARK coordinator and a SNARK worker together using Docker Compose. It includes a one-time init container that generates a wallet key. Save the following as `docker-compose.yml`, then start with `docker compose up -d`. Monitor logs with `docker compose logs -f`. ```yaml services: generate_wallet_key: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' environment: MINA_PRIVKEY_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key chmod -R 0700 /root/.mina-config/keys chmod -R 0600 /root/.mina-config/keys/wallet-key ' volumes: - './node/mina-config:/root/.mina-config' mina_snark_coordinator: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' restart: always environment: MINA_PRIVKEY_PASS: PssW0rD MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" healthcheck: test: ["CMD-SHELL", "mina client status"] interval: 60s timeout: 10s retries: 100 entrypoint: [] command: > bash -c ' mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --snark-worker-fee 0.001 \ --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ --work-selection rand ' volumes: - './node/mina-config:/root/.mina-config' ports: - '8302:8302' depends_on: generate_wallet_key: condition: service_completed_successfully mina_snark_worker: image: 'minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet' restart: always entrypoint: [] command: > bash -c ' mina internal \ snark-worker \ --daemon-address \ mina_snark_coordinator:8301 \ --proof-level full ' volumes: - './node/mina-config:/root/.mina-config' depends_on: mina_snark_coordinator: condition: service_healthy ``` ```yaml services: generate_wallet_key: image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' environment: MINA_PRIVKEY_PASS: PssW0rD entrypoint: [] command: > bash -c ' mina advanced generate-keypair --privkey-path /root/.mina-config/keys/wallet-key chmod -R 0700 /root/.mina-config/keys chmod -R 0600 /root/.mina-config/keys/wallet-key ' volumes: - './node/mina-config:/root/.mina-config' mina_snark_coordinator: image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' restart: always environment: MINA_PRIVKEY_PASS: PssW0rD MINA_CLIENT_TRUSTLIST: "0.0.0.0/0" healthcheck: test: ["CMD-SHELL", "mina client status"] interval: 60s timeout: 10s retries: 100 entrypoint: [] command: > bash -c ' mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt \ --snark-worker-fee 0.001 \ --run-snark-coordinator $(cat /root/.mina-config/keys/wallet-key.pub) \ --work-selection rand ' volumes: - './node/mina-config:/root/.mina-config' ports: - '8302:8302' depends_on: generate_wallet_key: condition: service_completed_successfully mina_snark_worker: image: 'gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet' restart: always entrypoint: [] command: > bash -c ' mina internal \ snark-worker \ --daemon-address \ mina_snark_coordinator:8301 \ --proof-level full ' volumes: - './node/mina-config:/root/.mina-config' depends_on: mina_snark_coordinator: condition: service_healthy ``` To scale additional workers, duplicate the `mina_snark_worker` service with a different name (e.g. `mina_snark_worker_2`). --- url: /node-operators/snark-workers/getting-started --- # SNARK Workers Getting Started :::note Before following this guide, complete the Validator Node setup — from [Requirements](/node-operators/validator-node/requirements) through [Connect to Mainnet or Devnet](/node-operators/validator-node/connecting-to-the-network). You should have a synced node and a [key pair](/node-operators/validator-node/generating-a-keypair) before proceeding. ::: There are two modes for running SNARK work: - **Embedded worker** — the daemon runs a single SNARK worker internally. Simpler to set up, no external processes needed. - **Coordinator with external workers** — the daemon runs a SNARK coordinator that distributes work to one or more external SNARK worker processes. Use this to scale across multiple machines or cores. In both modes, the daemon also participates in the network as a normal validator. ## Embedded SNARK worker Run the daemon with `--run-snark-worker` to produce SNARK proofs directly within the daemon process: ```sh mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --run-snark-worker $SNARK_WORKER_PUBLICKEY \ --snark-worker-fee 0.001 \ --work-selection seq ``` | Flag | Description | |--|--| | `--run-snark-worker` | Public key to receive SNARK work fees | | `--snark-worker-fee` | Fee (in MINA) to charge per SNARK proof | | `--work-selection` | Work selection method: `seq`, `rand`, or `roffset` | | `--snark-worker-parallelism` | Number of threads for SNARK work (does not affect block production) | ## Coordinator with external workers ### Start the coordinator Run the daemon with `--run-snark-coordinator`. The coordinator distributes work to external SNARK worker processes, propagates the generated proofs to the network, and sets the public key that receives SNARK work fees from those workers: ```sh mina daemon \ --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt \ --run-snark-coordinator $SNARK_WORKER_PUBLICKEY \ --snark-worker-fee 0.001 \ --work-selection seq ``` | Flag | Description | |--|--| | `--run-snark-coordinator` | Public key to receive SNARK work fees from external workers | | `--snark-worker-fee` | Fee (in MINA) to charge per SNARK proof | | `--work-selection` | Work selection method: `seq`, `rand`, or `roffset` | ### Connect workers to the coordinator :::caution The protocol between the coordinator and workers is not secure. Only run workers on the same intranet as the coordinator — do not expose the coordinator port to the public internet. ::: On each worker machine, run: ```sh mina internal snark-worker \ --proof-level full \ --shutdown-on-disconnect false \ --daemon-address ``` The default coordinator port is `8301`. Use `--snark-worker-parallelism` on the worker to set the number of threads used for SNARK work. For a Docker Compose example that sets up a coordinator and worker together, see [Docker Compose Example](/node-operators/snark-workers/docker-compose). ## Related - [Mina CLI Reference](/node-operators/reference/mina-cli-reference) — Full `mina daemon` command reference - [FAQ: SNARKs and SNARK Workers](/node-operators/faq#snarks-and-snark-workers) — Common questions about SNARK pricing, fees, and performance --- url: /node-operators/snark-workers --- # SNARK Workers While most protocols have one primary group of node operators (miners, validators, or block producers), Mina has a second group — **SNARK workers**. These nodes produce [zk-SNARK](/glossary#zk-snark) proofs of transactions, which keep the Mina blockchain at a constant size instead of growing over time. A **SNARK coordinator** can distribute work across a pool of SNARK workers. Deep knowledge of zk-SNARKs is not required to run a SNARK worker, but for background see the [What are zk-SNARKs?](https://minaprotocol.com/blog/what-are-zk-snarks) primer. ## Next steps - [Getting Started](/node-operators/snark-workers/getting-started) — Run a SNARK worker or coordinator - [Docker Compose Example](/node-operators/snark-workers/docker-compose) — Run a coordinator and worker with Docker Compose - [FAQ: SNARKs and SNARK Workers](/node-operators/faq#snarks-and-snark-workers) — Common questions about SNARK pricing, fees, and performance --- url: /node-operators/troubleshooting --- # Troubleshooting Here are some common problems you might encounter while trying to set up the Mina daemon. If you can't find your issue here please ask for help on [Discord](https://bit.ly/MinaDiscord) or open an issue on [Github](https://github.com/MinaProtocol/mina/issues). - [General](#general) - [Syncing a node](#syncing-a-node) - [Networking](#networking) - [Accounts and Transactions](#accounts-and-transactions) - [Block producer](#block-producer) - [SNARK worker](#snark-worker) - [Logging](#logging) ## General ### My node crashes every few minutes? If the node crashes quickly and repeatably, this is likely a configuration issue such as incorrect permissions on the private key, failing to find peers due to incorrectly passing the peers.txt file, an incorrect password or special characters in the password. The last few lines of the logs should provide more information on the issue. ### I closed my SSH terminal, and the node crashed? If you start the mina daemon in the foreground, once you detach from it, it will shut down (via a SIGINT signal). To run the process in the background so that you may detach, you have many options: - Start the daemon with the `-background` flag. - Run as a systemd service (see [the docs](/node-operators/validator-node/connecting-to-the-network#running-mina-node-as-a-service)). - Run with Docker (see [the docs](/node-operators/validator-node/connecting-to-the-network#running-mina-node-as-a-service)). - Run the daemon in a terminal multiplexer such as screen or [tmux](https://icohigh.gitbook.io/mina-node-testnet/english/setting-up-tmux) that you can detach from to keep the process running. Running as a service / via Docker is recommended as they have the advantage of automated restarts if your node crashes. ### What permissions are required for the keys directory? The `keys` directory should have 700 permissions, and the private key file 600. For example, these commands update the permissions when the keys directory is contained within your home directory and your private key file is named `my-wallet`: ``` chmod 700 ~/keys chmod 600 ~/keys/my-wallet ``` ### Can I run on a Raspberry Pi / ARM-based device? No. Only x86-64 is supported and not ARM. ### I have special characters in my password, and it is giving an error? You should use quotes around the password i.e. `"MY_PASSWORD"` and/or you can escape the special characters such as `$` in the password using the `\` character. ### I get a permissions error when running the docker command? Add the current user to the docker group as per [this article](https://docs.docker.com/engine/install/linux-postinstall/). You could prefix the command with `sudo`, but this is not recommended. ### I see monitor.ml.Error "Timed out getting connection from process" on macOS? If you're running Mina on macOS and see the following time out error `monitor.ml.Error "Timed out getting connection from process"`, you'll need to add your hostname to `/etc/hosts` by running the following: - $ `hostname` to get your hostname - Open the `/etc/hosts` file and add the mapping: ``` ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 127.0.0.1 This is necessary because sometimes macOS doesn't resolve your hostname to your local IP address. ``` ### What hardware do I need? See the requirements for the current network [here](/node-operators/block-producer-node/getting-started). Some lower-tier VPS providers may have an issue producing blocks within the slot time. If you continue to experience missing blocks, you may wish to try on more powerful hardware. ### I would like the mina service to start on boot? If you use `systemd` to manage the Mina daemon then it will not automatically restart on a reboot of the machine. You can manually run the service with `start` via `systemctl --user start mina` or start the service automatically at boot with `enable` by using `systemctl --user enable mina`. ### What should I add for MINA_PRIVKEY_PASS? When you generated a keypair, you created a password. Use the password you created for the value of `MINA_PRIVKEY_PASS`. ### I get an error about ~/.mina-config/daemon.json missing? This is an optional file to pass [configuration options](/node-operators/reference/mina-cli-reference#mina-daemon) to the daemon (rather than passing via the command line). The daemon looks for it by default, which results in an error if you do not include it. Just ignore this error (unless you are trying to include it) as it is not fatal, and the daemon will start as per normal. ### I see messages about prover/verifier being killed periodically This is normal, and these processes are currently periodically killed and restarted. Ignore these messages unless they result in a fatal error/crash. ### I crashed with "Fatal error: out of memory"? This is a common issue - see [this issue](https://github.com/MinaProtocol/mina/issues/6851) on GitHub and add any relevant information with logs and restart your node. ### Can I provide my password using an environment variable? Yes. Set the `MINA_PRIVKEY_PASS` environment variable to be your password. ### I am trying to install on Ubuntu 20.04 / Debian 10 and get dependency errors? See this [guide for ubuntu 20.04](https://discordapp.com/channels/484437221055922177/583400552487059546/822269019687354418) on Mina Protocol Discord to manually resolve the required dependencies. Alternatively, use a [supported OS](https://github.com/MinaProtocol/mina/releases) or use Docker. ## Syncing a node ### I am stuck at block height of 1 and a max observed block length of 1 The output of `mina client status` outputs similar to the following: ``` Block height: 1 Max observed block length: 1 ``` This issue was fixed by the release `9652f8ee092ea77e29f5ab49fa0a295e36743e8b`, please ensure you have upgraded. It is normal to see a height of 1 while the daemon initializes. It could take several minutes (20 mins to an hour) before the node progress to the catchup phase. ### My "Max observed block length" is 1 but my block height is correct? This issue was fixed by the release `9652f8ee092ea77e29f5ab49fa0a295e36743e8b`, please ensure you have upgraded. After upgrading make sure you let the daemon run (20 mins to an hour), and the error should resolve itself. ### My node is stuck in catchup / the block height does not update When the node is synced, **Block height** should be equal to **Max observed block length**, as seen in the output of `mina client status` and should match the current height of the network, as shown in the screenshot below: ![Syncing a node](https://i.imgur.com/iWJTYTr.png) When starting the node, and the node is in a bootstrap/catchup state, the block height will display 1 or a number that is a few hundred blocks from the current best block length (but much greater than 1). During catchup, the block height will not incrementally update, other than when new blocks are produced and will jump to the correct height when catchup is complete. So be patient; this process can take several hours to complete and does vary depending on the hardware used. ### I synced at height 1 / not at the current height of the network? What matters is that your current blockchain length, as seen in `mina client status`, is equal to the current network height. If your node is reporting it is synced at the wrong height, it should eventually enter the catchup phase to get the node to the correct height. You may occasionally switch between catchup and synced if the network sees any short forks it tries to catch up to. ### Why does my blockchain height jump to 1000+ and then get stuck? We only need the last `k` (290) blocks of the blockchain to produce blocks. So once bootstrap is completed, the root of the transition frontier (essentially your local store of blocks) should be the current maximum height minus `k` (290). The part of the syncing process that takes significant time is downloading those missing `k` blocks, which is the role of **catchup**. During catchup, you won't see your block height increase (other than new blocks produced on the network) until it jumps to the current height and is synced. This takes time, so leave it running! ### My sync status is offline? This status indicates that you have not received any messages from peers for the last ~24 minutes. Ensure that you use the `--peer-list` argument that points to `https://bootnodes.minaprotocol.com/networks/mainnet.txt` See [Connect to Mainnet](/node-operators/validator-node/connecting-to-the-network). ## Networking ### My hosting provider is warning me: "Abuse message: Netscan detected" There is some behavior with our p2p networking module that triggers this warning on some hosting providers (specifically we've heard this happening with Hetzner). To mitigate this configure your firewall to allow traffic from ssh, http, https and deny outgoing traffic to all private ip addresses. Here is an example of this using the [ufw](https://help.ubuntu.com/community/UFW#UFW_-_Uncomplicated_Firewall) firewall tool. Thanks Ducca for sharing these rules and confirming they fix the issues on Hetzner. Allow SSH, HTTP, HTTPS porst: ``` ufw allow 22 ufw allow 80 ufw allow 443 ufw enable ``` Block outgoing private connection: ``` ufw deny out from any to 10.0.0.0/8 ufw deny out from any to 172.16.0.0/12 ufw deny out from any to 192.168.0.0/16 ufw deny out from any to 100.64.0.0/10 ufw deny out from any to 198.18.0.0/15 ufw deny out from any to 169.254.0.0/16 ``` See [this issue](https://github.com/MinaProtocol/mina/issues/7053) for more details. ### What ports need to be open? The only port required to be open for the daemon to communicate with peers is TCP port `8302`. The client port `8301` should **never** be exposed to the internet. There may be outdated references to other ports that were once used before but are no longer required. ### Node fails with "Failed to find any peers, crashing as this is not a seed node"? Ensure that you use the `--peer-list` argument that points to `https://bootnodes.minaprotocol.com/networks/mainnet.txt` See [Connect to Mainnet](/node-operators/validator-node/connecting-to-the-network). ### I get an error couldn't determine our IP from the internet? If you see `couldn't determine our IP from the internet, use --external-ip` flag, then the daemon failed to determine its own IP from [these service providers](https://github.com/MinaProtocol/mina/blob/056d0203722ddfec1c7ad216846434648cd7af5e/src/app/cli/src/find_ip.ml#L7-L11). Your firewall may be blocking HTTP/S requests, or you have a misconfigured network connection. To bypass this, pass in the flag `-external-ip ` when starting the Mina daemon. To get your external IP address, run `curl ifconfig.me`. ### Do I need to configure port forwarding manually? The Mina node does its best to configure itself to be able to connect to the outside world without you needing to do any extra work. However, this may fail, depending on your router and network setup. In this case, you may have to manually forward the external-port. A common cause of this is routers not supporting UPnP, a protocol that allows the node to configure the port forwarding automatically. If you experience this type of problem, find your router model and search for ` port forwarding` and follow the instructions to forward the ports from your router to your device running the Mina node. You'll need to open the TCP port `8302` by default. Note: When running Mina in the cloud, you should instead configure security groups for your cloud provider. ### Do I need to allow "Accept incoming connections" If you see one or more warnings like the below, then choose "Allow": ``` Do you want the application "mina" to accept incoming network connections? ``` ## Accounts and Transactions ### What fee should I use to send a transaction / my transaction is stuck as pending? Transactions that are included in blocks are prioritized by their transaction fees. If many transactions are pending, then the highest fee transactions will be included first. So, increasing your fees is the best way to ensure that your transaction is included. To view the transaction pool on a running node, you can use the following command (you will need to install `jq,` which is used to format the output of the following command, e.g., `sudo apt install jq`): ``` mina advanced pooled-user-commands | jq . | grep fee | sort | uniq -c | sort -n 1 "fee": "0.031", 5 "fee": "0.1", ``` If there are many transactions in the pool, you may need to increase your fee. For a visual overview of transaction fees, see [here](https://minascan.io/mainnet/home). If you have a stuck transaction due to a low fee, you will have to wait for it to be included in a block or to be evicted from the transaction pool as there is currently no way to cancel a transaction due to this [known issue](https://github.com/MinaProtocol/mina/issues/6605). ### How many transactions can be included in a block? On the current network, this is 128, which also includes the coinbase transaction as well as any fee transfers to pay SNARK workers. ### Can I cancel a transaction? You can cancel pending transactions. See [Mina Client](/node-operators/reference/mina-cli-reference#mina-client) or wallet instructions. ### I sent a transaction, but it was never included in a block? See [this answer](#what-fee-should-i-use-to-send-a-transaction--my-transaction-is-stuck-as-pending). The transaction was likely stuck as pending and then eventually evicted from the transaction pool. Try sending again. ### Why is the coinbase 0 / there are no transactions included in a block? In certain circumstances, there is no SNARK work available to be purchased or is too expensive to be purchased. In this case, it may not be possible to include a coinbase transaction, and so there is no coinbase awarded for the block. If transactions are not being included, the transaction fees likely do not cover the cost of the SNARK work required to be purchased to offset, including the transactions. ### Does the order of sending transactions matter? Yes, transactions are processed in order according to the nonce associated with the transaction. So, if you send a transaction that is stuck, with, for example, a low fee, all following transactions will also be stuck regardless of the fees used in the later transactions. Try to cancel the stuck transaction. ### Why does my account say "locked"? If the output of `mina accounts list` shows your account is locked, this means that you need to unlock it using your private key password in order to use it to send transactions. To unlock, simply use the `mina accounts unlock --public-key` command. A block producer does **not** need the account to be unlocked to produce blocks. ### What are time-locked accounts? Why are some accounts time locked and others are not? See [Time-Locked Accounts](/mina-protocol/time-locked-accounts). ### Can I send a payment before I am synced? Yes, but only if you have funds already in the ledger. If you requested funds from, e.g. the faucet or another community member, you will need to wait until you are synced so that you have a balance you can use to send. ### Error: Specified sender is not in the ledger or sent a transaction in transaction pool when sending a transaction See [this answer](#can-i-send-a-payment-before-i-am-synced). You will need to wait until you are synced if you do not have an existing balance in the ledger. ### I am running a block producer, but I don't see anything in mina accounts list? If you started the daemon passing the `block-producer-key` flag, then you still need to import the account to the daemon in order to send a transaction. To do so, use the `mina accounts import --privkey-path` command, passing in the location of the private key file. ## Block producer ### How do I run a block producer? The methods to start a node [in the documentation](/node-operators/validator-node/connecting-to-the-network) will run a block producer by default. ### How do I know if I am running a block producer To check the status of your block producer, run `mina client status` and look for the lines **Block producers running**. You should see a value of 1 and also your public key. ![Running a block producer](https://i.imgur.com/IsXZcXN.png) The line **Next block will be produced in** lets you know the next time you have won a slot to produce a block. If you have not won any further blocks in the epoch, a message "None this epoch..." will be displayed and will only update once a new epoch starts. ### How can I increase my chance of winning a block? The chance of winning a block is determined by a Verifiable Random Function (VRF), with the chance of winning a block being proportional to your stake. The VRF will always return the same result no matter how many times it is run, so there is no way of improving your chance of winning a block. Other than your staking balance, it is down to luck. The stake associated with your public key is determined in advance at the start of an epoch. There is a delay in it being considered, so receiving funds, block rewards, delegating other funds, and SNARK worker rewards will **not** improve your chance of winning a block in this epoch as these funds will not be considered in the staking ledger for at least another full epoch (~2 weeks). ### Why was my block orphaned? Why did I not get a block reward? There can be more than one block producer per slot due to the way block producers are selected. So if two (or more) blocks are produced for the same slot, it will cause a short fork, and only one will be chosen - the winner in this instance is random based on the VRF output for each block producer. If you consistently see orphaned blocks, then you may be producing blocks slowly, and so other block producers may not see your block before building atop the current longest chain. It is also possible to produce a block in catchup, and this block will also be quickly orphaned as it is not building on the correct height. ### Why did I not produce a block or miss a slot? There are a few reasons why you could miss a slot / not successfully produce a block, for example, the node restarting and being in bootstrap at the time of producing a slot. Also, you must produce a block within the slot time (3 mins). If you are on less powerful hardware or the daemon is competing for resources, it may not produce the block in time. In this instance, you should find in your logs: `Internally generated block $state_hash cannot be rebroadcast because it's not a valid time to do so ($timing)` It is not recommended to run a SNARK worker on the same machine at the same time you are producing a block as the SNARK worker is resource-intensive and may lead to the block not being produced in time. You can disable the SNARK worker during block production by, for example, using the [SNARK stopper script](https://github.com/c29r3/mina-snark-stopper). ### Why is the block rate so low / how often should there be a block? A slot on the current network is every 3 mins, though not all slots should have a block produced, so on average, we would expect a block every 4 mins. However, not all the stake is online and active in producing blocks, and so not all slots will have a block, and sometimes there can be long delays between blocks. As more of the stake is online and staking, this situation improves. ### Why does o1Labs win most of the blocks? To keep the network stable, o1Labs has 30% of the stake, so has a much greater probability of winning a slot and producing a block. Users who were given a balance of 66,000 mina have about a 0.1% chance of winning any particular slot, so should expect a block every couple of days, but luck plays a major factor in how often you will win a block. ### How do I know if I won a block or a transaction went through? The easiest way is to check a [block explorer](https://minascan.io/mainnet/home). You can also get this information for recent blocks via the [GraphQL API](https://minaprotocol.com/docs/node-developers/graphql-api). ### Why do I have a message of "No blocks won this this epoch"? See [this answer](#how-can-i-increase-my-chance-of-winning-a-block). ## SNARK worker ### My SNARK work is not getting bought. What fee should I use for a SNARK worker? If you are running a SNARK worker and not seeing any work being included in blocks, then likely others are producing cheaper SNARK work. Multiple SNARK workers are all competing for the same SNARK work, with only the lowest fee for each being included in the SNARK pool to be bought by block producers. Sometimes high fees will be included in blocks, and this is a function of how SNARK workers select which work to complete and which work is required to be purchased by the block producer. By default, the work selection for a SNARK worker is random. You can change this by adding the `-work-selection` flag to the `mina daemon` command: `-work-selection seq` will work on jobs in the order required to be included from the scan state and will likely result in your snarks being included without a potentially lengthy delay; `-work-selection roffset` functions similarly to the `seq` option, but it begins processing jobs from a random offset instead of starting with the first job indicated by the scan state. For choosing fees, you can look at historical blocks to determine prices that have been bought. ### How can I disable the SNARK worker? Run `mina client set-snark-worker` to disable the SNARK worker. To enable again, pass your public key `mina client set-snark-worker --address `. ### Can I run a SNARK worker and block producer on the same machine? Yes, you can, but you should stop the snark worker during block production so as not to compete for resources and miss producing a block. SNARK workers also consume more resources in general. See the [snark stopper script](https://github.com/c29r3/mina-snark-stopper) to help in automating this. ## Logging ### I see weird messages/errors in the logs? The logs are noisy and often contain "scary" looking messages such as failure to connect etc. As a general rule, if the message is not fatal and the node does not crash, it is likely nothing to be worried about. The below messages are all considered "normal": ``` "RPC #841 failed: \"internal RPC error error: unknown stream_idx\"" "Peer $peer didn't have enough information to answer ledger_hash query. See error for more details: $error" "Timed out waiting for the parent of $cached_transition after 0 ms, signalling a catchup job" "Failed to reset stream (this means it was probably closed successfully): $error error: { "string": "RPC #365 failed: \"internal RPC error error: unknown stream_idx\"" } ``` ### How can I get my logs running as a service? `journalctl --user -u mina -n 1000 -f` ### How do I get my logs running Docker? `docker logs --follow mina` ### How do I get my logs running the daemon manually? `tail -f ~/.mina-config/mina.log` ### How many logs are kept / where are the logs located? The `~/.mina-config` directory contains the Mina logs, see [Logging](/node-operators/validator-node/logging). This directory contains the following: - `mina.log` - This file contains the latest logs of the daemon. Each log file is limited to 10 MiB in size and rotates through 50 log files. Rotated log files are named `mina.log.x` from `mina.log.0` to `mina.log.50`. - `mina-best-tip.log` - This is used to write the best tip logs to make it easier to collect the required logs from nodes to determine the state for a hard fork. Each file is limited to 5 MiB and rotates through a maximum of 5 files from` mina-best-tip.log.0` to `mina-best-tip.log.5`. - `mina-prover.log` - This logs memory usage and batch size of the prover and is limited to 128 MiB and rotates via a single log file. - `mina-verifier.log` - This logs memory usage and batch size of the verifier and is limited to 128 MiB and rotates via a single log file. - `mina.version` - This file contains the Git SHA of the running daemon. --- url: /node-operators/validator-node/connecting-to-the-network --- # Connect to Mainnet or Devnet Use this guide to connect a node to either network and verify connectivity. If you're using Ubuntu or Debian, first follow the [installation guide](/node-operators/validator-node/installing-on-ubuntu-and-debian), then return to this page for node startup. ## Standalone node ### Start **Note:** A known issue exists with the Hetzner hosting provider. If you are using Hetzner, follow the [Networking troubleshooting](/node-operators/troubleshooting#my-hosting-provider-is-warning-me-abuse-message-netscan-detected) guidance before starting a node. ```sh mina daemon --peer-list-url https://bootnodes.minaprotocol.com/networks/mainnet.txt ``` Devnet is for testing and experimentation. MINA on Devnet has no real value. ```sh mina daemon --peer-list-url https://bootnodes.minaprotocol.com/networks/devnet.txt ``` ### Stop In a new terminal, run: ```sh mina client stop-daemon ``` ## Running mina node as a service Configure your node to keep running after logout and restart on reboot. ### Start the service Create `~/.mina-env` and set options as needed: ```sh MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" LOG_LEVEL=Info FILE_LOG_LEVEL=Debug ``` Start and enable the service: ```sh systemctl --user daemon-reload systemctl --user start mina systemctl --user enable mina sudo loginctl enable-linger ``` Prepare directories: ```sh cd ~ mkdir -p ~/.mina-config ``` Create `~/.mina-env`: ```sh export MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" LOG_LEVEL=Info FILE_LOG_LEVEL=Debug PEER_LIST_URL=https://bootnodes.minaprotocol.com/networks/mainnet.txt ``` ```sh export MINA_PRIVKEY_PASS="My_V3ry_S3cure_Password" LOG_LEVEL=Info FILE_LOG_LEVEL=Debug PEER_LIST_URL=https://bootnodes.minaprotocol.com/networks/devnet.txt ``` Run the container: ```sh docker run --name mina-node -d \ -p 8302:8302 \ --restart=always \ -v $(pwd)/.mina-env:/entrypoint.d/mina-env:ro \ -v $(pwd)/keys:/keys:ro \ -v $(pwd)/.mina-config:/root/.mina-config \ minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet \ daemon ``` ```sh docker run --name mina-node -d \ -p 8302:8302 \ --restart=always \ -v $(pwd)/.mina-env:/entrypoint.d/mina-env:ro \ -v $(pwd)/keys:/keys:ro \ -v $(pwd)/.mina-config:/root/.mina-config \ gcr.io/o1labs-192920/mina-daemon:3.3.0-alpha1-6929a7e-bullseye-devnet \ daemon ``` ### Stop the service ```sh systemctl --user stop mina ``` ```sh docker stop mina-node ``` ## Monitor the mina client status ```sh mina client status ``` ```sh docker exec -it mina-node mina client status ``` On first bootstrap, expect the following timeline: | Time after start | Expected status | |--|--| | 0 – ~5 min | `mina client status` may fail to connect while the daemon initializes | | ~5 – ~25 min | `Sync Status: Bootstrap` then `Sync Status: Catchup` | | ~30 min | `Sync Status: Synced` | Subsequent restarts sync faster when the on-disk cache in `~/.mina-config` is preserved. For Docker, ensure `/root/.mina-config` is mounted to a persistent host volume. ## Step up your game Once synced, continue with [Sending a Payment](/mina-protocol/sending-a-payment) and [Staking and Snarking](/node-operators/validator-node/staking-and-snarking). --- url: /node-operators/validator-node/generating-a-keypair --- # Wallet Key Pair To use Mina on Mainnet or to fully participate in a Mina test network, the first step is to generate a wallet key pair that consists of a public key and a private key. The public key identifies each block producer on the network. In some cases, you want to generate more than one wallet key pair. For example, to run a block producer most securely, it is advisable to have accounts on both hot and cold wallets. See [Hot and Cold Block Production](/node-operators/block-producer-node/hot-cold-block-production). Always give out your public keys. Mina will never ask you for your private keys. Be sure that your private keys are stored safely. :::caution Never give out your private key. ::: If you lose your private key or if a malicious actor gains access to your private key, you will lose access to your account and lose your account funds. ## Generate a wallet keypair The supported tools for generating wallet key pairs are: - [mina advanced generate-keypair](#using-mina-advanced-generate-keypair) command - [Ledger Hardware Wallet](#ledger-hardware-wallet) - [Mina Signer](#mina-signer) - [Mina command line wallet package](https://github.com/jspada/ledger-app-mina/blob/v1.0.0-beta.2/README.md#command-line-wallet) that interfaces with your Ledger device and Mina blockchain to generate addresses on the Ledger hardware wallet ### Using mina advanced generate-keypair #### Preparations 1. Create a folder on your system where you can store the key files. By convention, the `~/keys` folder: ```sh mkdir ~/keys ``` 2. Ensure the permissions are set properly for this folder to prevent unwanted processes from accessing these files: ```sh chmod 700 ~/keys ``` :::caution Make sure to set a new and secure password for the commands below. Mina will never ask you for this password. Do not share this password with anyone. ::: #### Using Docker If you don't have Mina installed locally, you can use Docker. Start an interactive shell with your keys directory mounted: ```sh docker run -it --rm --entrypoint /bin/bash \ --volume "$YOUR_KEY_DIR":/root/keys \ minaprotocol/mina-daemon:3.3.0-8c0c2e6-bullseye-mainnet ``` All `mina` commands below can then be run directly inside the container. #### Generate your wallet keypair Run the `mina advanced generate-keypair` command: ```sh mina advanced generate-keypair --privkey-path ~/keys/my-wallet ``` When prompted, type in the password you intend to use to secure this key. Do NOT forget this password. If already set, the tool uses the password from the `MINA_PRIVKEY_PASS` environment variable instead of prompting you. Two files are created for your public/private key pair: - `~/keys/my-wallet`: the encrypted private key - `~/keys/my-wallet.pub`: the public key in plain text Finally, ensure the permissions are set properly for the private key file to prevent unwanted processes from accessing it. ```sh chmod 600 ~/keys/my-wallet ``` Be sure to store the private key file and password you used in a secure place, such as a password manager. ### Ledger Hardware Wallet You can use your [Ledger Nano S](https://www.ledger.com/) hardware wallet to securely store your Mina private keys. To get started, install the Mina app on the [Ledger Hardware Wallet](/using-mina/ledger-hardware-wallet). ### Mina Signer You can also use [Mina Signer](/node-operators/mina-signer) to generate key pairs and sign transactions. ## Validate your private key Now that you've created your key, validate that it works. Use the `mina advanced validate-keypair` command to verify that you can sign a transaction. ```sh mina advanced validate-keypair --privkey-path ~/keys/my-wallet ``` ## Next steps Now that you have created a public/private key pair, you are ready to [connect to the network](/node-operators/validator-node/connecting-to-the-network) or share your public key. --- url: /node-operators/validator-node --- # Validator Node The essentials for running a Mina validator node. This section covers everything you need to set up and operate a basic Mina validator node — from initial requirements through day-to-day operations. ## Setup 1. **[Requirements](/node-operators/validator-node/requirements)** -- Hardware, software, and network requirements for each node type. 2. **[Installing on Ubuntu and Debian](/node-operators/validator-node/installing-on-ubuntu-and-debian)** -- Install Mina packages for Mainnet or Devnet on Ubuntu and Debian. 3. **[Generating a Key Pair](/node-operators/validator-node/generating-a-keypair)** -- Generate wallet and libp2p key pairs needed for node operation. 4. **[Connect to Mainnet or Devnet](/node-operators/validator-node/connecting-to-the-network)** -- Start your validator and connect it to the target network. ## Operations 5. **[Staking and Snarking](/node-operators/validator-node/staking-and-snarking)** -- Participate in consensus through staking, delegate MINA, and configure SNARK workers. 6. **[Querying Data](/node-operators/validator-node/querying-data)** -- Query blockchain data from your running node via GraphQL. 7. **[Logging](/node-operators/validator-node/logging)** -- Understand log files, log levels, and how to export logs for debugging. ## Next Steps Once your validator is running, explore advanced node configurations: - [Block Producer](/node-operators/block-producer-node) -- Produce blocks and earn rewards - [SNARK Worker](/node-operators/snark-workers) -- Generate zk-SNARKs and earn fees - [Archive Node](/node-operators/archive-node) -- Maintain historical blockchain data --- url: /node-operators/validator-node/installing-on-ubuntu-and-debian --- # Installation Supported environments include Linux (Debian 10, 11, 12 and Ubuntu 20.04, 22.04 and 24.04), any host with Docker, and macOS (build from source). The binary download is around 1 GB. For pre-release builds, see the [Mina Releases](https://github.com/MinaProtocol/mina/releases) page on GitHub. ## Install by platform ### Ubuntu and Debian ```sh sudo rm /etc/apt/sources.list.d/mina*.list echo "deb [trusted=yes] http://packages.o1test.net $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/mina.list sudo apt-get update sudo apt-get install --yes curl unzip mina-mainnet=3.3.0-8c0c2e6 ``` ```sh sudo rm /etc/apt/sources.list.d/mina*.list echo "deb [trusted=yes] http://packages.o1test.net $(lsb_release -cs) alpha" | sudo tee /etc/apt/sources.list.d/mina-devnet.list sudo apt-get install --yes apt-transport-https sudo apt-get update sudo apt-get install --yes curl unzip mina-devnet=3.3.0-alpha1 ``` ### Docker Docker is cross-platform (Linux, macOS, Windows). Install Docker from [Get Docker](https://docs.docker.com/get-docker/), then follow the [Connect to the Mina Network](/node-operators/validator-node/connecting-to-the-network) instructions to run the daemon as a container. ### Windows Windows is not natively supported. Use the [Docker](#docker) instructions instead. ### macOS No pre-built packages are available for macOS. Use [Docker](#docker) or [build from source](#build-from-source). ### Build from source On Linux or macOS, you can build from source by following the [Building Mina](https://github.com/MinaProtocol/mina/blob/master/README-dev.md#building-mina) instructions. ## Verify your installation ```sh mina version ``` The output should include a `Commit` line. ## Next steps - [Generating a Wallet Key Pair](/node-operators/validator-node/generating-a-keypair) - [Connect to Mainnet or Devnet](/node-operators/validator-node/connecting-to-the-network) --- url: /node-operators/validator-node/logging --- # Logging ## Log files Mina logs are stored in `~/.mina-config/`: | File | Description | Size limit | Rotation | |--|--|--|--| | `mina.log` | Main daemon logs | 10 MiB | 50 files (`mina.log.0` .. `mina.log.50`) | | `mina-best-tip.log` | Best tip logs (useful for hard fork analysis) | 5 MiB | 1 file | | `mina-prover.log` | Prover memory usage and batch sizes | 128 MiB | 1 file | | `mina-verifier.log` | Verifier memory usage and batch sizes | 128 MiB | 1 file | ## Following logs Depending on how you started the daemon: ```sh # Docker docker logs --follow mina-node # Systemd journalctl --user -u mina -n 1000 -f # Direct tail -f ~/.mina-config/mina.log ``` ## Log levels The Mina daemon supports the following log levels, from most to least verbose: 1. Spam 2. Trace 3. Debug 4. **Info** (default for stdout) 5. Warn 6. Error 7. Fatal Setting a level filters out all messages below it. For example, `Info` shows only Info, Warn, Error, and Fatal messages. ## Log format By default, logs are output as plain text. When `-log-json` is enabled, logs use the following JSON structure: ```json { "timestamp": "2020-12-23 21:25:04.616526Z", "level": "Error", "source": { "module": "Transition_router", "location": "File \"src/lib/transition_router/transition_router.ml\", line 231, characters 12-24" }, "message": "Failed to find any peers during initialization (crashing because this is not a seed node)", "metadata": { "host": "1.1.1.2", "peer_id": "12D3KooWGQSPgo7ypy9717D3Vgz2RHaqB2ndDRHEFcAfJDAv284q", "pid": 12, "port": 8302 } } ``` ## Daemon logging options Set these flags when starting the daemon: | Flag | Default | Description | |--|--|--| | `-log-level` | Info | Log level for stdout | | `-file-log-level` | Trace | Log level for log files | | `-log-json` | off | Output logs as JSON instead of plain text | | `-log-block-creation` | true | Log steps for including transactions and SNARK work in a block | | `-log-received-blocks` | false | Log blocks received from peers | | `-log-snark-work-gossip` | false | Log snark-pool diffs received from peers | | `-log-txn-pool-gossip` | false | Log transaction-pool diffs received from peers | | `-log-precomputed-blocks` | false | Include precomputed blocks in logs | ## Exporting logs ### From a running node ```sh mina client export-logs -tarfile ``` Compresses available logs into a `.tar.gz` archive in `~/.mina-config/exported_logs/`. The `-tarfile` flag is optional and defaults to the current date-time. Logs can also be exported via GraphQL using the `exportLogs` [mutation](/node-developers/graphql-api#mutations). ### From a stopped node ```sh mina client export-local-logs -tarfile ``` Same behavior, but works without a running daemon. ## Crash reports If the daemon crashes, it generates a crash report in `~/.mina-config/`. Only the latest report is retained, named with the crash date-time. A crash report may contain: | File | Description | |--|--| | `crash_summary.json` | System info, version, and final log output | | `mina_status.json` | Output of `mina client status` at time of crash | | `mina_short.log` | Last 4 MB of `mina.log` | | `registered_mask.dot` | Latest ledger visualization | | `frontier.dot` | Latest frontier visualization | | `daemon.json` | Daemon configuration file | You can upload crash reports and exported logs directly to a [GitHub issue](https://github.com/MinaProtocol/mina/issues) to help with debugging. --- url: /node-operators/validator-node/querying-data --- # Interacting with the Node via GraphQL API The Mina daemon exposes a [GraphQL API](/node-developers/graphql-api) that you can use to query recent blockchain data and submit signed transactions. ## Setup Once your node is [connected to the network](./connecting-to-the-network), the GraphQL server is available at `localhost:3085` by default. To use a different port: ```sh mina daemon ... -rest-server-port ``` To make the server accessible from outside `localhost`: ```sh mina daemon ... -insecure-rest-server ``` :::caution If you expose the GraphQL server externally, ensure your firewall is configured properly. See [GraphQL API](/node-developers/graphql-api) for details. ::: If you want to archive historical data beyond what the node keeps in memory, see [Archive Node](/node-operators/archive-node/getting-started). ## Querying data The examples below query _recent_ chain data -- approximately the last 290 blocks (~10 hours of activity). To explore all available fields, open the GraphQL sandbox at `http://localhost:3085/graphql` in your browser. ### Block data ```graphql query BlockData { bestChain(maxLength: 10) { stateHash creatorAccount { balance { total } } } } ``` ### Account balance Query the current balance of a public key. The response also includes the `blockHeight` and `stateHash` of the block the balance was read from. ```graphql query CurrentBalance { account(publicKey: "B62qmyjqEtUEZrsBpUaiz18DCkwh1ovCrJboiHbDhpvH8JEoaag5fUP") { balance { blockHeight total stateHash } } } ``` ### Staking information In Mina, an account is either staking directly or delegating its entire stake. Query the current delegation status: ```graphql query StakingInfo { account(publicKey: "B62qmyjqEtUEZrsBpUaiz18DCkwh1ovCrJboiHbDhpvH8JEoaag5fUP") { balance { blockHeight total stateHash } delegateAccount { publicKey } } } ``` If `delegateAccount.publicKey` is `null`, the account is staking directly. :::note The active staking ledger for the current epoch is drawn from the SNARKed ledger of the last block two epochs prior. In practice, staking ledger transitions happen every 2-4 weeks. ::: ### Transaction details Look up transactions within recent blocks on the best chain: ```graphql query TransactionDetails { bestChain(maxLength: 10) { stateHash creatorAccount { balance { total } } transactions { coinbase userCommands { amount fee feePayer { publicKey } hash isDelegation kind memo nonce receiver { publicKey } source { publicKey } } } } } ``` ## Submitting a signed transaction Send a pre-signed payment using the `sendPayment` mutation: ```graphql mutation SubmitSignedTransaction { __typename sendPayment(input: { fee: "3000000", amount: "42", to: "B62qrcFstkpqXww1EkSGrqMCwCNho86kuqBd4FrAAUsPxNKdiPzAUsy", from: "B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg", nonce: "0", memo: "This is a memo", validUntil: "50000" }, signature: { field: "26393275544831950408026742662950427846842308902199169146789849923161392179806", scalar: "28530962508461835801829592060779431956054746814505059654319465133050504973404" }) { payment { amount fee kind memo nonce source { publicKey } receiver { publicKey } isDelegation } } } ``` --- url: /node-operators/validator-node/requirements --- # Requirements ## Hardware Requirements Please note the following are the hardware requirements for each node type after the upgrade: | Node Type | Memory | CPU | Storage | Network | |--|--|--|--|--| | Block Producer | 32 GB RAM | 8 core processor with BMI2 and AVX CPU instruction set are required | 64 GB | 1 Mbps Internet Connection | | SNARK Coordinator | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | SNARK Worker | 32 GB RAM | 4 core/8 threads per worker with BMI2 and AVX CPU instruction set are required | 64 GB | 1 Mbps Internet Connection | | Archive Node | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | Rosetta API standalone Docker image | 32 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | | Mina Seed Node | 64 GB RAM | 8 core processor | 64 GB | 1 Mbps Internet Connection | ## Software Supported environments include macOS, Linux (Debian 10, 11 and Ubuntu 20.04 LTS), and any host machine with Docker. Only x86-64 CPU architecture is supported. ## Clock Synchronization Your server must run a clock synchronization protocol such as [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) to participate in consensus. Most Linux distributions include NTP by default. ## Recommended VM Instances o1Labs has tested running nodes on several cloud providers. We recommend the following instances for basic node operator needs. Custom requirements and different cost constraints might require a different instance type. - AWS [c5.2xlarge](https://www.ec2instances.info/?filter=c5.2xl®ion=us-west-2&cost_duration=daily&selected=c5.2xlarge) - GCP [c2-standard-8](https://cloud.google.com/compute/docs/machine-types) - Azure [Standard_F8s_v2](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes-compute#fsv2-series-1) - Digital Ocean [c-8-16gib](https://cloud.digitalocean.com/droplets/new?size=c-8-16gib) ## Networking **IP:** By default, the Mina daemon determines its public IP address automatically via HTTPS (443) and HTTP (80). If you are behind a NAT or firewall, set the `--external-ip` flag to specify your public IP address. **Port:** Nodes must expose a port to communicate with peers. The default is TCP port `8302`. You can change it with the `--external-port` flag. **Firewall and port forwarding:** Allow inbound traffic on the following ports through your external IP address: - TCP port `8302` (required for peer communication) - TCP port `3085` (optional, for the GraphQL API) If you are using UFW: ```sh sudo ufw enable sudo ufw allow 22 sudo ufw allow 8302 sudo ufw allow 3085 ``` --- url: /node-operators/validator-node/staking-and-snarking --- # Delegating MINA Delegating assigns your stake to a block producer who shares earned rewards minus a fee. You don't need to run a node yourself. See [Staking Rewards on Mina](https://minaprotocol.com/blog/staking-rewards-on-mina) for reward details. If you want to produce blocks directly, see the [Block Producers](/node-operators/block-producer-node) section. - Your delegation takes effect after a latency period of 2-4 weeks. - You can re-delegate or un-delegate at any time with no penalty. Changes take effect after 1-2 epochs. - Your **full balance** is always delegated -- there is no partial delegation. ## Delegate your stake First, unlock your account: ```sh mina account unlock --public-key $DELEGATOR_PUBLICKEY ``` Then delegate: ```sh mina client delegate-stake \ --receiver $DELEGATEE_PUBLICKEY \ --sender $DELEGATOR_PUBLICKEY \ --fee 0.1 ``` | Flag | Description | |--|--| | `--receiver` | Public key of the delegatee (block producer) | | `--sender` | Public key of the account you are delegating from | | `--fee` | Transaction fee paid to the network | A stake delegation is a transaction on-chain, which is why it requires a fee. See also: [Mina Foundation Delegation Program](/node-operators/delegation-program/foundation-delegation-program). --- url: /participate/bugs-and-feature-requests --- # Reporting Issues, Bugs, & Feature Requests ## How to report things on Mina If you notice a bug, issue, or missing feature, please follow the steps below: ### 1. Search existing issues Before making a report, first search through [existing issues](https://github.com/MinaProtocol/mina/issues) to see if something similar has been reported. ### 2. Found a bug? If your issue is a bug, related to the Mina website or you have feedback about user experience, you can report it on the [Mina Protocol repo on GitHub](https://github.com/MinaProtocol/mina/issues/new/choose). ### 3. Found a vulnerability? If your issue is a vulnerability that may be putting other people's funds at risk or is related to the protocol infrastructure, the first step is to report the issue on the [Mina Protocol repo on GitHub](https://github.com/MinaProtocol/mina/issues/new/choose). You can request an invitation in the [#security](https://discord.com/channels/484437221055922177/799979001585336331) channel on Mina Protocol Discord. ### 4. Found an urgent issue? If your issue is time-sensitive and needs immediate attention, please send more details and your contact information to security@o1labs.org. A member of the engineering team will reach out promptly. :::note Our community learns best when we learn together. Please avoid sending issues by using Discord DMs. Instead, try the options listed here. ::: ### Join the security discussion Thanks for your help in securing the network! To learn more and discuss Mina-related security topics, you can participate in the [#security](https://discord.com/channels/484437221055922177/799979001585336331) channel on Mina Protocol Discord. --- url: /participate/careers --- # Careers If you're looking for another way to get involved with Mina, consider exploring the following career opportunities at Mina Foundation and Mina ecosystem partners. ### Mina Foundation [Mina Foundation Careers Page](https://apply.workable.com/mina-foundation/) ### Mina Ecosystem Partners - o1Labs [Careers](https://boards.greenhouse.io/o1labs) - Incubators of the Mina Protocol - =nil; Foundation [Careers](https://nil.foundation/careers/) - Creators of the zkBridge bridge from Mina to Ethereum - Viable Systems [Careers](https://www.viablesystems.io/rust-jobs) - Tools to help improve the performance of the Mina nodes and overall network Are you a Mina ecosystem partner? Select "EDIT THIS PAGE" at the top of this page to submit a pull request to add your company blog. Thank you for helping grow the Mina ecosystem. --- url: /participate/github --- # GitHub Mina Protocol is an open source project. ### Code Repositories As a decentralized protocol, Mina is open-source and its codebase is publicly available on GitHub. We invite you to view and become a contributor: [Github logo  MinaProtocol/mina](https://github.com/MinaProtocol/mina)  [](https://github.com/MinaProtocol/mina) [Github logo  o1-labs/o1js](https://github.com/o1-labs/o1js)  [](https://github.com/o1-labs/o1js) [Github logo  o1-labs/zkapp-cli](https://github.com/o1-labs/zkapp-cli)  [](https://github.com/o1-labs/zkapp-cli) ### Mina Discussions If you have questions or want to participate in discussions about the source code, head over to Mina Discussions: [Github logo  Mina Discussions on Github](https://github.com/MinaProtocol/mina/discussions) We also provide guidance on [Reporting Issues, Bugs, & Feature Requests](bugs-and-feature-requests). --- url: /participate/office-hours --- # Office Hours Talk with someone while you get started or when you need help ## zkApps Developers Office Hours On every Tuesday 16.00-17.00 UCT and every Saturday 08.00-09.00 UCT, Mina Foundation and o1Labs cohost online office hours to help zkApp developers. You can join to ask your o1js / Mina related questions, share and get feedback on your zkApp ideas, meet new developers, find team members for your ongoing ZK projects, or just to have a chat! Instead of creating an official or formal environment, our goal with the office hours is to make the developer community inside the Mina ecosystem more familiar with each other, and give the developers a chance to chat with Mina Foundation, o1Labs members, and other experienced o1js developers. Come to ask any questions — beginner to advanced! Register for upcoming [zkApps Developer Office Hours](https://lu.ma/mina). :::tip For a quicker response, you can ask questions and search for similar previous questions in the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel or [#zkapps-questions](https://discord.com/channels/484437221055922177/1047214314349658172) forum on Mina Protocol Discord. ::: --- url: /using-mina/Protect-Your-MINA --- # General Security Practices Security is critical when managing cryptocurrency. These are basic guidelines to help keep your MINA safe — always do your own research and stay informed about the latest security best practices. ### Never Share Your Seed Phrase, Private Keys, or Passwords Your seed phrase (12-24 words), private keys and wallet passwords are the master key to your wallet. **Never share it with anyone** for any reason. It should be: - Written down on paper (not stored digitally) - Kept in a secure location (safe, lockbox, etc.) - Never typed on websites or shared in messages - Never photographed or screenshotted ### Avoid Common Scams The crypto space has many types of scams. Here are the most common scams: - **Discord or Telegram impersonators:** Scammers copy team names and photos to appear legitimate. Please note that no one from Mina will DM you first. Always check for verified badges, and when in doubt, confirm in public channels. - **Impersonator Websites:** Scammers create convincing fake sites to steal your info. Always double-check URLs and bookmark official ones. - **Malicious links or software:** Clicking unknown links or installing unverified software can compromise your wallet or device. Only download from official Mina sources and avoid connecting your wallet to unfamiliar sites. Join the **#scam-alerts channel** on [Mina Discord](https://discord.gg/minaprotocol) to see real-time alerts about active scams targeting the Mina community. ### Follow General Security Best Practices - **Use hardware wallets** for large amounts (Ledger) - **Enable 2FA** on exchange accounts - **Keep software updated** - wallet apps, browsers, operating systems - **Use strong, unique passwords** for each service - **Be skeptical** of urgent requests or pressure to act quickly - **Verify everything** - double-check addresses before sending transactions - **Start small** - test with small amounts when trying new services **Remember: Crypto transactions are irreversible.** Once you send MINA, you can't get it back. Always take your time and verify everything. --- url: /using-mina/how-to-delegate --- Learn how to delegate MINA and receive staking rewards. # How to Delegate Instead of running your own node, you can delegate your MINA tokens to a validator (also called a block producer) and may receive staking rewards in return. Delegation is simple, requires no technical expertise, and allows you to participate in securing the Mina network while potentially earning variable rewards, which have historically averaged around 7% annually depending on network conditions and validator performance. Rewards are provided by independent validators. No entity custodies, controls, or guarantees any staking returns. Past performance is not indicative of future results ### Understanding Staking vs Delegating **Delegating (recommended for most users):** You assign your MINA to a validator who runs the infrastructure. You earn rewards without needing to run a node yourself. This is what most MINA holders do. **Running a block producer (advanced):** You operate your own node 24/7 to produce blocks directly. This requires technical knowledge, reliable infrastructure, and constant monitoring. [**More info here.**](https://minaprotocol.com/node-operators) **This guide focuses on delegating**, which is simple and accessible to everyone. ### Why Delegate MINA? - **No minimum amount required** - Delegate any amount of MINA - **No lock-up period** - Your MINA stays in your wallet and remains accessible - **No slashing risk** - Tokens aren’t taken for validator downtime or misbehavior - **Earn rewards by helping secure the Mina network** - delegating your MINA supports decentralization and may yield variable staking returns (recently ~7% annually, depending on validator performance and network conditions). - **Support decentralization** - Help secure and decentralize the Mina network Even if you don't stake Mina, your wallet may still be called upon to produce a block. If you aren't delegating or staking, no block will be produced and no transactions get processed in that slot. By delegating or staking your MINA, you ensure it actively helps produce blocks and secure the network. ### Prerequisites Before delegating, ensure you have: 1. A Mina wallet installed (Auro, Clorio, or Ledger) 2. MINA tokens in your wallet 3. A small amount of MINA for transaction fees ### How Delegation Works When you delegate MINA to a validator: 1. Your tokens **never leave your wallet** - you maintain full control 2. The validator uses your stake weight to increase their chances of producing blocks 3. When the validator wins a block (720 MINA reward), they distribute rewards proportionally to all delegators 4. The validator takes a commission fee and you receive your share of the remaining rewards 5. It takes **2-4 weeks** for your delegation to become active on the network 6. You can change validators anytime with no penalties :::note Values like staking rewards, epoch duration, and APY are subject to change with network upgrades. After the upcoming Mesa upgrade, block rewards will decrease from 720 to 360 MINA per block, and epoch duration will reduce from 2-4 weeks to 1-2 weeks. ::: ### How to Delegate Mina Here’s how to delegate MINA within common wallets: - [**Auro**](https://www.aurowallet.com) - Open the wallet, tap “*Staking*”, tap “*Go to Staking*”, select a block producer, and confirm the transaction details.
Screenshot of Mina Explorer


- [**Clorio Wallet**](https://clor.io) - Open the wallet, tap “*Staking Hub*”, select and confirm your validator, and enter your transaction fee and passphrase or private key.
Screenshot of Mina Explorer


- [**Ledger Hardware Wallet**](https://www.ledger.com/mina-wallet) - Follow the [instructions on creating a Ledger Mina account via Auro Wallet](https://www.ledger.com/coin/wallet/mina-protocol#learn-more), then see the instructions for staking MINA on Auro wallet above. - [**Pallad**](https://get.pallad.co/website) - Open the wallet, tap upper-right Menu button. Select "*Staking*" from the sidebar menu. Click "*Stake*", paste validator public key or use "*Find a validator*". Tap "*Next*", enter your spending password and submit to confirm the transaction.
Screenshot of Mina Explorer


:::note Mention of third-party wallets or exchanges is for informational purposes only and does not constitute an endorsement or guarantee. Please review each provider’s terms and regional availability before use. ::: ### Choosing a Validator Most wallets display a list of available validators with their commission rates and statistics. You can also: - Browse validators on [MinaScan](https://minascan.io/mainnet/validators/terms) - Ask the community in [Mina Discord](https://discord.gg/minaprotocol) - Check Block Producer’s performance on this [Uptime Tracker](https://uptime.minaprotocol.com/) When selecting a validator to delegate to, consider these factors: - **Commission Rate:** Validators charge a fee from block rewards before distributing to delegators. Lower commission means you keep more of your rewards, but reliable validators need sustainable fees to maintain quality infrastructure. - **Block Production Rate & Performance:** Check the validator's uptime and block production history. - **Reputation & Transparency:** Choose validators who are active on X or Discord with transparent communication about their operations. - **Network Decentralization:** Supporting smaller, reliable validators helps decentralize the network and improve security for everyone. ### Choosing a Validator Your delegation will become active after **2-4 weeks** (1-2 epochs). Here are some extra things to note: - **Checking Your Status:** Most wallets show your current delegation status, including: - Which validator you're delegated to - When your delegation becomes active - Your earned rewards - **Receiving Rewards:** Rewards are automatically credited to your account every epoch assuming your validator successfully produces blocks.. You don't need to claim them manually - they simply appear in your wallet balance. - **Changing Validators:** You can change validators anytime by submitting a new delegation transaction. The change will take effect after 1-2 epochs. There are no penalties for switching. - **Undelegating:** To stop delegating, you can delegate to yourself (your own public key) or simply let your current delegation remain inactive. Your MINA is always accessible regardless of delegation status. - **Transaction Fees:** When sending transactions on a blockchain, such as Mina, senders must include a transaction fee. Most wallets calculate a recommended fee automatically. --- url: /using-mina/how-to-send-and-receive --- # How to Send & Receive Learn how to send and receive MINA ### Prerequisites First, ensure you have [installed a Mina wallet](../using-mina/install-a-wallet). ### Receiving MINA To receive MINA, you must provide the unique address for your Mina account to the sender. Here’s how to find your address within common wallets: - [**Auro**](https://www.aurowallet.com) - Open the wallet, tap “*Receive*”, and tap “*Copy*” to share your address or QR code representing this address.

Screenshot of Auro Wallet


- [**Clorio Wallet**](https://clor.io) - Open the wallet and tap Copy icon on Clor.io at the top to copy your address. - [**Ledger Hardware Wallet**](https://www.ledger.com/mina-wallet) - Follow the [instructions on creating a Ledger Mina account via Auro Wallet](https://support.ledger.com/hc/en-us/articles/5458493215901-Creating-a-Ledger-MINA-account-via-Auro-Wallet?docs=true), then see the instructions for receiving MINA on Auro wallet above. - [**Pallad**](https://get.pallad.co/website) - Open the wallet, tap "*Receive*", and tap "*Copy to clipboard*" to share your address. Wallet's QR code is displayed as well.

Screenshot of Pallad


:::note To prevent spam, the Mina network charges a one-time account creation fee of 1 MINA. This fee is automatically deducted from the first transaction received. ::: ### Sending MINA When sending MINA, always double check that you have the correct Mina address for the recipient. Remember that transactions on the Mina blockchain are final and irreversible. - [**Auro**](https://www.aurowallet.com) - Open the wallet, tap “*Send*”, enter in the address, amount, and fee, and tap “*Next*” then “*Confirm*”.

Screenshot of Auro Wallet


- [**Clorio Wallet**](https://clor.io) - Open the wallet, tap “*Send TX*”, and enter in the address, memo, amount, and fee, tap “*Preview*”, and enter in the nonce then tap “*Confirm*”. - [**Ledger Hardware Wallet**](https://www.ledger.com/mina-wallet) - Follow the [instructions on creating a Ledger Mina account via Auro Wallet](https://support.ledger.com/hc/en-us/articles/5458493215901-Creating-a-Ledger-MINA-account-via-Auro-Wallet?docs=true), then see the instructions for sending MINA on Auro wallet above. - [**Pallad**](https://get.pallad.co/website) - Open the wallet, tap "*Send*". Enter address and amount, and tap "*Next*". Enter your spending password and submit to confirm the transaction.

Screenshot of Pallad


:::note When sending transactions on a blockchain, such as Mina, senders must include a transaction fee. Most wallets calculate a recommended fee. You can also view a suggested fee amount based on current network transaction volume at this community-created [Gas Station website](https://fees.mina.tools/). ::: ### Viewing your transction on a blockchain explorer You can view your transactions using one of the community-run blockchain explorers: - [MinaScan](https://minascan.io/) - [Minataur](https://minataur.net/) - [MinaSearch](https://minasearch.com/) (in development by Granola)
Screenshot of Mina Explorer
--- url: /using-mina/how-to-use-zkapp --- :::info The maximum number of zkApp transactions per block is currently capped at 24. This restriction will be gradually lifted after the Mainnet upgrade. ::: # How to Use a zkApp Learn how to interact with a zero knowledge smart contract ### Prerequisites 1. Install a zkApp-compatible [Mina wallet](../using-mina/install-a-wallet). 2. Make sure that your Mina wallet contains MINA to pay for transaction fees. :::note The Mina community has created a variety of different wallets. Only the [Auro Wallet for Chrome](https://www.aurowallet.com) supports interactions with zkApps currently. ::: ### Instructions 1. Visit the zkApp in a web browser. For example, `mycoolzkapp.com`. 2. Interact with the zkApp as intended. For example, make a move in a game, enter in your age, and so on. 3. Click the confirmation button to send the transaction to the Mina network. 4. In your Mina browser wallet extension, confirm the transaction. 5. Done! Congratulations. Your transaction will be processed by the Mina network and, when accepted into a block, will update the zkApp's on-chain state. ### Check the zkApp transaction To confirm that your zkApp transaction has been successfully processed, view the clickable transaction hash shown by the wallet on a block explorer. --- url: /using-mina/install-a-wallet --- # Install a Wallet Learn about wallets you can use to send and receive MINA. The Mina community has created a variety of different wallets. You can send and receive MINA using any of these wallets, currently the Auro Wallet for Chrome and MinaPortal support interactions with zkApps. - [Auro Wallet (Chrome, Firefox, iOS, & Android)](https://www.aurowallet.com) - [Clorio Wallet (Windows, MacOS, Linux, and online)](https://clor.io) - [Ledger Mina Protocol wallet](https://www.ledger.com/mina-wallet) For instructions, see the [Ledger Hardware Wallet](../using-mina/ledger-hardware-wallet) doc. - [MinaPortal, a MetaMask Snap](https://minaportal.sotatek.works/) To learn more, see the [MinaPortal wiki](https://github.com/sotatek-dev/mina-snap/wiki) . - [Pallad (Chrome & Brave side panel)](https://get.pallad.co/website) :::note To prevent spam, the Mina network charges a one-time account creation fee of 1 MINA. This fee is automatically deducted from the first transaction received. ::: ### Wallet for Node Operators The Mina CLI also provides the ability to store, send, and receive MINA. However, this method is intended only for Mina node operators and we do **not** recommend this as a wallet for typical users. View the [Mina CLI docs](/node-operators/reference/mina-cli-reference) to learn more. ### Next Steps Now that you've learned how to set up a wallet, you can learn [how to send and receive MINA](../using-mina/how-to-send-and-receive). --- url: /using-mina/ledger-hardware-wallet --- # Ledger Hardware Wallet Ledger has added support for Mina to their Nano S and Nano X hardware wallets. Install the Mina application on your hardware device to store your funds and interact with the Mina blockchain. :::info Please note that it's not yet possible to sign zkApp transactions using a Ledger wallet. ::: The Mina app supports the following operations: - Generating key pairs - Signing payment transactions - Signing delegation transaction The Mina app does **not** support the following operations: - Signing zkApp transactions - Native LedgerLive wallet integrations (instead, you can use third-party wallets) You can download the Mina app to your Ledger Nano S or Nano X using the instructions below. ## Installing the Mina app Before you get started, download [Ledger Live](https://www.ledger.com/ledger-live/download) if you have not done so already: Make sure your Ledger firmware is on the latest version supporting Mina. 1. Connect and unlock your Ledger device. 2. Open the **Manager** in [Ledger Live](https://support.ledger.com/hc/en-us/articles/4404382258961?docs=true). 3. Allow the manager on your device. 4. Search for **Mina** in the app catalog. 5. Click the **Install** button. Your device displays **Processing...**. 6. After the download is completed, Ledger Live displays **Installed**.
![Example banner](/img/LedgerLive.png)
:::tip A few reminders regarding hardware wallets: - Make sure to backup your secret pneumonomic phrase - Keep your ledger up-to-date ::: ## Troubleshooting **Why does signing a transaction take so long?**
Since Mina uses new cryptography and Ledger does not have hardware acceleration support, you may experience that signing with the Mina app takes longer than other wallets. We hope that this cryptography is supported by Ledger in the future. **Why don't I see the option to update my firmware?**
If your Nano X firmware does not offer an option to upgrade to the latest version, it means your device is in the process of getting staged for the update. Just wait 1 or 2 days to see if the option is available. If not, reach out to Ledger support. ## Next Steps Congratulations! Now that you have installed Mina’s Ledger app, you can start using your Ledger and connect to one of Mina’s Ledger supported wallets: - [Aurowallet.com](https://www.aurowallet.com/) - [Clor.io](https://clor.io/) If you need help or have questions about Ledger, join the [#ledger-hardware](https://discord.com/channels/484437221055922177/733755408161833040) channel on Mina Protocol Discord. --- url: /welcome --- # Welcome --- url: /zkapps/advanced/experimental --- # Experimental features Some new features are considered experimental before they are production-ready. :::experimental Experimental features are clearly marked and link to this page. ::: Exposing experimental features gives you an opportunity to try our newest features sooner. In return, your feedback helps us make sure that our new features are reliable and useful. ## Feedback We appreciate any and all feedback you want to provide. The best place to provide feedback and ask questions is on [Mina Protocol Discord](https://bit.ly/MinaDiscord). To ask zkApps questions and engage with other developers building zkApps with o1js, use the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel. Experimental features are in active development and your feedback is especially appreciated. - The feature may have bugs - The feature may be changed, deprecated, or removed - All documentation for the feature explicitly states that the feature is experimental --- url: /zkapps/advanced/zkapps-for-ethereum-developers --- # zkApps for Ethereum Developers Mina and Ethereum are both decentralized, programmable, layer-one blockchains, but they are designed in fundamentally different ways. The Ethereum network verifies transaction execution by having every node execute every transaction. While this design solves a real problem, it also imposes some severe limitations on privacy and scalability. The Mina Protocol works differently. It verifies transactions (and previous blocks) cryptographically using recursive zero knowledge proofs. Smart contract code is written in TypeScript and executes off chain. Mina nodes need to verify only a small proof in order to validate the associated execution. Better still, the proof does not reveal any information about the underlying computation, meaning developers can choose whether their inputs and outputs should be public or private, depending on the requirements of their application. ## At a Glance
Ethereum Smart Contracts Mina zkApps
Language Smart contracts are written in Solidity. zkApp smart contracts are written using o1js (a TypeScript library).
Execution Environment Smart contracts run on every Ethereum node. zkApps run client side in a user’s web browser, and publish only a small validity proof which is verified by the Mina nodes.
Transaction Cost Execution costs are variable, and determined using a gas model. Execution costs are small, and constant because the Mina nodes are verifying the same size proof regardless of the amount of client-side computation.
Application Storage Ethereum is designed around the idea that storage, and computation are inherently coupled; all state must live on every Ethereum node. Mina’s design allows state, and computation to be decoupled so that application state can live anywhere; developers can choose a solution that fits their cost/security requirements best.
Developer Tooling New developer tools with unusual patterns like Hardhat, and Truffle are needed in order to manage the deployment of Ethereum smart contracts. The zkApp CLI manages scaffolding, linting, testing, and deployment using common JavaScript/TypeScript tools you are already familiar with.
Scaling Ethereum nodes must execute every transaction directly making horizontal scaling hard. Mina’s recursive zero knowledge proofs allow snark-workers to compress the blockchain, and developers to compress transactions using native rollups for exponential scaling.
Consensus Ethereum nodes must download the entire block history (~700GB) in order to verify the current finalized chain state. Mina clients can verify the current finalized state using a single 22KB recursive zero knowledge proof.
## Example Code ```ts export class Add extends SmartContract { /* The state decorator tells o1js to store/retrieve num from the Mina blockchain */ /* The Field type represents elements of a finite field (similar to uint256 for practical purposes, but loops back to 1 after overflowing) */ @state(Field) num = State(); // Initialize the contract (similar to a constructor in Solidity) init() { super.init(); // Set num equal to a Field element of value 1 on contract deployment this.num.set(Field(1)); } /* The method decorator tells o1js to be ready to generate a proof of execution any time this method is called */ @method async update() { // Get the state of num from the Mina blockchain and set it to currentState const currentState = this.num.get(); /* Calling add instead of using the JS infix addition operator enables o1js to prove that the addition is done correctly */ const newState = currentState.add(2); /* Set the state of num on the Mina blockchain equal to newState (this state update will not happen unless the transaction is accompanied by a valid proof of execution) */ this.num.set(newState); } } ``` ## How does Mina bridge to Ethereum? Mina proofs are small and easy to verify; this means that any Turing complete blockchain (like Ethereum) can validate the entire Mina state in a single transaction using a bridge contract. These are a bit different from existing bridging solutions because they don't require additional security assumptions. Think of them as full Mina nodes that are implemented in smart contracts on other chains. They validate the Mina state in exactly the same way a Mina block producer would and expose Mina directly to any other contract. The Nil Foundation is working on the [first of these bridges](https://verify.mina.nil.foundation/walkthrough/index.html) for Ethereum and other EVM-compatible networks. ### Have another question? Reach out in the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel on Mina Protocol Discord. It's better when we learn together. --- url: /zkapps/faq --- # zkApps and o1js FAQ Answers to common questions about zkApps (zero knowledge apps) and o1js, a TypeScript library for writing zk smart contracts. ### How do I stay up to date with zkApps and o1js? Follow the official o1Labs channels: - Twitter/X [@o1_labs](https://twitter.com/o1_labs) - o1Labs [Blog](https://www.o1labs.org/), especially the [What's New in o1js](https://www.o1labs.org/blog?topics=o1js) monthly updates ### Where can I ask questions and contribute answers? [Mina Protocol Discord](https://discord.gg/minaprotocol) is the most popular place where Mina enthusiasts and technical contributors gather. Join us in these zkApps channels: * [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) to meet other developers building zkApps with o1js * [#zkapps-general](https://discord.com/channels/484437221055922177/910549624413102100) to ask general questions about zkApps, how to use a zkApp, and so on * [#zkapps-questions](https://discord.com/channels/484437221055922177/1047214314349658172) to ask zkApps-related questions and see Q&A history ### What files do I use to write zkApps? There are many approaches to building a smart contract. For the zkApp tutorials, most examples follow this convention: - `index.ts`: The entry point of your project that imports all smart contract classes you want access to and exports them to your smart contract. - `main.ts`: How you interact with the smart contract. For example, the `import` statement brings in objects and methods from `o1js` that you use to interact with your smart contract. - `.ts`: Your specific smart contract logic. ### Where can I find the o1js API reference documentation? See the autogenerated [o1js reference](/zkapps/o1js-reference) documentation with doc comments, like the [Provable](/zkapps/o1js-reference/type-aliases/Provable) module. ### What is ZkProgram? A general-purpose API for creating zk proofs. A ZkProgram is similar to a zkApp smart contract but isn't tied to an on-chain account. ### What is the difference between `getActions` and `fetchActions`? Use the appropriate module to work with the live network or with historical archive nodes: - [getActions](/zkapps/o1js-reference/namespaces/Mina/functions/getActions) works with the blockchain network - [fetchActions](/zkapps/o1js-reference/namespaces/Mina/functions/fetchActions) works with archive nodes ### Does o1js compile my JavaScript code to an arithmetic circuit? No, o1js **does NOT compile into anything else**. In contrast to other zk ecosystems, o1js is just a JS library. It creates zk circuits from user code by _executing_ that code. If you have a smart contract with a `@method async myMethod()`, for example, o1js simply calls `myMethod();` during proof generation. This works because o1js sets up some global state - a "circuit" - where it collects variables and constraints. The use of functions like `Field.mul` or `Bool.assertEquals` inside your smart contract methods add corresponding variables and constraints to the global circuit. This has some implications: - To turn your logic into a proof, you must use o1js built-in datatypes such as `Field` and use the o1js functions that operate on them, like `Field.mul()`. - A statement like `x.mul(y)` adds a generic PLONK gate to your circuit and returns a variable that you can use in further statements that get wired to the multiplication gate. - Some o1js methods allow you to convert normal JavaScript datatypes into `Field` elements and back, such as `Encoding.stringToFields()`. Methods like this that don't add anything to your circuit are typically clarified in a doc comment. - Conventional JavaScript code such as `'hello world'.split('').join(' ')` that doesn't use o1js built-ins are not included in your zk proof since it doesn't add anything to your circuit. - Why? Because it doesn't call any of the functions that build the circuit. - There's nothing wrong with having non-circuit code inside your method, as long as you're aware of what it's (not) doing. - It's fine to use if-statements, for-loops, arrays, objects, and any other JavaScript language constructs to facilitate writing circuits. However, be aware that these flexible constructs don't allow you to overcome the static nature of circuits. This example asserts that a Field element `x` is not equal to `5`, `10` or `15`: ```ts // good for (let y of [5, 10, 15]) { x.equals(y).assertFalse(); } ``` The previous for-loop example just stitches together a fixed number of o1js commands, which is fine. However, the following snippet, where the loop's length is determined from user input, won't work: ```ts // bad @method async myMethod(x: Field, n: Field) { let n0 = Number(n.toString()); // nope for (let y = 0; y < n0; y += 5) { x.equals(y).assertFalse(); } } ``` This example fails for two reasons: 1. `n.toString()` can't be used in circuit code at all. It throws an error during `SmartContract.compile()` because during `compile()`, variables like `n` don't have any JS values attached to them; they represent abstract variables used to build up an abstract arithmetic circuit. So, in general, you can't use any of the methods that read out the JS value of your Field elements: `Field.toString()`, `Field.toBigInt()`, `Bool.toBoolean()` etc. 2. More subtly, your methods must create the same constraints every time because a proof cannot be verified against a verification key for a differing set of constraints. The code above adds `x.equals(y).assertFalse()` _on condition of_ the value of `n` which leads to constraints varying between executions of the proof. ### Why is the variable currentState set to a value retrieved from the blockchain and then immediately compared to that value? As represented in the tutorial example code: ```TypeScript const currentState = this.num.get(); this.num.requireEquals(currentState); ``` - The first line of code executes before the proof is generated. - The second line of code creates a precondition that is checked when the proof is sent in a transaction to the blockchain to be verified. This ensures that the transaction fails if the value of the field in question has changed. ### Can I pass hex values into Fields? Yes, just pass in the appropriate BigInt literal. `Field(0x1337)` ### Can I pass arguments to the SmartContract init method? The best practice is no. To test something with more than one initialization state, you can set the state by passing arguments to another user-defined method. ### Can I use TypeScript enums? You can try! We experimented with this, so it might generate unconstrained functionality. ### How can I use the Field type? Are there specific reasons I want to specify the `Field` type? All provable types are built using the type `Field`. For efficiency, use `Field` only when you do not need to take advantage of the properties of the other provable types in o1js. ### What does the @method decorator do? It allows the method to be invoked by a user interacting with the smart contract. You can check out the compiled JavaScript in `./build/src` to see exactly what's going on. ### How can you enforce that an account update must be signed by the account owner? Use the `requireSignature` command. See the [requireSignature](/zkapps/o1js-reference/classes/SmartContract#requiresignature) Method reference. ### How do I configure who has the authority to interact and make changes to a specific part of an account? Permissions determine who has the authority to interact and make changes to a specific part of a smart contract. See [Permissions](https://docs.minaprotocol.com/zkapps/writing-a-zkapp/feature-overview/permissions). ### How are proofs generated in the Mina Protocol? [Kimchi](https://minaprotocol.com/blog/kimchi-the-latest-update-to-minas-proof-system) is the main machinery that generates the recursive proofs that allow the Mina blockchain to remain of a fixed size of about 22 KB. See [Proof systems](https://o1-labs.github.io/proof-systems/). ### Are there proof generation scenarios when recursive proofs are not needed? Yes. It is possible to use the Kimchi proof system without the Pickles recursion layer. See [Pickles](https://o1-labs.github.io/proof-systems/specs/pickles.html?highlight=pickl#pickles) in the Mina book. ### Which curves are used by the Mina Protocol to generate proofs? Pasta curves (Pallas and Vesta). See [Pasta Curves](https://o1-labs.github.io/proof-systems/specs/pasta.html?highlight=curves#pasta-curves) in the Mina book. ### When do I use Provable conditional logic? Are there situations in which I would not want to use the Provable versions? If the conditional logic is not part of your provable code, you do not need to use Provable conditional statements. --- url: /zkapps/front-end-integration-guides/angular --- # Angular Integration Guide ## Install a Wallet - Install a wallet that supports zkApp transactions. For this tutorial, we’ll use **Auro Wallet** (v2.3.1). [Download it here](https://www.aurowallet.com/). - Add the Auro Wallet browser extension. - Open the extension and follow the steps to create a new wallet. - Click **"Mainnet"** at the top of the extension view, then select **"Show Testnet"** from the menu. After that, select **"Devnet"**. - Using Devnet will allow us to interact with a test version of the Mina network without needing to spend real Mina to pay for transaction fees.
Enable testnets on Auro

- Fund your wallet using the [Mina Faucet](https://faucet.minaprotocol.com/). - You'll need to wait one block (~3 minutes) to see the change in balance reflected on chain. You can use [Minascan](https://minascan.io/devnet) to track the status of your transaction.
Enable testnets on Auro

## Initialize the Project - Install the Angular CLI globally: ```bash npm install -g @angular/cli@19 ``` - Create a new Angular project by running: ```bash ng new ``` - Configure the project - For **Which stylesheet format would you like to use?**, select CSS. - For **Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? (y/N)**, choose **No**. - Install the `o1js` library: ```bash cd npm install o1js@2 ``` - Start the local development server. - This command runs `ng serve` which we will further configure by changing `options` under the `serve` build target in `angular.json`. ```bash npm run start ``` ## Create the ZkApp Contract - Navigate out of the demo project directory and install the `zkapp-cli` globally: ```bash cd ../ npm install -g zkapp-cli@0.22.3 ``` - Initialize a new zkapp with the CLI. When prompted to create a UI project, select **none**. ```bash zk project add ``` - Change into the newly created `add` directory and build the contract: ```bash cd add npm run build ``` - We've already deployed an instance of the default `Add` contract to Devnet at [B62qnTDEeYtBHBePA4yhCt4TCgDtA4L2CGvK7PirbJyX4pKH8bmtWe5](https://minascan.io/devnet/account/B62qnTDEeYtBHBePA4yhCt4TCgDtA4L2CGvK7PirbJyX4pKH8bmtWe5) so you won't need to deploy the contract you just created. You'll still need to include the contract code in your project so that it can be compiled into a verification key and proving key. - The proving key enables users to generate proofs of valid contract execution directly in their browsers. A user can run a contract call locally, create a proof of its execution using the proving key, and then publish the proof on-chain to update the zkApp’s state. Since the verification key is stored on-chain, the network will accept a transaction sent to this address if it includes a proof generated with the proving key that matches the on-chain verification key. ## Call Contracts - Move back into the Angular project. - To interact with the deployed `Add` contract, we’ll add code to fetch the current state and initiate a transaction. This code will execute only in the browser, so we'll add it to `afterNextRender` in the constructor of `src/app/app.component.ts`. - `afterNextRender` only runs after the Angular component has fully rendered. - The Auro wallet injects a Mina provider into the global context. It is accessible as `window.mina`. ```tsx @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { // replace with your project name! title = ''; constructor() { afterNextRender(async () => { const {Mina, PublicKey, fetchAccount} = await import('o1js'); const {Add} = await import('../../../add'); // connect the Mina instance to testnet Mina.setActiveInstance(Mina.Network('https://api.minascan.io/node/devnet/v1/graphql')); // we've already deployed the Add contract on testnet at this address // https://minascan.io/devnet/account/B62qnTDEeYtBHBePA4yhCt4TCgDtA4L2CGvK7PirbJyX4pKH8bmtWe5 const zkAppAddress = `B62qnTDEeYtBHBePA4yhCt4TCgDtA4L2CGvK7PirbJyX4pKH8bmtWe5`; await fetchAccount({publicKey: zkAppAddress}); const zkApp = new Add(PublicKey.fromBase58(zkAppAddress)); // Read state from the testnet Add contract console.log(`Reading state of add contract at ${zkAppAddress}: num=${zkApp.num.get()}`); try { // retrieve the injected mina provider if it exists const mina = (window as any).mina; const walletKey: string = (await mina.requestAccounts())[0]; console.log(`Injected mina provider address: ${walletKey}`); await fetchAccount({publicKey: PublicKey.fromBase58(walletKey)}); console.log("Compiling Add"); await Add.compile(); console.log("Compiled Add"); // send a transaction with the injected Mina provider const transaction = await Mina.transaction(async () => { await zkApp.update(); }); await transaction.prove(); const {hash} = await mina.sendTransaction({ transaction: transaction.toJSON(), }); // display the link to the transaction const transactionLink = `https://minascan.io/devnet/tx/${hash}`; console.log(`View transaction at ${transactionLink}`); } catch (e: any) { console.error(e.message); if (e.message.includes("Cannot read properties of undefined (reading 'requestAccounts')")) { console.error("Is Auro installed?"); } else if (e.message.includes("Please create or restore wallet first.")) { console.error("Have you created a wallet?"); } else if (e.message.includes("User rejected the request.")) { console.error("Did you grant the app permission to connect to your wallet?"); } else { console.error("An unknown error occurred:", e); } } }); } } ``` - The above code: - Connects Mina to a Devnet node so transactions are broadcasted to Devnet. - Requests the user's address from the mina provider injected into the browser context by the wallet. - Compiles the `Add` zkApp contract to generate and cache the proving key, which will allow the app to create proofs for transactions. - Creates a zkapp transaction calling `update` on the `Add` contract. - Proves the transaction using the proving key which o1js has internally cached. - Prompts the user to broadcast the transaction to the network with their wallet. - Now run the application in your browser with `npm run start` (which executes `ng serve`) and open the browser console. - Approve the connection request displayed in Auro. ## SharedArrayBuffer Headers for `ng serve` - You'll see that some of the code works, like the on-chain state retrieval, but compiling a zkapp fails with `DataCloneError: Failed to execute 'postMessage' on 'Worker': SharedArrayBuffer transfer requires self.crossOriginIsolated`. - `SharedArrayBuffer` is a JavaScript object that lets different threads share memory. Since o1js's proving is very computationally intensive, we us WASM workers for parallel processing in the browser. - For security reasons, `SharedArrayBuffer` needs certain headers to be set. These prevent cross origin resources (scripts and content loaded from external domains, iframes, and popups) from accessing shared memory. - Cross-Origin-Opener-Policy (COOP) must be set to `"same-origin"` to prevents cross-origin resources from accessing the main document’s memory. - Cross-Origin-Embedder-Policy (COEP) must be set to `"require-corp"` to restrict the way cross origin resources can be loaded by the main document. They'll either need to be from the same origin or include the `Cross-Origin-Resource-Policy: cross-origin` header. - Depending on how the application is being run, there are different ways to set these headers. Running the application locally with `ng serve` uses `@angular-devkit/build-angular:dev-server"` which we can configure in the project's `angular.json` file at `/projects//architect/serve/configurations/development`. - Architect is Angular's task runner, the entries (called build targets) under `architect` each represent tasks that the Angular CLI can run (`ng build`, `ng serve`, `ng test`, etc). The `builder` property of each target specifies the program that Architect should run to execute the task. The `options` can be used to supply parameters to the builder, and the `configurations`specifies a custom set of options for different target configurations (development, production, etc). - Running `ng serve` locally runs the `@angular-devkit/build-angular:dev-server` builder, and in its options object we can specify custom headers specifying the headers required for `SharedArrayBuffer` as follows: ```json "serve": { "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "headers": { + "Cross-Origin-Opener-Policy": "same-origin", + "Cross-Origin-Embedder-Policy": "require-corp" + } + }, "configurations": { "production": { "buildTarget": "angular-demo:build:production" }, "development": { "buildTarget": "angular-demo:build:development" } }, "defaultConfiguration": "development" }, ``` - Restart the server with `npm run start` and view the application in the browser again - the `SharedArrayBuffer` error should be gone! ## Loading o1js - We still have another error: `Uncaught ReferenceError: __async is not defined`. - This one comes from the way Angular bundles dependencies internally. We'll address it by supplying our own custom webpack config which will exclude o1js from the bundle generated by Angular. Then we'll copy o1js into our static assets directory so it's served with the app and use import maps to import o1js directly. ### Create a Custom Webpack Config - Start by creating a custom webpack config by adding a file `webpack.config.js` at the root of your project with the following contents: ```jsx module.exports = { externals: { 'o1js': 'o1js' } }; ``` ### Update Builders to Use Custom Webpack - Install builders which support using custom webpack configs - Angular's default builder will ignore the webpack file. ```bash npm install @angular-builders/custom-webpack@19 ``` - Update the `serve` and `build` build targets to use the `@angular-builders/custom-webpack` builders and load the file. - In `angular.json` under `/projects//architect/build`, replace the default builder `"builder": "@angular-devkit/build-angular:application",` with `"builder": "@angular-builders/custom-webpack:browser"`. - rename the `browser` property to `main` in `options`. - add `"customWebpackConfig": { "path": "./webpack.config.js" },` to `options`. - In `angular.json` under `/projects//architect/serve`, replace the default builder `"builder": "@angular-devkit/build-angular:dev-server",` with `"builder": "@angular-builders/custom-webpack:dev-server"`. - The changes to your build targets should look like this: ```json "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular-builders/custom-webpack:browser", "options": { + "customWebpackConfig": { "path": "./webpack.config.js" }, "outputPath": "dist/angular-demo", "index": "src/index.html", - "browser": "src/main.ts", + "main": "src/main.ts", "polyfills": [ "zone.js" ], "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": [ "src/styles.css" ], "scripts": [] }, "configurations": { ... }, "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular-builders/custom-webpack:dev-server", "options": { "headers": { "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp" } }, "configurations": { ... }, "defaultConfiguration": "development" }, ``` ### Copy o1js into Static Assets - Now we'll write a script to copy o1js into `public` where our static assets are served along with the application and then import it directly with an `importmap`. - Add a script to `package.json` that copies o1js from `node_modules` to a new directory at `public/lib/o1js`. - Files under public are served with the app, so the file itself will be available at `http://localhost:4200/lib/o1js/index.js`. ```json "copy-libs": "mkdir -p public/lib/o1js && cp node_modules/o1js/dist/web/index.js public/lib/o1js/index.js" ``` - Add the `copy-o1js-lib` task to the build script and the start script. ```json "build": "npm run copy-libs && ng build", "start": "npm run copy-libs && ng serve" ``` - Add `public/lib` to `.gitignore`. ### Load o1js with an `importmap` - Above the closing `` tag in `src/index.html` add these scripts to import o1js from `public/lib/o1js`: ```html ... ``` - Now instead of importing o1js as a regular npm dependency, we declare it as a top level variable in app component knowing that it will exist in the global context of the browser at runtime. Add the following to the top of `src/app.component.ts`: ```tsx // at the top of the file: declare var o1js: typeof o1jsTypes; ``` - Remove the import of o1js inside of `afterNextRender` and replace it with this: ```tsx - const {Mina, PublicKey, fetchAccount} = await import('o1js'); + const {Mina, PublicKey, fetchAccount} = o1js; ``` ## Running the App Locally - Congratulations! The app should work as expected when served with `npm run start` (`ng serve`). - Restart the application with `npm run start`. - Verify that `Set the global o1js instance: Module {…}` was logged in the console, indicating that o1js was successfully loaded from our public assets. - Verify that the current `num` on the `Add` zkapp is logged, meaning that we're successfully reading state from the contract at `B62qnTDEeYtBHBePA4yhCt4TCgDtA4L2CGvK7PirbJyX4pKH8bmtWe5` on Devnet. - Verify that "Compiled Add" is logged, meaning that the SDK has successfully generated a proving key for the `Add` zkapp. - If you're connected to Devnet and your account is funded with Devnet tokens, you should be be able to broadcast a successful transaction calling `update` on the zkapp. After a few minutes, the state change associated with the transaction will take effect on chain and you'll see `num` increase when you reload the page! ## Deploying to GitHub Pages - Now we'll set the app up for deployment to GitHub pages. - Publish your project to a GitHub repository with the same name. - Run `ng deploy` and select GitHub Pages. ```bash ng deploy ``` - Add `baseHref` to `options` under `build` in angular.json with the name of your GitHub repository. - **Do not remove the slashes!** ```json "baseHref": "//" ``` - Create a deploy script in package.json which copies the required libraries ```json "deploy": "npm run copy-libs && ng deploy --dir=dist/" ``` - Deploy the app. ```bash npm run deploy ``` - You can view deployment details at `https://github.com///actions` and your live site at `https://.github.io//`. ## SharedArrayBuffer in Deployed Instance - View the site and open the browser console. You'll see the same error about the SharedArrayBuffer from before! The headers set previously apply only to `ng serve`, so we’ll set them up for GitHub Pages. - Install `coi-serviceworker`. ```bash npm install coi-serviceworker@^0.1.7 ``` - Update the script that copies `o1js` to `public` to also include the `coi-serviceworker` file: ```json "copy-libs": "mkdir -p public/lib/o1js && cp node_modules/o1js/dist/web/index.js public/lib/o1js/index.js && cp node_modules/coi-serviceworker/coi-serviceworker.min.js public/coi-serviceworker.min.js" ``` - Import it in your `index.html` file right above the o1js importmap script. ```html ``` - Redeploy the application with the `COIServiceWorker` files. ```bash npm run deploy ``` ## Congratulations, you’ve developed and deployed a zkApp UI with Angular! Next steps include learning to use web workers to prevent computationally expensive operations like `compile` from blocking the UI thread, handling events, and building more complex zkApp contracts! --- url: /zkapps/front-end-integration-guides/next --- # Next JS Integration Guide ## Initialize the Project We will follow the project initialization workflow from the [NextJS docs](https://nextjs.org/docs/app/getting-started/installation). This tutorial uses version 15, but the same concepts should apply to all versions of Next. - Create a new project by running: ```bash npx create-next-app@15.1.4 ``` For this tutorial, I have selected the following options: ``` ✔ What is your project named? … next-js-integration-guide ✔ Would you like to use TypeScript? … Yes ✔ Would you like to use ESLint? … Yes ✔ Would you like to use Tailwind CSS? … Yes ✔ Would you like your code inside a `src/` directory? … Yes ✔ Would you like to use App Router? (recommended) … Yes ✔ Would you like to use Turbopack for `next dev`? … No ✔ Would you like to customize the import alias (`@/*` by default)? … No ``` - Install o1js For this tutorial, we are using o1js version 2. ```bash npm i o1js@^2 ``` - Make sure that everything is working by running the development server ```bash npm run dev ``` ## Configure the app for effective o1js usage This section will walk through the basics of configuring a Next.js app to work with o1js. The two main points are: - Set the COOP and COEP headers so that o1js can communicate with the shared array buffer used by WASM - This is strictly necessary for o1js to work in browers, whether or not you choose to use web workers - Set up some web worker infrastructure so that long-running o1js computation does not block rendering your site ### Update headers in next config To set the COOP and COEP headers correctly in next, edit your `next.config.ts` file to match the snippet below: ```ts const nextConfig: NextConfig = { async headers() { return [ { source: "/(.*)", headers: [ { key: "Cross-Origin-Opener-Policy", value: "same-origin", }, { key: "Cross-Origin-Embedder-Policy", value: "require-corp", }, ], }, ]; }, }; export default nextConfig; ``` #### (Alternative) Update Headers in Vercel Config If you plan to deploy to vercel only, then you can configure the headers in `vercel.json` instead of `next.config.ts`. Here is an example of how to do that: ```json { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }, { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" } ] } ] } ``` The Next JS config method will work on all deployment platforms, including Vercel. ### Use Comlink to create a worker We strongly recommend using web workers in your o1js-enabled apps. Comlink is a package which wraps web workers in a convenient API, and I will use it for this guide, but any way of using web workers that you're comfortable with will work. To use Comlink, first install it: ```bash npm i comlink ``` Then, create a worker, and a workerClient file. For this app, I will call the files `todoListWorker.ts` and `todoListWorkerClient.ts`. ```bash touch src/app/todoListWorker.ts src/app/todoListWorkerClient.ts ``` For now, let's put some boilerplate in these files: ```ts // todoListWorker.ts export const api = { async sayHi() { return "Hello from the worker!"; } }; Comlink.expose(api); ``` ```ts // todoListWorkerClient.ts export default class TodoListWorkerClient { worker!: Worker; remoteApi: Comlink.Remote; constructor() { const worker = new Worker(new URL("./todoListWorker.ts", import.meta.url), { type: "module", }); this.remoteApi = Comlink.wrap(worker); } async sayHi() { return await this.remoteApi.sayHi(); } } ``` ### Set any page that needs access to the web worker to 'use client' mode Only client-side rendered code will have access to web workers. Server-rendered components don't have access to browser features. In order to make use of web workers, tell next that your component should be client-rendered with `'use client'` on `page.tsx`. ```ts // page.tsx 'use client' // <---- Add this line to tell next to render this page client-side export default function Home() { return ( ``` Then, import the web worker and confirm that it is working: ```ts 'use client' export default function Home() { /** * Add this code to the top of the page confirm that the worker is functioning */ const workerClient = new TodoListWorkerClient(); workerClient.sayHi().then((message) => { console.log(message); }); return ( //... ``` Confirm that you see the message logged in your browser by opening the dev tools (F12) and looking for 'Hello from the worker!'. Now we have our web worker set up and we're ready to add logic to our app! ## Write the provable code that you want to execute in browser The rest of the guide will go through specifically how to write a todolist program with o1js and run it in the browser using the Next.js config that we just set up. The first step is writing a `ZkProgram`. `ZkProgram` is how proofs are created in o1js. Generating the proof is done in javascript, either in node, or in a browser, and verifying the proof can be done in javascript as well, or on a network like Mina, Protokit or Zeko. Let's get started by creating a new file called `zkTodoList.ts` and describing our program: ```bash mkdir -p src/lib && touch src/lib/zkTodoList.ts ``` ```ts // zkTodoList.ts export { IndexedMerkleMap8, ZkTodoList, ZkTodoListProof }; class IndexedMerkleMap8 extends Experimental.IndexedMerkleMap(8) {} const ZkTodoList = ZkProgram({ name: "TodoList", publicOutput: IndexedMerkleMap8, methods: {}, }); class ZkTodoListProof extends ZkProgram.Proof(ZkTodoList) {} ``` - `class IndexedMerkleMap8 extends Experimental.IndexedMerkleMap(8) {}` - This line creates the class we will use to store our todo list - IndexedMerkleMap(8) means a merkle map with 2^8 leaves that can be accessed by index - `publicOutput: IndexedMerkleMap8,` - This line defines the type of the output of the proof as our indexed merkle map class - So every proof of the contents of a todolist will export the merkle map that it is valid for Next let's add the data structure for a todo item. We want to track the text of the todo and the status, whether it's been completed or not. ```ts export { IndexedMerkleMap8, Todo, // <---- Add this line to export the Todo class ZkTodoList, ZkTodoListProof }; class IndexedMerkleMap8 extends Experimental.IndexedMerkleMap(8) {} // Add this class to represent a todo item as a provable struct class Todo extends Struct({ text: CircuitString, status: Bool, }) { hash() { return Poseidon.hash([this.text.hash(), this.status.toField()]); } } const ZkTodoList = ZkProgram({ ``` Finally, let's add methods to our program to handle initializing, adding a todo, and completing a todo. ```ts const ZkTodoList = ZkProgram({ name: "TodoList", publicOutput: IndexedMerkleMap8, methods: { /** * init creates a proof of an empty merkle map, representing an empty todo list */ init: { privateInputs: [], method: async () => { const publicOutput = new IndexedMerkleMap8(); return { publicOutput }; }, }, /** * addTodo inserts a new todo into the merkle map at the given index */ addTodo: { privateInputs: [SelfProof, Field, Todo], method: async ( p: SelfProof, index: Field, todo: Todo ) => { p.verify(); const publicOutput = p.publicOutput.clone(); publicOutput.insert(index, todo.hash()); return { publicOutput }; }, }, /** * completeTodo marks a todo at a given index as completed */ completeTodo: { privateInputs: [SelfProof, Field, Todo], method: async ( p: SelfProof, index: Field, todo: Todo ) => { p.verify(); const publicOutput = p.publicOutput.clone(); publicOutput.get(index).assertEquals(todo.hash()); todo.status = Bool(true); publicOutput.update(index, todo.hash()); return { publicOutput }; }, }, }, }); ``` That should do it for our ZkProgram! Let's get back to the web application and integrate this new feature. ## Wrap ZkProgram functionality in the web worker Back in our web worker, we will now want to expose the funcitonality of the todo list program to the Next.js application. Since we already set the worker up properly, this part is very straightforward. We simply need to import the zk program and write new methods for the worker that correspond to the features. We will also track some state in the web worker for convenience. ```ts // todoListWorker.ts IndexedMerkleMap8, Todo, ZkTodoList, ZkTodoListProof, } from "../lib/zkTodoList"; export type TodoObjectRepr = { text: string; status: boolean; }; const state = { merkleMap: null as IndexedMerkleMap8 | null, objectRepr: {} as Record, proof: null as ZkTodoListProof | null, index: 0, }; export const api = { async init() { console.time("Compiling zkTodoList"); await ZkTodoList.compile(); console.timeEnd("Compiling zkTodoList"); const initialProof = await ZkTodoList.init(); state.proof = initialProof.proof; state.merkleMap = initialProof.proof.publicOutput; }, async addTodos(todos: Array) { if (!state.proof) { throw new Error("Proof not initialized"); } let i = 0; while (todos.length > 0) { const text = todos.shift()!; console.log("Adding todo", i, text); const todo = new Todo({ text: CircuitString.fromString(text), status: Bool(false), }); const index = Field(state.index + 1); const proof = await ZkTodoList.addTodo(state.proof, index, todo); state.merkleMap = proof.proof.publicOutput; state.index++; i++; state.objectRepr[state.index] = { text, status: false }; state.proof = proof.proof; } }, async completeTodo(index: number) { if (!state.proof || !state.merkleMap) { throw new Error("Proof not initialized"); } try { const todoHash = state.merkleMap.get(Field(index)); console.log("Completing todo", index, todoHash); } catch (e) { throw new Error("Todo not found"); } const todoRepr = state.objectRepr[index]; if (!todoRepr) { throw new Error("Todo not found"); } if (todoRepr.status) { throw new Error("Todo already completed"); } const todo = new Todo({ text: CircuitString.fromString(todoRepr.text), status: Bool(todoRepr.status), }); const text = todo.text.toString(); const proof = await ZkTodoList.completeTodo( state.proof, Field(index), new Todo({ text: CircuitString.fromString(text), status: Bool(false), }) ); todoRepr.status = true; state.merkleMap = proof.proof.publicOutput; state.objectRepr[index] = todoRepr; state.proof = proof.proof; }, async completeTodos(indices: Array) { for (const index of indices) { console.log("Completing todo", index); await this.completeTodo(index); } }, getTodo(index: number) { return state.objectRepr[index]; }, getTodos() { return state.objectRepr; }, }; Comlink.expose(api); ``` And add the relevant wrappers to the worker client. ```ts // todoListWorkerClient.ts export default class TodoListWorkerClient { worker!: Worker; remoteApi: Comlink.Remote; constructor() { const worker = new Worker(new URL("./todoListWorker.ts", import.meta.url), { type: "module", }); this.remoteApi = Comlink.wrap(worker); } async init() { await this.remoteApi.init(); } async addTodos(todos: Array) { await this.remoteApi.addTodos(todos); } async completeTodos(indices: Array) { await this.remoteApi.completeTodos(indices); } async getTodo(index: number) { return await this.remoteApi.getTodo(index); } async getTodos() { return await this.remoteApi.getTodos(); } } ``` ## Applying the UI For the final step, let's create a couple simple components to round out our application. Let's create some files. These components will render our pending and proven todo items. The pending items are stored in react state until we add them to the proven data by calling the web worker client. This improves performance by not having to wait for the proof to be generated every time an action is taken. ```bash mkdir -p src/components touch src/components/PendingTodoItem.tsx src/components/PendingTodosQueue.tsx src/components/ProvenTodoItem.tsx src/components/ProvenTodosQueue.tsx ``` ```tsx // PendingTodoItem.tsx export default function PendingTodoItem({ todo }: { todo: string }) { return (
  • {todo}

  • ); } ``` ```tsx // PendingTodosQueue.tsx export default function TodosQueue({ title, subheading, todos }: { title: string, subheading: string, todos: Array }) { return (

    {title}

    {subheading}

  • Todo

    • {todos.map((todo, index) => ( ))}
    ); } ``` ```tsx // ProvenTodoItem.tsx export default function ProvenTodoItem({ todo, index, completeTodo }: { todo: TodoObjectRepr, index: number, completeTodo: (index: number) => void }) { return (
  • {todo.text}

    {todo.status ? "✅" : "❌"}

    {index}

    {todo.status ? (

    Already complete!

    ) : ()}
  • ); } ``` ```tsx // ProvenTodosQueue.tsx export default function ProvenTodosQueue({ title, subheading, todos, completeTodo }: { title: string, subheading: string, todos: Record, completeTodo: (index: number) => void }) { return (

    {title}

    {subheading}

  • Todo

    Status

    Index

    Actions

    • {Object.entries(todos).map(([index, todo]) => { console.log(index, todo); return ( ); })}
    ); } ``` Now that these files are created, let's use them in our main `page.tsx`. ```tsx // page.tsx "use client"; export default function Home() { const [todoListWorkerClient, setTodoListWorkerClient] = useState(null); const [hasBeenInitialized, setHasBeenInitialized] = useState(false); const [workerIsBusy, setWorkerIsBusy] = useState(false); const [todoList, setTodoList] = useState | null>(null); const [newTodo, setNewTodo] = useState(""); const [newTodosQueue, setNewTodosQueue] = useState([]); const [pendingCompleteTodosQueue, setPendingCompleteTodosQueue] = useState([]); const [logMessages, setLogMessages] = useState([]); const logContainerRef = useRef(null); const isInitializingRef = useRef(false); const initializeWorker = async (worker: TodoListWorkerClient) => { setLogMessages((prev) => [...prev, "Compiling zk program..."]); const timeStart = Date.now(); await worker.init(); const todos = await worker.getTodos(); setLogMessages((prev) => [...prev, `Zk program compiled in ${Date.now() - timeStart}ms`]); setTodoList(todos); setHasBeenInitialized(true); isInitializingRef.current = false; }; const setup = async () => { setWorkerIsBusy(true); if (!todoListWorkerClient) { setLogMessages((prev) => [...prev, "No worker client found, creating new one..."]); const workerClient = new TodoListWorkerClient(); setTodoListWorkerClient(workerClient); setLogMessages((prev) => [...prev, "Worker client created"]); isInitializingRef.current = true; await initializeWorker(workerClient); } else if (!hasBeenInitialized && !isInitializingRef.current) { isInitializingRef.current = true; await initializeWorker(todoListWorkerClient); } setWorkerIsBusy(false); }; useEffect(() => { setup(); }, [hasBeenInitialized, todoListWorkerClient]); useEffect(() => { if (logContainerRef.current) { logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight; } }, [logMessages]); const addTodo = async () => { setNewTodosQueue([...newTodosQueue, newTodo]); setLogMessages((prev) => [...prev, `Added todo to pending queue: ${newTodo.substring(0, 10)}...`]); setNewTodo(""); }; const resolveTodosQueue = async () => { setLogMessages((prev) => [...prev, "Proving pending todos queue..."]); setWorkerIsBusy(true); const timeStart = Date.now(); await todoListWorkerClient!.addTodos(newTodosQueue); const todos = await todoListWorkerClient!.getTodos(); setTodoList(todos); setWorkerIsBusy(false); setLogMessages((prev) => [...prev, `Todos queue proven in ${Date.now() - timeStart}ms!`]); setNewTodosQueue([]); }; const completeTodo = async (index: number) => { if(!todoList) return; setLogMessages((prev) => [...prev, `Marking todo ${index} for completion...`]); setPendingCompleteTodosQueue([...pendingCompleteTodosQueue, index]); }; const resolveCompleteTodosQueue = async () => { setLogMessages((prev) => [...prev, "Proving pending complete todos queue..."]); setWorkerIsBusy(true); const timeStart = Date.now(); await todoListWorkerClient!.completeTodos(pendingCompleteTodosQueue); const todos = await todoListWorkerClient!.getTodos(); setTodoList(todos); setWorkerIsBusy(false); setLogMessages((prev) => [...prev, `Complete todos queue proven in ${Date.now() - timeStart}ms!`]); setPendingCompleteTodosQueue([]); }; return (

    Todo List with o1js and Next JS!

    This is a demo site built with o1js and Next JS. Follow along with step by step instructions for how to build this site{" "} here!

    Console Log

      {logMessages.map((message, index) => (
    • {message}
    • ))}
    setNewTodo(e.target.value)} />
    todoList![index].text)} />
    {hasBeenInitialized ? ( todoList !== null && (
    ) ) : (
    Waiting for zk circuit to compile...
    )}
    ); } ``` ## Deployment Now that we have a complete app, here are the steps to deploy. We will cover deployment to Vercel. Deploying a Next JS app to Vercel is quite easy! You will need a github repository with the code. If you've been following along with this guide, you can use the repo that you've already built, or you can fork the reference implementation [on Github](https://github.com/o1-labs-XT/next-js-integration-example). You can follow the instructions about linking your repo to Vercel and deploying it [here](https://nextjs.org/learn-pages-router/basics/deploying-nextjs-app/deploy). In the Vercel UI, you simply import your Github repo, and it will deploy automatically. ### Troubleshooting #### Build Failure Make sure that running `npm run build` locally works before deploying. If it doesn't, fix the error locally, then push your changes to git, and they will be automatically redeployed. --- url: /zkapps/o1js-reference/README --- # o1js   [![npm version](https://img.shields.io/npm/v/o1js.svg?style=flat)](https://www.npmjs.com/package/o1js) [![npm](https://img.shields.io/npm/dm/o1js)](https://www.npmjs.com/package/o1js) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/o1-labs/o1js/blob/main/CONTRIBUTING.md) ℹ️ **o1js** is an evolution of [SnarkyJS](https://www.npmjs.com/package/snarkyjs) which saw 49 updated versions over two years of development with 43,141 downloads. This name change to o1js reflects the evolution of our vision for the premiere toolkit used by developers to build zero knowledge-enabled applications, while paying homage to our technology's recursive proof generation capabilities. Your favorite functionality stays the same and transitioning to o1js is a quick and easy process: - To update zkApp-cli, run the following command: `npm i -g zkapp-cli@latest` - To remove the now-deprecated SnarkyJS package and install o1js, run the following command: `npm remove snarkyjs && npm install o1js` - For existing zkApps, make sure to update your imports from `snarkyjs` to `o1js` - No need to redeploy, you are good to go! ## o1js o1js helps developers build apps powered by zero knowledge (zk) cryptography. The easiest way to write zk programs is using o1js. o1js is a TypeScript library for [zk-SNARKs](https://minaprotocol.com/blog/what-are-zk-snarks) and zkApps. You can use o1js to write zk smart contracts based on zero-knowledge proofs for the Mina Protocol. o1js is automatically included when you create a project using the [zkApp CLI](https://www.npmjs.com/package/zkapp-cli). ## Learn More - To learn more about developing zkApps, see the [zkApp Developers](https://docs.minaprotocol.com/zkapps) docs. - For guided steps building and using zkApps, see the [zkApp Developers Tutorials](https://docs.minaprotocol.com/zkapps/tutorials/hello-world). - To meet other developers building zkApps with o1js, participate in the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel on Mina Protocol Discord. - For a list of changes between versions, see the [CHANGELOG](https://github.com/o1-labs/o1js/blob/main/CHANGELOG.md). - To stay up to date with o1js, see the [O(1) Labs Blog](https://www.o1labs.org/blog?topics=o1js). ## Contributing o1js is an open source project. We appreciate all community contributions to o1js! See the [Contributing guidelines](https://github.com/o1-labs/o1js/blob/main/CONTRIBUTING.md) for ways you can contribute. ## Development Workflow For guidance on building o1js from source and understanding the development workflow, see [o1js README-dev](https://github.com/o1-labs/o1js/blob/main/README-dev.md). ## Community Packages High-quality community packages from open source developers are available for your project. - **o1js-elgamal** A partially homomorphic encryption library for o1js based on Elgamal encryption: [GitHub](https://github.com/Trivo25/o1js-elgamal) and [npm](https://www.npmjs.com/package/o1js-elgamal) - **o1js-pack** A library for o1js that allows a zkApp developer to pack extra data into a single Field. [GitHub](https://github.com/45930/o1js-pack) and [npm](https://www.npmjs.com/package/o1js-pack) - **zk-regex-o1js** A CLI tool for compiling ZK Regex circuits in o1js. [Github](https://github.com/Shigoto-dev19/zk-regex-o1js) and [npm](https://www.npmjs.com/package/zk-regex-o1js) To include your package, see [Creating high-quality community packages](https://github.com/o1-labs/o1js/blob/main/CONTRIBUTING.md#creating-high-quality-community-packages). | Member | Description | | :------ | :------ | | [Crypto](namespaces/Crypto/README.mdx) | - | | [Encryption](namespaces/Encryption/README.mdx) | - | | [Experimental](namespaces/Experimental/README.mdx) | This module exposes APIs that are unstable, in the sense that the API surface is expected to change. | | [Lightnet](namespaces/Lightnet/README.mdx) | - | | [Mina](namespaces/Mina/README.mdx) | - | | [AccountUpdate](classes/AccountUpdate.mdx) | An [AccountUpdate](classes/AccountUpdate.mdx) is a set of instructions for the Mina network. | | [AccountUpdateForest](classes/AccountUpdateForest.mdx) | Class which represents a forest (list of trees) of account updates, | | [AccountUpdateTree](classes/AccountUpdateTree.mdx) | Class which represents a tree of account updates, | | [AlmostForeignField](classes/AlmostForeignField.mdx) | - | | [BaseMerkleWitness](classes/BaseMerkleWitness.mdx) | The [BaseMerkleWitness](classes/BaseMerkleWitness.mdx) class defines a circuit-compatible base class for [Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof). | | [Bool](classes/Bool.mdx) | A boolean value. You can use it like this: | | [CanonicalForeignField](classes/CanonicalForeignField.mdx) | - | | [Character](classes/Character.mdx) | - | | [Circuit](classes/Circuit.mdx) | - | | [CircuitString](classes/CircuitString.mdx) | - | | [DynamicProof](classes/DynamicProof.mdx) | The `DynamicProof` class enables circuits to verify proofs using in-ciruit verfication keys. | | [EcdsaSignature](classes/EcdsaSignature.mdx) | - | | [Field](classes/Field.mdx) | A [Field](classes/Field.mdx) is an element of a prime order [finite field](https://en.wikipedia.org/wiki/Finite_field). | | [ForeignCurve](classes/ForeignCurve.mdx) | - | | [ForeignField](classes/ForeignField.mdx) | - | | [Group](classes/Group.mdx) | An element of a Group. | | [Hashed](classes/Hashed.mdx) | `Hashed` represents a type `T` by its hash. | | [Int64](classes/Int64.mdx) | A 64 bit signed integer with values ranging from -18,446,744,073,709,551,615 to 18,446,744,073,709,551,615. | | [Keypair](classes/Keypair.mdx) | - | | [Ledger](classes/Ledger.mdx) | Represents the Mina ledger. | | [MerkleList](classes/MerkleList.mdx) | Dynamic-length list which is represented as a single hash | | [MerkleListIterator](classes/MerkleListIterator.mdx) | MerkleListIterator helps iterating through a Merkle list. | | [MerkleMap](classes/MerkleMap.mdx) | - | | [MerkleMapWitness](classes/MerkleMapWitness.mdx) | - | | [MerkleTree](classes/MerkleTree.mdx) | A [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) is a binary tree in which every leaf is the cryptography hash of a piece of data, | | [Nullifier](classes/Nullifier.mdx) | Nullifiers are used as a public commitment to a specific anonymous account, | | [Packed](classes/Packed.mdx) | `Packed` is a "packed" representation of any type `T`. | | [PrivateKey](classes/PrivateKey.mdx) | A signing key. You can generate one via [PrivateKey.random](classes/PrivateKey.mdx#random). | | [Proof](classes/Proof.mdx) | - | | [ProofBase](classes/ProofBase.mdx) | - | | [PublicKey](classes/PublicKey.mdx) | A public key, which is also an address on the Mina network. | | [Scalar](classes/Scalar.mdx) | Represents a [Scalar](classes/Scalar.mdx). | | [ScalarField](classes/ScalarField.mdx) | ForeignField representing the scalar field of Pallas and the base field of Vesta | | [SelfProof](classes/SelfProof.mdx) | - | | [Sign](classes/Sign.mdx) | - | | [Signature](classes/Signature.mdx) | A Schnorr [Signature](classes/Signature.mdx) over the Pasta Curves. | | [SmartContract](classes/SmartContract.mdx) | The main zkapp class. To write a zkapp, extend this class as such: | | [TokenAccountUpdateIterator](classes/TokenAccountUpdateIterator.mdx) | Data structure to represent a forest of account updates that is being iterated over, | | [TokenContract](classes/TokenContract.mdx) | Base token contract which | | [TokenSymbol](classes/TokenSymbol.mdx) | - | | [UInt32](classes/UInt32.mdx) | A 32 bit unsigned integer with values ranging from 0 to 4,294,967,295. | | [UInt64](classes/UInt64.mdx) | A 64 bit unsigned integer with values ranging from 0 to 18,446,744,073,709,551,615. | | [UInt8](classes/UInt8.mdx) | A 8 bit unsigned integer with values ranging from 0 to 255. | | [Unconstrained](classes/Unconstrained.mdx) | Container which holds an unconstrained value. This can be used to pass values | | [VerificationKey](classes/VerificationKey.mdx) | - | | [Permissions](interfaces/Permissions.mdx) | Permissions specify how specific aspects of the zkapp account are allowed | | [Account](type-aliases/Account.mdx) | - | | [Bool](type-aliases/Bool.mdx) | - | | [BoolVar](type-aliases/BoolVar.mdx) | - | | [Bytes](type-aliases/Bytes.mdx) | - | | [Cache](type-aliases/Cache.mdx) | Interface for storing and retrieving values, for caching. | | [CacheHeader](type-aliases/CacheHeader.mdx) | A header that is passed to the caching layer, to support rich caching strategies. | | [ConstantField](type-aliases/ConstantField.mdx) | - | | [DeployArgs](type-aliases/DeployArgs.mdx) | - | | [Empty](type-aliases/Empty.mdx) | - | | [FeatureFlags](type-aliases/FeatureFlags.mdx) | - | | [Field](type-aliases/Field.mdx) | - | | [FlexibleProvable](type-aliases/FlexibleProvable.mdx) | - | | [FlexibleProvablePure](type-aliases/FlexibleProvablePure.mdx) | - | | [Group](type-aliases/Group.mdx) | - | | [InferProvable](type-aliases/InferProvable.mdx) | - | | [JsonProof](type-aliases/JsonProof.mdx) | - | | [MerkleListBase](type-aliases/MerkleListBase.mdx) | Common base type for [MerkleList](classes/MerkleList.mdx) and [MerkleListIterator](classes/MerkleListIterator.mdx) | | [MerkleListIteratorBase](type-aliases/MerkleListIteratorBase.mdx) | - | | [Option](type-aliases/Option.mdx) | - | | [Provable](type-aliases/Provable.mdx) | `Provable` is the general interface for provable types in o1js. | | [ProvableExtended](type-aliases/ProvableExtended.mdx) | - | | [ProvableHashable](type-aliases/ProvableHashable.mdx) | - | | [ProvableHashable](type-aliases/ProvableHashable-1.mdx) | - | | [ProvablePure](type-aliases/ProvablePure.mdx) | `ProvablePure` is a special kind of [Provable](type-aliases/Provable.mdx) interface, where the "auxiliary" (non-provable) data is empty. | | [ProvableType](type-aliases/ProvableType.mdx) | - | | [ProvableTypePure](type-aliases/ProvableTypePure.mdx) | - | | [ProvableWithEmpty](type-aliases/ProvableWithEmpty.mdx) | - | | [Reducer](type-aliases/Reducer.mdx) | - | | [ScalarConst](type-aliases/ScalarConst.mdx) | - | | [State](type-aliases/State.mdx) | Gettable and settable state that can be checked for equality. | | [Struct](type-aliases/Struct.mdx) | - | | [ToProvable](type-aliases/ToProvable.mdx) | - | | [TransactionPromise](type-aliases/TransactionPromise.mdx) | A `Promise` with some additional methods for making chained method calls | | [TransactionStatus](type-aliases/TransactionStatus.mdx) | INCLUDED: A transaction that is on the longest chain | | [TupleN](type-aliases/TupleN.mdx) | tuple type that has the length as generic parameter | | [Undefined](type-aliases/Undefined.mdx) | - | | [VarField](type-aliases/VarField.mdx) | - | | [Void](type-aliases/Void.mdx) | - | | [WithHash](type-aliases/WithHash.mdx) | - | | [WithProvable](type-aliases/WithProvable.mdx) | - | | [Witness](type-aliases/Witness.mdx) | - | | [ZkProgram](type-aliases/ZkProgram.mdx) | - | | [ZkappPublicInput](type-aliases/ZkappPublicInput.mdx) | The public input for zkApps consists of certain hashes of the proving | | [Account](variables/Account.mdx) | - | | [Bool](variables/Bool.mdx) | A boolean value. You can create it like this: | | [Cache](variables/Cache.mdx) | - | | [Crypto](variables/Crypto.mdx) | - | | [Empty](variables/Empty.mdx) | - | | [FeatureFlags](variables/FeatureFlags.mdx) | Feature flags indicate what custom gates are used in a proof of circuit. | | [Field](variables/Field.mdx) | A [Field](variables/Field.mdx) is an element of a prime order [finite field](https://en.wikipedia.org/wiki/Finite_field). | | [Gadgets](variables/Gadgets.mdx) | - | | [Group](variables/Group.mdx) | An element of a Group. | | [Hash](variables/Hash.mdx) | A collection of hash functions which can be used in provable code. | | [Keccak](variables/Keccak.mdx) | - | | [Permissions](variables/Permissions.mdx) | - | | [Poseidon](variables/Poseidon.mdx) | - | | [ProvableType](variables/ProvableType.mdx) | - | | [TokenId](variables/TokenId.mdx) | - | | [TransactionVersion](variables/TransactionVersion.mdx) | - | | [TupleN](variables/TupleN.mdx) | - | | [Undefined](variables/Undefined.mdx) | - | | [Void](variables/Void.mdx) | - | | [ZkappPublicInput](variables/ZkappPublicInput.mdx) | - | | [emptyHash](variables/emptyHash.mdx) | - | | [Bytes](functions/Bytes.mdx) | A provable type representing an array of bytes. | | [ConstantField](functions/ConstantField.mdx) | - | | [MerkleListBase](functions/MerkleListBase.mdx) | - | | [MerkleWitness](functions/MerkleWitness.mdx) | Returns a circuit-compatible Witness for a specific Tree height. | | [Option](functions/Option.mdx) | Define an optional version of a provable type. | | [Reducer](functions/Reducer.mdx) | - | | [State](functions/State.mdx) | - | | [Struct](functions/Struct.mdx) | `Struct` lets you declare composite types for use in o1js circuits. | | [VarField](functions/VarField.mdx) | - | | [WithHash](functions/WithHash.mdx) | - | | [ZkProgram](functions/ZkProgram.mdx) | - | | [addCachedAccount](functions/addCachedAccount.mdx) | Adds an account to the local cache, indexed by a GraphQL endpoint. | | [assert](functions/assert.mdx) | Assert that a statement is true. If the statement is false, throws an error with the given message. | | [checkBitLength](functions/checkBitLength.mdx) | - | | [checkZkappTransaction](functions/checkZkappTransaction.mdx) | - | | [circuitMain](functions/circuitMain.mdx) | - | | [conditionalSwap](functions/conditionalSwap.mdx) | - | | [createEcdsa](functions/createEcdsa.mdx) | Create a class [EcdsaSignature](classes/EcdsaSignature.mdx) for verifying ECDSA signatures on the given curve. | | [createForeignCurve](functions/createForeignCurve.mdx) | Create a class representing an elliptic curve group, which is different from the native [Group](classes/Group.mdx). | | [createForeignField](functions/createForeignField.mdx) | Create a class representing a prime order finite field, which is different from the native [Field](classes/Field.mdx). | | [declareMethods](functions/declareMethods.mdx) | `declareMethods` can be used in place of the `@method` decorator | | [declareState](functions/declareState.mdx) | `declareState` can be used in place of the `@state` decorator to declare on-chain state on a SmartContract. | | [fetchAccount](functions/fetchAccount.mdx) | Gets account information on the specified publicKey by performing a GraphQL query | | [fetchEvents](functions/fetchEvents.mdx) | Asynchronously fetches event data for an account from the Mina Archive Node GraphQL API. | | [fetchLastBlock](functions/fetchLastBlock.mdx) | Fetches the last block on the Mina network. | | [fetchTransactionStatus](functions/fetchTransactionStatus.mdx) | Fetches the status of a transaction. | | [genericHash](functions/genericHash.mdx) | - | | [initializeBindings](functions/initializeBindings.mdx) | A function that has to finish before any bindings exports can be used. | | [merkleListHash](functions/merkleListHash.mdx) | - | | [method](functions/method.mdx) | A decorator to use in a zkApp to mark a method as provable. | | [provable](functions/provable.mdx) | - | | [provablePure](functions/provablePure.mdx) | - | | [public\_](functions/public.mdx) | - | | [readVarMessage](functions/readVarMessage.mdx) | - | | [sendZkapp](functions/sendZkapp.mdx) | Sends a zkApp command (transaction) to the specified GraphQL endpoint. | | [setArchiveGraphqlEndpoint](functions/setArchiveGraphqlEndpoint.mdx) | Sets up a GraphQL endpoint to be used for fetching information from an Archive Node. | | [setGraphqlEndpoint](functions/setGraphqlEndpoint.mdx) | - | | [setGraphqlEndpoints](functions/setGraphqlEndpoints.mdx) | - | | [setNumberOfWorkers](functions/setNumberOfWorkers.mdx) | Set the number of workers to use for parallelizing the proof generation. By default the number of workers is set to the number of physical CPU cores on your machine, but there may be some instances where you want to set the number of workers manually. Some machines may have a large number of cores, but not enough memory to support that many workers. In that case, you can set the number of workers to a lower number to avoid running out of memory. On the other hand, some machines with heterogeneous cores may benefit from setting the number of workers to a lower number to avoid contention between core types if load-link/store-conditional multithreading is used. Feel free to experiment and see what works best for your use case. Maybe you can squeeze slightly more performance out by tweaking this value :) | | [state](functions/state-1.mdx) | A decorator to use within a zkapp to indicate what will be stored on-chain. | | [toConstantField](functions/toConstantField.mdx) | - | | [toFp](functions/toFp.mdx) | - | | [verify](functions/verify.mdx) | - | | [withHashes](functions/withHashes.mdx) | - | | [withMessage](functions/withMessage.mdx) | - | --- url: /zkapps/o1js-reference/classes/AccountUpdate --- An [AccountUpdate](AccountUpdate.mdx) is a set of instructions for the Mina network. It includes Preconditions and a list of state updates, which need to be authorized by either a [Signature](Signature.mdx) or [Proof](Proof.mdx). ## Implements - `AccountUpdate` ## Constructors ### new AccountUpdate() ```ts new AccountUpdate(body: Body, authorization?: {}): AccountUpdate ``` #### Parameters • **body**: `Body` • **authorization?** #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:703](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L703) ## Properties ### account ```ts account: Account; ``` #### Source [lib/mina/account-update.ts:694](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L694) *** ### authorization ```ts authorization: {}; ``` #### Implementation of `Types.AccountUpdate.authorization` #### Source [lib/mina/account-update.ts:691](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L691) *** ### body ```ts body: Body; ``` #### Implementation of `Types.AccountUpdate.body` #### Source [lib/mina/account-update.ts:690](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L690) *** ### currentSlot ```ts currentSlot: CurrentSlot; ``` #### Source [lib/mina/account-update.ts:696](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L696) *** ### id ```ts id: number; ``` #### Source [lib/mina/account-update.ts:684](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L684) *** ### label ```ts label: string = ''; ``` A human-readable label for the account update, indicating how that update was created. Can be modified by applications to add richer information. #### Source [lib/mina/account-update.ts:689](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L689) *** ### lazyAuthorization ```ts lazyAuthorization: undefined | LazySignature | LazyProof | LazyNone = undefined; ``` #### Source [lib/mina/account-update.ts:692](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L692) *** ### network ```ts network: Network; ``` #### Source [lib/mina/account-update.ts:695](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L695) *** ### Actions ```ts static Actions: { "emptyActionState": Field; "fromList": Events; "hash": Field; "pushEvent": Events; "updateSequenceState": Field; }; ``` #### emptyActionState() ##### Returns [`Field`](Field.mdx) #### fromList() ##### Parameters • **events**: `Event`[] ##### Returns `Events` #### hash() ##### Parameters • **events**: `Event`[] ##### Returns [`Field`](Field.mdx) #### pushEvent() ##### Parameters • **actions**: `Events` • **action**: [`Field`](Field.mdx)[] ##### Returns `Events` #### updateSequenceState() ##### Parameters • **state**: [`Field`](Field.mdx) • **sequenceEventsHash**: [`Field`](Field.mdx) ##### Returns [`Field`](Field.mdx) #### Source [lib/mina/account-update.ts:700](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L700) *** ### Events ```ts static Events: { "fromList": Events; "hash": Field; "pushEvent": Events; }; ``` #### fromList() ##### Parameters • **events**: `Event`[] ##### Returns `Events` #### hash() ##### Parameters • **events**: `Event`[] ##### Returns [`Field`](Field.mdx) #### pushEvent() ##### Parameters • **events**: `Events` • **event**: [`Field`](Field.mdx)[] ##### Returns `Events` #### Source [lib/mina/account-update.ts:701](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L701) *** ### MayUseToken ```ts static MayUseToken: { "InheritFromParent": { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; "No": { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; "ParentsOwnToken": { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; "isInheritFromParent": (a: AccountUpdate) => Bool; "isNo": (__namedParameters: AccountUpdate) => Bool; "isParentsOwnToken": (a: AccountUpdate) => Bool; "type": BaseMayUseToken; }; ``` #### InheritFromParent ```ts InheritFromParent: { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; ``` #### InheritFromParent.inheritFromParent ```ts inheritFromParent: Bool; ``` #### InheritFromParent.parentsOwnToken ```ts parentsOwnToken: Bool; ``` #### No ```ts No: { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; ``` #### No.inheritFromParent ```ts inheritFromParent: Bool; ``` #### No.parentsOwnToken ```ts parentsOwnToken: Bool; ``` #### ParentsOwnToken ```ts ParentsOwnToken: { "inheritFromParent": Bool; "parentsOwnToken": Bool; }; ``` #### ParentsOwnToken.inheritFromParent ```ts inheritFromParent: Bool; ``` #### ParentsOwnToken.parentsOwnToken ```ts parentsOwnToken: Bool; ``` #### isInheritFromParent() ```ts isInheritFromParent: (a: AccountUpdate) => Bool; ``` ##### Parameters • **a**: [`AccountUpdate`](AccountUpdate.mdx) ##### Returns [`Bool`](Bool.mdx) #### isNo() ```ts isNo: (__namedParameters: AccountUpdate) => Bool; ``` ##### Parameters • **\_\_namedParameters**: [`AccountUpdate`](AccountUpdate.mdx) ##### Returns [`Bool`](Bool.mdx) #### isParentsOwnToken() ```ts isParentsOwnToken: (a: AccountUpdate) => Bool; ``` ##### Parameters • **a**: [`AccountUpdate`](AccountUpdate.mdx) ##### Returns [`Bool`](Bool.mdx) #### type ```ts type: {} = BaseMayUseToken; ``` #### Source [lib/mina/account-update.ts:1235](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1235) *** ### check() ```ts static check: (x: AccountUpdate) => void = Types.AccountUpdate.check; ``` #### Parameters • **x**: `AccountUpdate` #### Returns `void` #### Source [lib/mina/account-update.ts:1187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1187) *** ### sizeInFields() ```ts static sizeInFields: () => number = Types.AccountUpdate.sizeInFields; ``` #### Returns `number` #### Source [lib/mina/account-update.ts:1174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1174) *** ### toFields() ```ts static toFields: (x: AccountUpdate) => Field[] = Types.AccountUpdate.toFields; ``` #### Parameters • **x**: `AccountUpdate` #### Returns [`Field`](Field.mdx)[] #### Source [lib/mina/account-update.ts:1175](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1175) *** ### toInput() ```ts static toInput: (x: AccountUpdate) => {} = Types.AccountUpdate.toInput; ``` #### Parameters • **x**: `AccountUpdate` #### Returns ```ts {} ``` #### Source [lib/mina/account-update.ts:1183](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1183) *** ### toValue() ```ts static toValue: (x: AccountUpdate) => AccountUpdate = Types.AccountUpdate.toValue; ``` #### Parameters • **x**: `AccountUpdate` #### Returns `AccountUpdate` #### Source [lib/mina/account-update.ts:1195](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1195) ## Accessors ### balance ```ts get balance(): { "addInPlace": void; "subInPlace": void; } ``` #### Returns ```ts { "addInPlace": void; "subInPlace": void; } ``` ##### addInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` ##### subInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` #### Source [lib/mina/account-update.ts:785](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L785) *** ### balanceChange ```ts get balanceChange(): Int64 ``` ```ts set balanceChange(x: Int64): void ``` #### Parameters • **x**: [`Int64`](Int64.mdx) #### Returns [`Int64`](Int64.mdx) #### Source [lib/mina/account-update.ts:800](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L800) *** ### publicKey ```ts get publicKey(): PublicKey ``` #### Returns [`PublicKey`](PublicKey.mdx) #### Source [lib/mina/account-update.ts:875](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L875) *** ### tokenId ```ts get tokenId(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/mina/account-update.ts:732](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L732) *** ### update ```ts get update(): {} ``` #### Returns ```ts {} ``` #### Source [lib/mina/account-update.ts:807](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L807) ## Methods ### approve() ```ts approve(child: AccountUpdate | AccountUpdateTree | AccountUpdateForest): void ``` Makes another [AccountUpdate](AccountUpdate.mdx) a child of this one. The parent-child relationship means that the child becomes part of the "statement" of the parent, and goes into the commitment that is authorized by either a signature or a proof. For a proof in particular, child account updates are contained in the public input of the proof that authorizes the parent account update. #### Parameters • **child**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) \| [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Returns `void` #### Source [lib/mina/account-update.ts:773](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L773) *** ### extractTree() ```ts extractTree(): AccountUpdateTree ``` #### Returns [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Source [lib/mina/account-update.ts:1021](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1021) *** ### hash() ```ts hash(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/mina/account-update.ts:977](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L977) *** ### isDummy() ```ts isDummy(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/mina/account-update.ts:1047](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1047) *** ### requireSignature() ```ts requireSignature(): void ``` Use this command if this account update should be signed by the account owner, instead of not having any authorization. If you use this and are not relying on a wallet to sign your transaction, then you should use the following code before sending your transaction: ```ts let tx = await Mina.transaction(...); // create transaction as usual, using `requireSignature()` somewhere tx.sign([privateKey]); // pass the private key of this account to `sign()`! ``` Note that an account's [Permissions](../variables/Permissions.mdx) determine which updates have to be (can be) authorized by a signature. #### Returns `void` #### Source [lib/mina/account-update.ts:894](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L894) *** ### send() ```ts send(__namedParameters: { "amount": number | bigint | UInt64; "to": PublicKey | AccountUpdate | SmartContract; }): AccountUpdate ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) • **\_\_namedParameters.to**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:736](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L736) *** ### toJSON() ```ts toJSON(): AccountUpdate ``` #### Returns `AccountUpdate` #### Source [lib/mina/account-update.ts:966](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L966) *** ### toPretty() ```ts toPretty(): any ``` Returns a JSON representation of only the fields that differ from the default [AccountUpdate](AccountUpdate.mdx). #### Returns `any` #### Source [lib/mina/account-update.ts:1241](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1241) *** ### toPrettyLayout() ```ts toPrettyLayout(): void ``` #### Returns `void` #### Source [lib/mina/account-update.ts:1015](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1015) *** ### toPublicInput() ```ts toPublicInput(__namedParameters: { "accountUpdates": AccountUpdate[]; }): ZkappPublicInput ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.accountUpdates**: [`AccountUpdate`](AccountUpdate.mdx)[] #### Returns [`ZkappPublicInput`](../type-aliases/ZkappPublicInput.mdx) #### Source [lib/mina/account-update.ts:985](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L985) *** ### assertBetween() ```ts static assertBetween( property: OrIgnore>, lower: T, upper: T): void ``` Constrain a property to lie between lower and upper bounds. #### Type parameters • **T** #### Parameters • **property**: `OrIgnore`\<`ClosedInterval`\<`T`\>\> The property to constrain • **lower**: `T` The lower bound • **upper**: `T` The upper bound Example: To constrain the account balance of a SmartContract to lie between 0 and 20 MINA, you can use ```ts \@method onlyRunsWhenBalanceIsLow() { let lower = UInt64.zero; let upper = UInt64.from(20e9); AccountUpdate.assertBetween(this.self.body.preconditions.account.balance, lower, upper); // ... } ``` #### Returns `void` #### Source [lib/mina/account-update.ts:835](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L835) *** ### assertEquals() ```ts static assertEquals(property: OrIgnore>, value: T): void ``` Fix a property to a certain value. #### Type parameters • **T** *extends* `object` #### Parameters • **property**: `OrIgnore`\<`T` \| `ClosedInterval`\<`T`\>\> The property to constrain • **value**: `T` The value it is fixed to Example: To fix the account nonce of a SmartContract to 0, you can use ```ts \@method onlyRunsWhenNonceIsZero() { AccountUpdate.assertEquals(this.self.body.preconditions.account.nonce, UInt32.zero); // ... } ``` #### Returns `void` #### Source [lib/mina/account-update.ts:862](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L862) *** ### attachToTransaction() ```ts static attachToTransaction(accountUpdate: AccountUpdate): void ``` Attach account update to the current transaction -- if in a smart contract, to its children #### Parameters • **accountUpdate**: [`AccountUpdate`](AccountUpdate.mdx) #### Returns `void` #### Source [lib/mina/account-update.ts:1107](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1107) *** ### clone() ```ts static clone(accountUpdate: AccountUpdate): AccountUpdate ``` Clones the [AccountUpdate](AccountUpdate.mdx). #### Parameters • **accountUpdate**: [`AccountUpdate`](AccountUpdate.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:718](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L718) *** ### create() ```ts static create(publicKey: PublicKey, tokenId?: Field): AccountUpdate ``` Creates an account update. If this is inside a transaction, the account update becomes part of the transaction. If this is inside a smart contract method, the account update will not only become part of the transaction, but also becomes available for the smart contract to modify, in a way that becomes part of the proof. #### Parameters • **publicKey**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1072](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1072) *** ### createIf() ```ts static createIf( condition: Bool, publicKey: PublicKey, tokenId?: Field): AccountUpdate ``` Create an account update that is added to the transaction only if a condition is met. See [AccountUpdate.create](AccountUpdate.mdx#create) for more information. In this method, you can pass in a condition that determines whether the account update should be added to the transaction. #### Parameters • **condition**: [`Bool`](Bool.mdx) • **publicKey**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1094](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1094) *** ### createSigned() ```ts static createSigned(publicKey: PublicKey, tokenId?: Field): AccountUpdate ``` Creates an account update, like [AccountUpdate.create](AccountUpdate.mdx#create), but also makes sure this account update will be authorized with a signature. If you use this and are not relying on a wallet to sign your transaction, then you should use the following code before sending your transaction: ```ts let tx = await Mina.transaction(...); // create transaction as usual, using `createSigned()` somewhere tx.sign([privateKey]); // pass the private key of this account to `sign()`! ``` Note that an account's [Permissions](../variables/Permissions.mdx) determine which updates have to be (can be) authorized by a signature. #### Parameters • **publicKey**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1143](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1143) *** ### default() ```ts static default(address: PublicKey, tokenId?: Field): AccountUpdate ``` Create an account update from a public key and an optional token id. **Important**: This method is different from `AccountUpdate.create()`, in that it really just creates the account update object. It does not attach the update to the current transaction or smart contract. Use this method for lower-level operations with account updates. #### Parameters • **address**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1038](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1038) *** ### defaultFeePayer() ```ts static defaultFeePayer(address: PublicKey, nonce: UInt32): FeePayerUnsigned ``` #### Parameters • **address**: [`PublicKey`](PublicKey.mdx) • **nonce**: [`UInt32`](UInt32.mdx) #### Returns `FeePayerUnsigned` #### Source [lib/mina/account-update.ts:1051](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1051) *** ### dummy() ```ts static dummy(): AccountUpdate ``` #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1042](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1042) *** ### dummyFeePayer() ```ts static dummyFeePayer(): FeePayerUnsigned ``` #### Returns `FeePayerUnsigned` #### Source [lib/mina/account-update.ts:1060](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1060) *** ### empty() ```ts static empty(): AccountUpdate ``` #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1184](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1184) *** ### fromFields() ```ts static fromFields(fields: Field[], __namedParameters: any[]): AccountUpdate ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] • **\_\_namedParameters**: `any`[] #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1188](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1188) *** ### fromJSON() ```ts static fromJSON(json: AccountUpdate): AccountUpdate ``` #### Parameters • **json**: `AccountUpdate` #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:972](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L972) *** ### fromValue() ```ts static fromValue(value: AccountUpdate | AccountUpdate | AccountUpdate): AccountUpdate ``` #### Parameters • **value**: `AccountUpdate` \| `AccountUpdate` \| [`AccountUpdate`](AccountUpdate.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/account-update.ts:1196](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1196) *** ### fundNewAccount() ```ts static fundNewAccount(feePayer: PublicKey, numberOfAccounts: number): AccountUpdate ``` Use this method to pay the account creation fee for another account (or, multiple accounts using the optional second argument). Beware that you _don't_ need to specify the account that is created! Instead, the protocol will automatically identify that accounts need to be created, and require that the net balance change of the transaction covers the account creation fee. #### Parameters • **feePayer**: [`PublicKey`](PublicKey.mdx) the address of the account that pays the fee • **numberOfAccounts**: `number`= `1` the number of new accounts to fund (default: 1) #### Returns [`AccountUpdate`](AccountUpdate.mdx) they [AccountUpdate](AccountUpdate.mdx) for the account which pays the fee #### Source [lib/mina/account-update.ts:1164](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1164) *** ### getNonce() ```ts static getNonce(accountUpdate: FeePayerUnsigned | AccountUpdate): UInt32 ``` #### Parameters • **accountUpdate**: `FeePayerUnsigned` \| [`AccountUpdate`](AccountUpdate.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/mina/account-update.ts:918](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L918) *** ### setValue() ```ts static setValue(maybeValue: SetOrKeep, value: T): void ``` #### Type parameters • **T** #### Parameters • **maybeValue**: `SetOrKeep`\<`T`\> • **value**: `T` #### Returns `void` #### Source [lib/mina/account-update.ts:811](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L811) *** ### signFeePayerInPlace() ```ts static signFeePayerInPlace(feePayer: FeePayerUnsigned): void ``` #### Parameters • **feePayer**: `FeePayerUnsigned` #### Returns `void` #### Source [lib/mina/account-update.ts:912](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L912) *** ### toAuxiliary() ```ts static toAuxiliary(a?: AccountUpdate): (any[] | { "id": number; "label": string; "lazyAuthorization": undefined | LazySignature | LazyProof | LazyNone; })[] ``` #### Parameters • **a?**: [`AccountUpdate`](AccountUpdate.mdx) #### Returns (`any`[] \| \{ `"id"`: `number`; `"label"`: `string`; `"lazyAuthorization"`: `undefined` \| `LazySignature` \| `LazyProof` \| `LazyNone`; \})[] #### Source [lib/mina/account-update.ts:1176](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1176) *** ### toJSON() ```ts static toJSON(a: AccountUpdate): AccountUpdate ``` #### Parameters • **a**: [`AccountUpdate`](AccountUpdate.mdx) #### Returns `AccountUpdate` #### Source [lib/mina/account-update.ts:969](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L969) *** ### unlink() ```ts static unlink(accountUpdate: AccountUpdate): void ``` Disattach an account update from where it's currently located in the transaction #### Parameters • **accountUpdate**: [`AccountUpdate`](AccountUpdate.mdx) #### Returns `void` #### Source [lib/mina/account-update.ts:1124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1124) *** ### witness() ```ts static witness( resultType: FlexibleProvable, compute: () => Promise<{ "accountUpdate": AccountUpdate; "result": T; }>, __namedParameters: { "skipCheck": false; }): Promise<{ "accountUpdate": AccountUpdate; "result": T; }> ``` #### Type parameters • **T** #### Parameters • **resultType**: [`FlexibleProvable`](../type-aliases/FlexibleProvable.mdx)\<`T`\> • **compute** • **\_\_namedParameters**= `{}` • **\_\_namedParameters.skipCheck**: `undefined` \| `boolean`= `false` #### Returns `Promise`\<\{ `"accountUpdate"`: [`AccountUpdate`](AccountUpdate.mdx); `"result"`: `T`; \}\> > ##### accountUpdate > > ```ts > accountUpdate: AccountUpdate; > ``` > > ##### result > > ```ts > result: T; > ``` > #### Source [lib/mina/account-update.ts:1219](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1219) --- url: /zkapps/o1js-reference/classes/AccountUpdateForest --- Class which represents a forest (list of trees) of account updates, in a compressed way which allows iterating and selectively witnessing the account updates. The (recursive) type signature is: ``` type AccountUpdateForest = MerkleList; type AccountUpdateTree = { accountUpdate: Hashed; children: AccountUpdateForest; }; ``` ## Extends - [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}, `this`\> ## Constructors ### new AccountUpdateForest() ```ts new AccountUpdateForest(__namedParameters: MerkleListBase<{ "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }>): AccountUpdateForest ``` #### Parameters • **\_\_namedParameters**: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> #### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Inherited from [`MerkleList`](MerkleList.mdx).[`constructor`](MerkleList.mdx#constructors) #### Source [lib/provable/merkle-list.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L84) ## Properties ### data ```ts data: Unconstrained; "id": RandomId; }>[]>; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`data`](MerkleList.mdx#data) #### Source [lib/provable/merkle-list.ts:82](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L82) *** ### hash ```ts hash: Field; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`hash`](MerkleList.mdx#hash) #### Source [lib/provable/merkle-list.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L81) *** ### \_emptyHash ```ts static _emptyHash: undefined | Field; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`_emptyHash`](MerkleList.mdx#_emptyhash) #### Source [lib/provable/merkle-list.ts:350](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L350) *** ### \_innerProvable ```ts static _innerProvable: undefined | ProvableHashable; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`_innerProvable`](MerkleList.mdx#_innerprovable) #### Source [lib/provable/merkle-list.ts:353](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L353) *** ### \_nextHash ```ts static _nextHash: undefined | (hash: Field, t: any) => Field; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`_nextHash`](MerkleList.mdx#_nexthash) #### Source [lib/provable/merkle-list.ts:349](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L349) *** ### \_provable ```ts static _provable: undefined | ProvableHashable>; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`_provable`](MerkleList.mdx#_provable) #### Source [lib/provable/merkle-list.ts:352](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L352) *** ### provable ```ts static provable: { "check": void; "empty": AccountUpdateForest; "fromFields": AccountUpdateForest; "fromValue": AccountUpdateForest; "sizeInFields": number; "toAuxiliary": any[]; "toFields": Field[]; "toInput": HashInput; "toValue": any; }; ``` #### check() ##### Parameters • **value**: [`AccountUpdateForest`](AccountUpdateForest.mdx) \| [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> ##### Returns `void` #### empty() ##### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### fromFields() ##### Parameters • **fields**: [`Field`](Field.mdx)[] • **aux**: `any`[] ##### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### fromValue() ##### Parameters • **value**: `any` ##### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### sizeInFields() ##### Returns `number` #### toAuxiliary() ##### Parameters • **value?**: [`AccountUpdateForest`](AccountUpdateForest.mdx) \| [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> ##### Returns `any`[] #### toFields() ##### Parameters • **value**: [`AccountUpdateForest`](AccountUpdateForest.mdx) \| [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> ##### Returns [`Field`](Field.mdx)[] #### toInput() ##### Parameters • **value**: [`AccountUpdateForest`](AccountUpdateForest.mdx) \| [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> ##### Returns `HashInput` #### toValue() ##### Parameters • **value**: [`AccountUpdateForest`](AccountUpdateForest.mdx) \| [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> ##### Returns `any` #### Overrides `MerkleList.create( AccountUpdateTreeBase, merkleListHash ).provable` #### Source [lib/mina/account-update.ts:1379](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1379) ## Accessors ### Constructor ```ts get Constructor(): typeof MerkleList ``` #### Returns *typeof* [`MerkleList`](MerkleList.mdx) #### Source [lib/provable/merkle-list.ts:355](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L355) *** ### innerProvable ```ts get innerProvable(): ProvableHashable ``` #### Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:372](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L372) *** ### emptyHash ```ts get static emptyHash(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/merkle-list.ts:367](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L367) ## Methods ### clone() ```ts clone(): MerkleList<{ "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }> ``` #### Returns [`MerkleList`](MerkleList.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> > ##### accountUpdate > > ```ts > accountUpdate: Hashed = HashedAccountUpdate; > ``` > > ##### children > > ```ts > children: MerkleListBase; > ``` > > ##### id > > ```ts > id: number = RandomId; > ``` > #### Inherited from [`MerkleList`](MerkleList.mdx).[`clone`](MerkleList.mdx#clone) #### Source [lib/provable/merkle-list.ts:223](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L223) *** ### forEach() ```ts forEach(length: number, callback: (element: { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }, isDummy: Bool, i: number) => void): void ``` Iterate through the list in a fixed number of steps any apply a given callback on each element. Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback. Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the `isDummy` flag separately. #### Parameters • **length**: `number` • **callback** #### Returns `void` #### Inherited from [`MerkleList`](MerkleList.mdx).[`forEach`](MerkleList.mdx#foreach) #### Source [lib/provable/merkle-list.ts:237](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L237) *** ### isEmpty() ```ts isEmpty(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Inherited from [`MerkleList`](MerkleList.mdx).[`isEmpty`](MerkleList.mdx#isempty) #### Source [lib/provable/merkle-list.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L89) *** ### lengthUnconstrained() ```ts lengthUnconstrained(): Unconstrained ``` #### Returns [`Unconstrained`](Unconstrained.mdx)\<`number`\> #### Inherited from [`MerkleList`](MerkleList.mdx).[`lengthUnconstrained`](MerkleList.mdx#lengthunconstrained) #### Source [lib/provable/merkle-list.ts:267](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L267) *** ### nextHash() ```ts nextHash(hash: Field, value: { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }): Field ``` #### Parameters • **hash**: [`Field`](Field.mdx) • **value** • **value.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **value.children**: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>= `undefined` • **value.id**: `number`= `RandomId` #### Returns [`Field`](Field.mdx) #### Inherited from [`MerkleList`](MerkleList.mdx).[`nextHash`](MerkleList.mdx#nexthash) #### Source [lib/provable/merkle-list.ts:359](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L359) *** ### pop() ```ts pop(): { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` Remove the last element from the list and return it. If the list is empty, returns a dummy element. #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: MerkleListBase; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`pop`](MerkleList.mdx#pop) #### Source [lib/provable/merkle-list.ts:155](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L155) *** ### popExn() ```ts popExn(): { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` Remove the last element from the list and return it. This proves that the list is non-empty, and fails otherwise. #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: MerkleListBase; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`popExn`](MerkleList.mdx#popexn) #### Source [lib/provable/merkle-list.ts:140](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L140) *** ### popIf() ```ts popIf(condition: Bool): { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` Return the last element, but only remove it if `condition` is true. If the list is empty, returns a dummy element. #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: MerkleListBase; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`popIf`](MerkleList.mdx#popif) #### Source [lib/provable/merkle-list.ts:174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L174) *** ### popIfUnsafe() ```ts popIfUnsafe(shouldPop: Bool): { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` Low-level, minimal version of `pop()` which lets the _caller_ decide whether there is an element to pop. I.e. this proves: - If the input condition is true, this returns the last element and removes it from the list. - If the input condition is false, the list is unchanged and the return value is garbage. Note that if the caller passes `true` but the list is empty, this will fail. If the caller passes `false` but the list is non-empty, this succeeds and just doesn't pop off an element. #### Parameters • **shouldPop**: [`Bool`](Bool.mdx) #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: MerkleListBase; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from [`MerkleList`](MerkleList.mdx).[`popIfUnsafe`](MerkleList.mdx#popifunsafe) #### Source [lib/provable/merkle-list.ts:200](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L200) *** ### push() ```ts push(update: AccountUpdate | AccountUpdateTreeBase): void ``` Push a new element to the list. #### Parameters • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| `AccountUpdateTreeBase` #### Returns `void` #### Overrides [`MerkleList`](MerkleList.mdx).[`push`](MerkleList.mdx#push) #### Source [lib/mina/account-update.ts:1381](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1381) *** ### pushIf() ```ts pushIf(condition: Bool, update: AccountUpdate | AccountUpdateTreeBase): void ``` Push a new element to the list, if the `condition` is true. #### Parameters • **condition**: [`Bool`](Bool.mdx) • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| `AccountUpdateTreeBase` #### Returns `void` #### Overrides [`MerkleList`](MerkleList.mdx).[`pushIf`](MerkleList.mdx#pushif) #### Source [lib/mina/account-update.ts:1386](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1386) *** ### startIterating() ```ts startIterating(): MerkleListIterator<{ "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }> ``` #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> > ##### accountUpdate > > ```ts > accountUpdate: Hashed = HashedAccountUpdate; > ``` > > ##### children > > ```ts > children: MerkleListBase; > ``` > > ##### id > > ```ts > id: number = RandomId; > ``` > #### Inherited from [`MerkleList`](MerkleList.mdx).[`startIterating`](MerkleList.mdx#startiterating) #### Source [lib/provable/merkle-list.ts:251](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L251) *** ### startIteratingFromLast() ```ts startIteratingFromLast(): MerkleListIterator<{ "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }> ``` #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}\> > ##### accountUpdate > > ```ts > accountUpdate: Hashed = HashedAccountUpdate; > ``` > > ##### children > > ```ts > children: MerkleListBase; > ``` > > ##### id > > ```ts > id: number = RandomId; > ``` > #### Inherited from [`MerkleList`](MerkleList.mdx).[`startIteratingFromLast`](MerkleList.mdx#startiteratingfromlast) #### Source [lib/provable/merkle-list.ts:256](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L256) *** ### toArrayUnconstrained() ```ts toArrayUnconstrained(): Unconstrained<{ "accountUpdate": HashedAccountUpdate; "children": MerkleListBase; "id": RandomId; }[]> ``` #### Returns [`Unconstrained`](Unconstrained.mdx)\<\{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`AccountUpdateTreeBase`\>; `"id"`: `RandomId`; \}[]\> #### Inherited from [`MerkleList`](MerkleList.mdx).[`toArrayUnconstrained`](MerkleList.mdx#toarrayunconstrained) #### Source [lib/provable/merkle-list.ts:261](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L261) *** ### toFlatArray() ```ts toFlatArray(mutate: boolean, depth: number): AccountUpdate[] ``` #### Parameters • **mutate**: `boolean`= `true` • **depth**: `number`= `0` #### Returns [`AccountUpdate`](AccountUpdate.mdx)[] #### Source [lib/mina/account-update.ts:1398](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1398) *** ### assertConstant() ```ts static assertConstant(forest: AccountUpdateForestBase): void ``` #### Parameters • **forest**: `AccountUpdateForestBase` #### Returns `void` #### Source [lib/mina/account-update.ts:1429](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1429) *** ### create() ```ts static create( type: WithProvable>, nextHash: (hash: Field, value: T) => Field, emptyHash_: Field): typeof MerkleList & { "empty": () => MerkleList; "from": (array: T[]) => MerkleList; "fromReverse": (array: T[]) => MerkleList; "provable": ProvableHashable>; } ``` Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<[`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\>\> • **nextHash**= `undefined` • **emptyHash\_**: [`Field`](Field.mdx)= `emptyHash` #### Returns *typeof* [`MerkleList`](MerkleList.mdx) & \{ `"empty"`: () => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"from"`: (`array`: `T`[]) => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"fromReverse"`: (`array`: `T`[]) => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`MerkleList`](MerkleList.mdx)\<`T`\>\>; \} #### Inherited from [`MerkleList`](MerkleList.mdx).[`create`](MerkleList.mdx#create) #### Example ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` #### Source [lib/provable/merkle-list.ts:283](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L283) *** ### empty() ```ts static empty(): AccountUpdateForest ``` #### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Overrides `MerkleList.create( AccountUpdateTreeBase, merkleListHash ).empty` #### Source [lib/mina/account-update.ts:1442](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1442) *** ### from() ```ts static from(array: AccountUpdateTreeBase[]): AccountUpdateForest ``` #### Parameters • **array**: `AccountUpdateTreeBase`[] #### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Overrides `MerkleList.create( AccountUpdateTreeBase, merkleListHash ).from` #### Source [lib/mina/account-update.ts:1445](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1445) *** ### fromFlatArray() ```ts static fromFlatArray(updates: AccountUpdate[]): AccountUpdateForest ``` #### Parameters • **updates**: [`AccountUpdate`](AccountUpdate.mdx)[] #### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Source [lib/mina/account-update.ts:1393](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1393) *** ### fromReverse() ```ts static fromReverse(array: AccountUpdateTreeBase[]): AccountUpdateForest ``` #### Parameters • **array**: `AccountUpdateTreeBase`[] #### Returns [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Overrides `MerkleList.create( AccountUpdateTreeBase, merkleListHash ).fromReverse` #### Source [lib/mina/account-update.ts:1448](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1448) *** ### toFlatArray() ```ts static toFlatArray( forest: AccountUpdateForestBase, mutate: boolean, depth: number): AccountUpdate[] ``` #### Parameters • **forest**: `AccountUpdateForestBase` • **mutate**: `boolean`= `true` • **depth**: `number`= `0` #### Returns [`AccountUpdate`](AccountUpdate.mdx)[] #### Source [lib/mina/account-update.ts:1402](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1402) --- url: /zkapps/o1js-reference/classes/AccountUpdateTree --- Class which represents a tree of account updates, in a compressed way which allows iterating and selectively witnessing the account updates. The (recursive) type signature is: ``` type AccountUpdateTree = { accountUpdate: Hashed; children: AccountUpdateForest; }; type AccountUpdateForest = MerkleList; ``` ## Extends - \{ `"accountUpdate"`: `HashedAccountUpdate`; `"children"`: `AccountUpdateForest`; `"id"`: `RandomId`; \} ## Constructors ### new AccountUpdateTree() ```ts new AccountUpdateTree(value: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }): AccountUpdateTree ``` #### Parameters • **value** • **value.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **value.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **value.id**: `number`= `RandomId` #### Returns [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).constructor` #### Source [lib/provable/types/struct.ts:280](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L280) ## Properties ### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).accountUpdate` #### Source [lib/mina/account-update.ts:1468](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1468) *** ### children ```ts children: AccountUpdateForest = AccountUpdateForest; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).children` #### Source [lib/mina/account-update.ts:1469](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1469) *** ### id ```ts id: number = RandomId; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).id` #### Source [lib/mina/account-update.ts:1467](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1467) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, })._isStruct` #### Source [lib/provable/types/struct.ts:280](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L280) *** ### check() ```ts static check: (value: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **value.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **value.id**: `number`= `RandomId` #### Returns `void` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### fromValue() ```ts static fromValue: (x: any) => { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }; ``` Convert provable type from a normal JS type. #### Parameters • **x**: `any` #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: AccountUpdateForest = AccountUpdateForest; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.accountUpdate?**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **value.children?**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **value.id?**: `number`= `RandomId` #### Returns `any`[] #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **x.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **x.id**: `number`= `RandomId` #### Returns ```ts { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; } ``` ##### accountUpdate ```ts accountUpdate: Hashed = HashedAccountUpdate; ``` ##### children ```ts children: AccountUpdateForest = AccountUpdateForest; ``` ##### id ```ts id: number = RandomId; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **value.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **value.id**: `number`= `RandomId` #### Returns [`Field`](Field.mdx)[] #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **x.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **x.id**: `number`= `RandomId` #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).toInput` #### Source [lib/provable/types/struct.ts:283](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L283) *** ### toValue() ```ts static toValue: (x: { "accountUpdate": HashedAccountUpdate; "children": AccountUpdateForest; "id": RandomId; }) => any; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.accountUpdate**: [`Hashed`](Hashed.mdx)\<[`AccountUpdate`](AccountUpdate.mdx)\>= `HashedAccountUpdate` • **x.children**: [`AccountUpdateForest`](AccountUpdateForest.mdx)= `AccountUpdateForest` • **x.id**: `number`= `RandomId` #### Returns `any` #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### approve() ```ts approve(update: AccountUpdate | AccountUpdateTree, hash?: Field): void ``` Add an [AccountUpdate](AccountUpdate.mdx) or [AccountUpdateTree](AccountUpdateTree.mdx) to the children of this tree's root. See [AccountUpdate.approve](AccountUpdate.mdx#approve). #### Parameters • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) • **hash?**: [`Field`](Field.mdx) #### Returns `void` #### Source [lib/mina/account-update.ts:1488](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1488) *** ### empty() ```ts static empty(): AccountUpdateTree ``` #### Returns [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Overrides `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).empty` #### Source [lib/mina/account-update.ts:1504](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1504) *** ### from() ```ts static from(update: AccountUpdate | AccountUpdateTree, hash?: Field): AccountUpdateTree ``` Create a tree of account updates which only consists of a root. #### Parameters • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) • **hash?**: [`Field`](Field.mdx) #### Returns [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Source [lib/mina/account-update.ts:1474](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1474) *** ### fromFields() ```ts static fromFields(fields: Field[], aux: any): AccountUpdateTree ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] • **aux**: `any` #### Returns [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Overrides `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).fromFields` #### Source [lib/mina/account-update.ts:1501](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L1501) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `StructNoJson({ id: RandomId, accountUpdate: HashedAccountUpdate, children: AccountUpdateForest, }).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/classes/AlmostForeignField --- ## Extends - `ForeignFieldWithMul` ## Constructors ### new AlmostForeignField() ```ts new AlmostForeignField(x: | string | number | bigint | Field3 | AlmostForeignField): AlmostForeignField ``` #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Overrides `ForeignFieldWithMul.constructor` #### Source [lib/provable/foreign-field.ts:487](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L487) ## Properties ### type ```ts type: "AlmostReduced" | "FullyReduced" = 'AlmostReduced'; ``` #### Source [lib/provable/foreign-field.ts:485](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L485) *** ### value ```ts value: Field3; ``` The internal representation of a foreign field element, as a tuple of 3 limbs. #### Inherited from `ForeignFieldWithMul.value` #### Source [lib/provable/foreign-field.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L49) *** ### \_Bigint ```ts static _Bigint: undefined | {} = undefined; ``` #### Inherited from `ForeignFieldWithMul._Bigint` #### Source [lib/provable/foreign-field.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L27) *** ### \_modulus ```ts static _modulus: undefined | bigint = undefined; ``` #### Inherited from `ForeignFieldWithMul._modulus` #### Source [lib/provable/foreign-field.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L28) *** ### \_provable ```ts static _provable: undefined | ProvablePureExtended = undefined; ``` #### Overrides `ForeignFieldWithMul._provable` #### Source [lib/provable/foreign-field.ts:491](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L491) *** ### \_variants ```ts static _variants: undefined | { "almostReduced": typeof AlmostForeignField; "canonical": typeof CanonicalForeignField; "unreduced": typeof UnreducedForeignField; } = undefined; ``` Sibling classes that represent different ranges of field elements. #### Inherited from `ForeignFieldWithMul._variants` #### Source [lib/provable/foreign-field.ts:58](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L58) ## Accessors ### Constructor ```ts get Constructor(): typeof ForeignField ``` #### Returns *typeof* [`ForeignField`](ForeignField.mdx) #### Source [lib/provable/foreign-field.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L51) *** ### modulus ```ts get modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L39) *** ### AlmostReduced ```ts get static AlmostReduced(): typeof AlmostForeignField ``` Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L76) *** ### Bigint ```ts get static Bigint(): {} ``` #### Returns ```ts {} ``` #### Source [lib/provable/foreign-field.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L31) *** ### Canonical ```ts get static Canonical(): typeof CanonicalForeignField ``` Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). #### Returns *typeof* [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:83](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L83) *** ### Unreduced ```ts get static Unreduced(): typeof UnreducedForeignField ``` Constructor for unreduced field elements. #### Returns *typeof* `UnreducedForeignField` #### Source [lib/provable/foreign-field.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L69) *** ### modulus ```ts get static modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L35) *** ### provable ```ts get static provable(): ProvablePureExtended ``` #### Returns `ProvablePureExtended`\<[`AlmostForeignField`](AlmostForeignField.mdx), `bigint`, `string`\> #### Source [lib/provable/foreign-field.ts:494](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L494) *** ### sizeInBits ```ts get static sizeInBits(): number ``` #### Returns `number` #### Source [lib/provable/foreign-field.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L42) ## Methods ### add() ```ts add(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field addition #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.add` #### Example ```ts x.add(2); // x + 2 mod p ``` #### Source [lib/provable/foreign-field.ts:218](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L218) *** ### assertAlmostReduced() ```ts assertAlmostReduced(): AlmostForeignField ``` Assert that this field element lies in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. Returns the field element as a [AlmostForeignField](AlmostForeignField.mdx). For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1). Note: this does not ensure that the field elements is in the canonical range [0, p). To assert that stronger property, there is [assertCanonical](ForeignField.mdx#assertcanonical). You should typically use [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for ensuring validity of all our non-native field arithmetic methods. #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:173](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L173) *** ### assertCanonical() ```ts assertCanonical(): CanonicalForeignField ``` Assert that this field element is fully reduced, i.e. lies in the range [0, p), where p is the foreign field modulus. Returns the field element as a [CanonicalForeignField](CanonicalForeignField.mdx). #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `ForeignFieldWithMul.assertCanonical` #### Source [lib/provable/foreign-field.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L204) *** ### assertEquals() #### assertEquals(y, message) ```ts assertEquals(y: number | bigint | CanonicalForeignField, message?: string): CanonicalForeignField ``` Assert equality with a ForeignField-like value ##### Parameters • **y**: `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) • **message?**: `string` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Example ```ts x.assertEquals(0, "x is zero"); ``` Since asserting equality can also serve as a range check, this method returns `x` with the appropriate type: ##### Example ```ts let xChecked = x.assertEquals(1, "x is 1"); xChecked satisfies CanonicalForeignField; ``` ##### Source [lib/provable/foreign-field.ts:296](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L296) #### assertEquals(y, message) ```ts assertEquals(y: AlmostForeignField, message?: string): AlmostForeignField ``` ##### Parameters • **y**: [`AlmostForeignField`](AlmostForeignField.mdx) • **message?**: `string` ##### Returns [`AlmostForeignField`](AlmostForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Source [lib/provable/foreign-field.ts:300](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L300) #### assertEquals(y, message) ```ts assertEquals(y: ForeignField, message?: string): ForeignField ``` ##### Parameters • **y**: [`ForeignField`](ForeignField.mdx) • **message?**: `string` ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Source [lib/provable/foreign-field.ts:301](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L301) *** ### assertLessThan() ```ts assertLessThan(c: number | bigint, message?: string): void ``` Assert that this field element is less than a constant c: `x < c`. The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. #### Parameters • **c**: `number` \| `bigint` • **message?**: `string` #### Returns `void` #### Inherited from `ForeignFieldWithMul.assertLessThan` #### Example ```ts x.assertLessThan(10); ``` #### Source [lib/provable/foreign-field.ts:339](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L339) *** ### div() ```ts div(y: number | bigint | AlmostForeignField): AlmostForeignField ``` Division in the finite field, i.e. `x*y^(-1) mod p` where `y^(-1)` is the finite field inverse. #### Parameters • **y**: `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.div` #### Example ```ts let z = x.div(y); // x/y mod p z.mul(y).assertEquals(x); ``` #### Source [lib/provable/foreign-field.ts:461](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L461) *** ### equals() ```ts equals(y: number | bigint): Bool ``` Check equality with a constant value. #### Parameters • **y**: `number` \| `bigint` #### Returns [`Bool`](Bool.mdx) #### Example ```ts let isXZero = x.equals(0); ``` #### Source [lib/provable/foreign-field.ts:521](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L521) *** ### inv() ```ts inv(): AlmostForeignField ``` Multiplicative inverse in the finite field #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.inv` #### Example ```ts let z = x.inv(); // 1/x mod p z.mul(x).assertEquals(1); ``` #### Source [lib/provable/foreign-field.ts:447](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L447) *** ### isConstant() ```ts isConstant(): boolean ``` Checks whether this field element is a constant. See FieldVar to understand constants vs variables. #### Returns `boolean` #### Inherited from `ForeignFieldWithMul.isConstant` #### Source [lib/provable/foreign-field.ts:136](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L136) *** ### mul() ```ts mul(y: number | bigint | AlmostForeignField): UnreducedForeignField ``` Finite field multiplication #### Parameters • **y**: `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.mul` #### Example ```ts x.mul(y); // x*y mod p ``` #### Source [lib/provable/foreign-field.ts:433](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L433) *** ### neg() ```ts neg(): AlmostForeignField ``` Finite field negation #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.neg` #### Example ```ts x.neg(); // -x mod p = p - x ``` #### Source [lib/provable/foreign-field.ts:229](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L229) *** ### sub() ```ts sub(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field subtraction #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.sub` #### Example ```ts x.sub(1); // x - 1 mod p ``` #### Source [lib/provable/foreign-field.ts:244](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L244) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this field element to a bigint. #### Returns `bigint` #### Inherited from `ForeignFieldWithMul.toBigInt` #### Source [lib/provable/foreign-field.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L156) *** ### toBits() ```ts toBits(length?: number): Bool[] ``` Unpack a field element to its bits, as a [Bool](Bool.mdx)[] array. This method is provable! #### Parameters • **length?**: `number` #### Returns [`Bool`](Bool.mdx)[] #### Inherited from `ForeignFieldWithMul.toBits` #### Source [lib/provable/foreign-field.ts:358](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L358) *** ### toConstant() ```ts toConstant(): ForeignField ``` Convert this field element to a constant. See FieldVar to understand constants vs variables. **Warning**: This function is only useful in Provable.witness or Provable.asProver blocks, that is, in situations where the prover computes a value outside provable code. #### Returns [`ForeignField`](ForeignField.mdx) #### Inherited from `ForeignFieldWithMul.toConstant` #### Source [lib/provable/foreign-field.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L148) *** ### toFields() ```ts toFields(): Field[] ``` Instance version of `Provable.toFields`, see Provable.toFields #### Returns [`Field`](Field.mdx)[] #### Inherited from `ForeignFieldWithMul.toFields` #### Source [lib/provable/foreign-field.ts:406](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L406) *** ### assertAlmostReduced() ```ts static assertAlmostReduced(...xs: T): [...{ [i in string | number | symbol]: AlmostForeignField }[]] ``` Assert that one or more field elements lie in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. This is most efficient than when checking a multiple of 3 field elements at once. #### Type parameters • **T** *extends* `Tuple`\<[`ForeignField`](ForeignField.mdx)\> #### Parameters • ...**xs**: `T` #### Returns [...\{ [i in string \| number \| symbol]: AlmostForeignField \}[]] #### Inherited from `ForeignFieldWithMul.assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L187) *** ### check() ```ts static check(x: ForeignField): void ``` #### Parameters • **x**: [`ForeignField`](ForeignField.mdx) #### Returns `void` #### Overrides `ForeignFieldWithMul.check` #### Source [lib/provable/foreign-field.ts:499](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L499) *** ### from() #### from(x) ```ts static from(x: string | number | bigint): CanonicalForeignField ``` Coerce the input to a [ForeignField](ForeignField.mdx). ##### Parameters • **x**: `string` \| `number` \| `bigint` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.from` ##### Source [lib/provable/foreign-field.ts:124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L124) #### from(x) ```ts static from(x: string | number | bigint | ForeignField): ForeignField ``` ##### Parameters • **x**: `string` \| `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.from` ##### Source [lib/provable/foreign-field.ts:125](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L125) *** ### fromBits() ```ts static fromBits(bits: Bool[]): AlmostForeignField ``` Create a field element from its bits, as a `Bool[]` array. This method is provable! #### Parameters • **bits**: [`Bool`](Bool.mdx)[] #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.fromBits` #### Source [lib/provable/foreign-field.ts:388](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L388) *** ### random() ```ts static random(): CanonicalForeignField ``` #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `ForeignFieldWithMul.random` #### Source [lib/provable/foreign-field.ts:399](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L399) *** ### sum() ```ts static sum(xs: (number | bigint | ForeignField)[], operations: (-1 | 1)[]): UnreducedForeignField ``` Sum (or difference) of multiple finite field elements. #### Parameters • **xs**: (`number` \| `bigint` \| [`ForeignField`](ForeignField.mdx))[] • **operations**: (`-1` \| `1`)[] #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.sum` #### Example ```ts let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 z.assertEquals(2); ``` This method expects a list of ForeignField-like values, `x0,...,xn`, and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), and returns `x0 + op1*x1 + ... + opn*xn` where the sum is computed in finite field arithmetic. **Important:** For more than two summands, this is significantly more efficient than chaining calls to [ForeignField.add](ForeignField.mdx#add) and [ForeignField.sub](ForeignField.mdx#sub). #### Source [lib/provable/foreign-field.ts:269](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L269) *** ### unsafeFrom() ```ts static unsafeFrom(x: ForeignField): AlmostForeignField ``` Coerce the input to an [AlmostForeignField](AlmostForeignField.mdx) without additional assertions. **Warning:** Only use if you know what you're doing. #### Parameters • **x**: [`ForeignField`](ForeignField.mdx) #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:509](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L509) --- url: /zkapps/o1js-reference/classes/BaseMerkleWitness --- The [BaseMerkleWitness](BaseMerkleWitness.mdx) class defines a circuit-compatible base class for [Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof). ## Extends - `CircuitValue` ## Constructors ### new BaseMerkleWitness() ```ts new BaseMerkleWitness(witness: Witness): BaseMerkleWitness ``` Takes a [Witness](../type-aliases/Witness.mdx) and turns it into a circuit-compatible Witness. #### Parameters • **witness**: [`Witness`](../type-aliases/Witness.mdx) Witness. #### Returns [`BaseMerkleWitness`](BaseMerkleWitness.mdx) A circuit-compatible Witness. #### Overrides `CircuitValue.constructor` #### Source [lib/provable/merkle-tree.ts:187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L187) ## Properties ### isLeft ```ts isLeft: Bool[]; ``` #### Source [lib/provable/merkle-tree.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L177) *** ### path ```ts path: Field[]; ``` #### Source [lib/provable/merkle-tree.ts:176](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L176) *** ### height ```ts static height: number; ``` #### Source [lib/provable/merkle-tree.ts:175](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L175) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### calculateIndex() ```ts calculateIndex(): Field ``` Calculates the index of the leaf node that belongs to this Witness. #### Returns [`Field`](Field.mdx) Index of the leaf. #### Source [lib/provable/merkle-tree.ts:221](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L221) *** ### calculateRoot() ```ts calculateRoot(leaf: Field): Field ``` Calculates a root depending on the leaf value. #### Parameters • **leaf**: [`Field`](Field.mdx) Value of the leaf node that belongs to this Witness. #### Returns [`Field`](Field.mdx) The calculated root. #### Source [lib/provable/merkle-tree.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L204) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### height() ```ts height(): number ``` #### Returns `number` #### Source [lib/provable/merkle-tree.ts:178](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L178) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### check() ```ts static check(this: T, v: InstanceType): void ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `void` #### Inherited from `CircuitValue.check` #### Source [lib/provable/types/circuit-value.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L163) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromJSON` #### Source [lib/provable/types/circuit-value.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L208) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromValue` #### Source [lib/provable/types/circuit-value.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L98) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L197) *** ### toValue() ```ts static toValue(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toValue` #### Source [lib/provable/types/circuit-value.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L89) --- url: /zkapps/o1js-reference/classes/Bool --- A boolean value. You can use it like this: ``` const x = new Bool(true); ``` You can also combine multiple booleans via [[`not`]], [[`and`]], [[`or`]]. Use [[assertEquals]] to enforce the value of a Bool. ## Constructors ### new Bool() ```ts new Bool(x: boolean | FieldVar | Bool): Bool ``` #### Parameters • **x**: `boolean` \| `FieldVar` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L33) ## Properties ### value ```ts value: FieldVar; ``` #### Source [lib/provable/bool.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L31) *** ### Unsafe ```ts static Unsafe: { "fromField": Bool; }; ``` #### fromField() Converts a [Field](Field.mdx) into a [Bool](Bool.mdx). This is an **unsafe** operation as it assumes that the field element is either 0 or 1 (which might not be true). Only use this if you have already constrained the Field element to be 0 or 1. ##### Parameters • **x**: [`Field`](Field.mdx) a [Field](Field.mdx) ##### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:373](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L373) *** ### sizeInBytes ```ts static sizeInBytes: number = 1; ``` #### Source [lib/provable/bool.ts:367](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L367) ## Methods ### and() ```ts and(y: boolean | Bool): Bool ``` #### Parameters • **y**: `boolean` \| [`Bool`](Bool.mdx) A [Bool](Bool.mdx) to AND with this [Bool](Bool.mdx). #### Returns [`Bool`](Bool.mdx) a new [Bool](Bool.mdx) that is set to true only if this [Bool](Bool.mdx) and `y` are also true. #### Source [lib/provable/bool.ts:73](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L73) *** ### assertEquals() ```ts assertEquals(y: boolean | Bool, message?: string): void ``` Proves that this [Bool](Bool.mdx) is equal to `y`. #### Parameters • **y**: `boolean` \| [`Bool`](Bool.mdx) a [Bool](Bool.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/bool.ts:114](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L114) *** ### assertFalse() ```ts assertFalse(message?: string): void ``` Proves that this [Bool](Bool.mdx) is `false`. #### Parameters • **message?**: `string` #### Returns `void` #### Source [lib/provable/bool.ts:145](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L145) *** ### assertTrue() ```ts assertTrue(message?: string): void ``` Proves that this [Bool](Bool.mdx) is `true`. #### Parameters • **message?**: `string` #### Returns `void` #### Source [lib/provable/bool.ts:131](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L131) *** ### equals() ```ts equals(y: boolean | Bool): Bool ``` Returns true if this [Bool](Bool.mdx) is equal to `y`. #### Parameters • **y**: `boolean` \| [`Bool`](Bool.mdx) a [Bool](Bool.mdx). #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:160](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L160) *** ### implies() ```ts implies(y: boolean | Bool): Bool ``` Whether this Bool implies another Bool `y`. This is the same as `x.not().or(y)`: if `x` is true, then `y` must be true for the implication to be true. #### Parameters • **y**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts let isZero = x.equals(0); let lessThan10 = x.lessThan(10); assert(isZero.implies(lessThan10), 'x = 0 implies x < 10'); ``` #### Source [lib/provable/bool.ts:106](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L106) *** ### isConstant() ```ts isConstant(): this is Object ``` #### Returns `this is Object` #### Source [lib/provable/bool.ts:45](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L45) *** ### not() ```ts not(): Bool ``` #### Returns [`Bool`](Bool.mdx) a new [Bool](Bool.mdx) that is the negation of this [Bool](Bool.mdx). #### Source [lib/provable/bool.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L59) *** ### or() ```ts or(y: boolean | Bool): Bool ``` #### Parameters • **y**: `boolean` \| [`Bool`](Bool.mdx) a [Bool](Bool.mdx) to OR with this [Bool](Bool.mdx). #### Returns [`Bool`](Bool.mdx) a new [Bool](Bool.mdx) that is set to true if either this [Bool](Bool.mdx) or `y` is true. #### Source [lib/provable/bool.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L86) *** ### sizeInFields() ```ts sizeInFields(): number ``` Returns the size of this type. #### Returns `number` #### Source [lib/provable/bool.ts:185](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L185) *** ### toBoolean() ```ts toBoolean(): boolean ``` This converts the [Bool](Bool.mdx) to a JS `boolean`. This can only be called on non-witness values. #### Returns `boolean` #### Source [lib/provable/bool.ts:216](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L216) *** ### toField() ```ts toField(): Field ``` Converts a [Bool](Bool.mdx) to a [Field](Field.mdx). `false` becomes 0 and `true` becomes 1. #### Returns [`Field`](Field.mdx) #### Source [lib/provable/bool.ts:52](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L52) *** ### toFields() ```ts toFields(): Field[] ``` Serializes this [Bool](Bool.mdx) into [Field](Field.mdx) elements. #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/bool.ts:192](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L192) *** ### toJSON() ```ts toJSON(): boolean ``` Serialize the [Bool](Bool.mdx) to a JSON string. This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Field. #### Returns `boolean` #### Source [lib/provable/bool.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L208) *** ### toString() ```ts toString(): string ``` Serialize the [Bool](Bool.mdx) to a string, e.g. for printing. This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Field. #### Returns `string` #### Source [lib/provable/bool.ts:200](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L200) *** ### and() ```ts static and(x: boolean | Bool, y: boolean | Bool): Bool ``` Boolean AND operation. #### Parameters • **x**: `boolean` \| [`Bool`](Bool.mdx) • **y**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:244](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L244) *** ### assertEqual() ```ts static assertEqual(x: Bool, y: boolean | Bool): void ``` Asserts if both [Bool](Bool.mdx) are equal. #### Parameters • **x**: [`Bool`](Bool.mdx) • **y**: `boolean` \| [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/provable/bool.ts:264](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L264) *** ### check() ```ts static check(x: Bool): void ``` #### Parameters • **x**: [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/provable/bool.ts:369](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L369) *** ### empty() ```ts static empty(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:344](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L344) *** ### equal() ```ts static equal(x: boolean | Bool, y: boolean | Bool): Bool ``` Checks two [Bool](Bool.mdx) for equality. #### Parameters • **x**: `boolean` \| [`Bool`](Bool.mdx) • **y**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:275](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L275) *** ### fromBytes() ```ts static fromBytes(bytes: number[]): Bool ``` #### Parameters • **bytes**: `number`[] #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:356](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L356) *** ### fromFields() ```ts static fromFields(fields: Field[]): Bool ``` Creates a data structure from an array of serialized [Field](Field.mdx) elements. #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:299](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L299) *** ### fromJSON() ```ts static fromJSON(b: boolean): Bool ``` Deserialize a JSON structure into a [Bool](Bool.mdx). This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Field. #### Parameters • **b**: `boolean` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:333](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L333) *** ### fromValue() ```ts static fromValue(b: boolean | Bool): Bool ``` `Provable.fromValue()` #### Parameters • **b**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:316](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L316) *** ### not() ```ts static not(x: boolean | Bool): Bool ``` Boolean negation. #### Parameters • **x**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:234](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L234) *** ### or() ```ts static or(x: boolean | Bool, y: boolean | Bool): Bool ``` Boolean OR operation. #### Parameters • **x**: `boolean` \| [`Bool`](Bool.mdx) • **y**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/bool.ts:254](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L254) *** ### readBytes() ```ts static readBytes(bytes: number[], offset: NonNegativeInteger): [Bool, number] ``` #### Type parameters • **N** *extends* `number` #### Parameters • **bytes**: `number`[] • **offset**: `NonNegativeInteger`\<`N`\> #### Returns [[`Bool`](Bool.mdx), `number`] #### Source [lib/provable/bool.ts:360](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L360) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Returns the size of this type. #### Returns `number` #### Source [lib/provable/bool.ts:340](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L340) *** ### toAuxiliary() ```ts static toAuxiliary(_?: Bool): [] ``` Static method to serialize a [Bool](Bool.mdx) into its auxiliary data. #### Parameters • **\_?**: [`Bool`](Bool.mdx) #### Returns [] #### Source [lib/provable/bool.ts:292](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L292) *** ### toBytes() ```ts static toBytes(b: Bool): number[] ``` #### Parameters • **b**: [`Bool`](Bool.mdx) #### Returns `number`[] #### Source [lib/provable/bool.ts:352](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L352) *** ### toField() ```ts static toField(x: boolean | Bool): Field ``` #### Parameters • **x**: `boolean` \| [`Bool`](Bool.mdx) #### Returns [`Field`](Field.mdx) #### Source [lib/provable/bool.ts:227](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L227) *** ### toFields() ```ts static toFields(x: Bool): Field[] ``` Static method to serialize a [Bool](Bool.mdx) into an array of [Field](Field.mdx) elements. #### Parameters • **x**: [`Bool`](Bool.mdx) #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/bool.ts:285](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L285) *** ### toInput() ```ts static toInput(x: Bool): { "packed": [Field, number][]; } ``` #### Parameters • **x**: [`Bool`](Bool.mdx) #### Returns ```ts { "packed": [Field, number][]; } ``` ##### packed ```ts packed: [Field, number][]; ``` #### Source [lib/provable/bool.ts:348](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L348) *** ### toJSON() ```ts static toJSON(x: Bool): boolean ``` Serialize a [Bool](Bool.mdx) to a JSON string. This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Field. #### Parameters • **x**: [`Bool`](Bool.mdx) #### Returns `boolean` #### Source [lib/provable/bool.ts:325](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L325) *** ### toValue() ```ts static toValue(x: Bool): boolean ``` `Provable.toValue()` #### Parameters • **x**: [`Bool`](Bool.mdx) #### Returns `boolean` #### Source [lib/provable/bool.ts:309](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L309) --- url: /zkapps/o1js-reference/classes/CanonicalForeignField --- ## Extends - `ForeignFieldWithMul` ## Constructors ### new CanonicalForeignField() ```ts new CanonicalForeignField(x: | string | number | bigint | Field3 | CanonicalForeignField): CanonicalForeignField ``` #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `Field3` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Overrides `ForeignFieldWithMul.constructor` #### Source [lib/provable/foreign-field.ts:529](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L529) ## Properties ### type ```ts type: "FullyReduced"; ``` #### Source [lib/provable/foreign-field.ts:527](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L527) *** ### value ```ts value: Field3; ``` The internal representation of a foreign field element, as a tuple of 3 limbs. #### Inherited from `ForeignFieldWithMul.value` #### Source [lib/provable/foreign-field.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L49) *** ### \_Bigint ```ts static _Bigint: undefined | {} = undefined; ``` #### Inherited from `ForeignFieldWithMul._Bigint` #### Source [lib/provable/foreign-field.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L27) *** ### \_modulus ```ts static _modulus: undefined | bigint = undefined; ``` #### Inherited from `ForeignFieldWithMul._modulus` #### Source [lib/provable/foreign-field.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L28) *** ### \_provable ```ts static _provable: undefined | ProvablePureExtended = undefined; ``` #### Overrides `ForeignFieldWithMul._provable` #### Source [lib/provable/foreign-field.ts:533](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L533) *** ### \_variants ```ts static _variants: undefined | { "almostReduced": typeof AlmostForeignField; "canonical": typeof CanonicalForeignField; "unreduced": typeof UnreducedForeignField; } = undefined; ``` Sibling classes that represent different ranges of field elements. #### Inherited from `ForeignFieldWithMul._variants` #### Source [lib/provable/foreign-field.ts:58](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L58) ## Accessors ### Constructor ```ts get Constructor(): typeof ForeignField ``` #### Returns *typeof* [`ForeignField`](ForeignField.mdx) #### Source [lib/provable/foreign-field.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L51) *** ### modulus ```ts get modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L39) *** ### AlmostReduced ```ts get static AlmostReduced(): typeof AlmostForeignField ``` Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L76) *** ### Bigint ```ts get static Bigint(): {} ``` #### Returns ```ts {} ``` #### Source [lib/provable/foreign-field.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L31) *** ### Canonical ```ts get static Canonical(): typeof CanonicalForeignField ``` Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). #### Returns *typeof* [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:83](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L83) *** ### Unreduced ```ts get static Unreduced(): typeof UnreducedForeignField ``` Constructor for unreduced field elements. #### Returns *typeof* `UnreducedForeignField` #### Source [lib/provable/foreign-field.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L69) *** ### modulus ```ts get static modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L35) *** ### provable ```ts get static provable(): ProvablePureExtended ``` #### Returns `ProvablePureExtended`\<[`CanonicalForeignField`](CanonicalForeignField.mdx), `bigint`, `string`\> #### Source [lib/provable/foreign-field.ts:536](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L536) *** ### sizeInBits ```ts get static sizeInBits(): number ``` #### Returns `number` #### Source [lib/provable/foreign-field.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L42) ## Methods ### add() ```ts add(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field addition #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.add` #### Example ```ts x.add(2); // x + 2 mod p ``` #### Source [lib/provable/foreign-field.ts:218](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L218) *** ### assertAlmostReduced() ```ts assertAlmostReduced(): AlmostForeignField ``` Assert that this field element lies in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. Returns the field element as a [AlmostForeignField](AlmostForeignField.mdx). For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1). Note: this does not ensure that the field elements is in the canonical range [0, p). To assert that stronger property, there is [assertCanonical](ForeignField.mdx#assertcanonical). You should typically use [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for ensuring validity of all our non-native field arithmetic methods. #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:173](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L173) *** ### assertCanonical() ```ts assertCanonical(): CanonicalForeignField ``` Assert that this field element is fully reduced, i.e. lies in the range [0, p), where p is the foreign field modulus. Returns the field element as a [CanonicalForeignField](CanonicalForeignField.mdx). #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `ForeignFieldWithMul.assertCanonical` #### Source [lib/provable/foreign-field.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L204) *** ### assertEquals() #### assertEquals(y, message) ```ts assertEquals(y: number | bigint | CanonicalForeignField, message?: string): CanonicalForeignField ``` Assert equality with a ForeignField-like value ##### Parameters • **y**: `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) • **message?**: `string` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Example ```ts x.assertEquals(0, "x is zero"); ``` Since asserting equality can also serve as a range check, this method returns `x` with the appropriate type: ##### Example ```ts let xChecked = x.assertEquals(1, "x is 1"); xChecked satisfies CanonicalForeignField; ``` ##### Source [lib/provable/foreign-field.ts:296](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L296) #### assertEquals(y, message) ```ts assertEquals(y: AlmostForeignField, message?: string): AlmostForeignField ``` ##### Parameters • **y**: [`AlmostForeignField`](AlmostForeignField.mdx) • **message?**: `string` ##### Returns [`AlmostForeignField`](AlmostForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Source [lib/provable/foreign-field.ts:300](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L300) #### assertEquals(y, message) ```ts assertEquals(y: ForeignField, message?: string): ForeignField ``` ##### Parameters • **y**: [`ForeignField`](ForeignField.mdx) • **message?**: `string` ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.assertEquals` ##### Source [lib/provable/foreign-field.ts:301](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L301) *** ### assertLessThan() ```ts assertLessThan(c: number | bigint, message?: string): void ``` Assert that this field element is less than a constant c: `x < c`. The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. #### Parameters • **c**: `number` \| `bigint` • **message?**: `string` #### Returns `void` #### Inherited from `ForeignFieldWithMul.assertLessThan` #### Example ```ts x.assertLessThan(10); ``` #### Source [lib/provable/foreign-field.ts:339](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L339) *** ### div() ```ts div(y: number | bigint | AlmostForeignField): AlmostForeignField ``` Division in the finite field, i.e. `x*y^(-1) mod p` where `y^(-1)` is the finite field inverse. #### Parameters • **y**: `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.div` #### Example ```ts let z = x.div(y); // x/y mod p z.mul(y).assertEquals(x); ``` #### Source [lib/provable/foreign-field.ts:461](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L461) *** ### equals() ```ts equals(y: number | bigint | CanonicalForeignField): Bool ``` Check equality with a ForeignField-like value. #### Parameters • **y**: `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts let isEqual = x.equals(y); ``` Note: This method only exists on canonical fields; on unreduced fields, it would be easy to misuse, because not being exactly equal does not imply being unequal modulo p. #### Source [lib/provable/foreign-field.ts:566](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L566) *** ### inv() ```ts inv(): AlmostForeignField ``` Multiplicative inverse in the finite field #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.inv` #### Example ```ts let z = x.inv(); // 1/x mod p z.mul(x).assertEquals(1); ``` #### Source [lib/provable/foreign-field.ts:447](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L447) *** ### isConstant() ```ts isConstant(): boolean ``` Checks whether this field element is a constant. See FieldVar to understand constants vs variables. #### Returns `boolean` #### Inherited from `ForeignFieldWithMul.isConstant` #### Source [lib/provable/foreign-field.ts:136](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L136) *** ### mul() ```ts mul(y: number | bigint | AlmostForeignField): UnreducedForeignField ``` Finite field multiplication #### Parameters • **y**: `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.mul` #### Example ```ts x.mul(y); // x*y mod p ``` #### Source [lib/provable/foreign-field.ts:433](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L433) *** ### neg() ```ts neg(): AlmostForeignField ``` Finite field negation #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.neg` #### Example ```ts x.neg(); // -x mod p = p - x ``` #### Source [lib/provable/foreign-field.ts:229](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L229) *** ### sub() ```ts sub(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field subtraction #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.sub` #### Example ```ts x.sub(1); // x - 1 mod p ``` #### Source [lib/provable/foreign-field.ts:244](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L244) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this field element to a bigint. #### Returns `bigint` #### Inherited from `ForeignFieldWithMul.toBigInt` #### Source [lib/provable/foreign-field.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L156) *** ### toBits() ```ts toBits(length?: number): Bool[] ``` Unpack a field element to its bits, as a [Bool](Bool.mdx)[] array. This method is provable! #### Parameters • **length?**: `number` #### Returns [`Bool`](Bool.mdx)[] #### Inherited from `ForeignFieldWithMul.toBits` #### Source [lib/provable/foreign-field.ts:358](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L358) *** ### toConstant() ```ts toConstant(): ForeignField ``` Convert this field element to a constant. See FieldVar to understand constants vs variables. **Warning**: This function is only useful in Provable.witness or Provable.asProver blocks, that is, in situations where the prover computes a value outside provable code. #### Returns [`ForeignField`](ForeignField.mdx) #### Inherited from `ForeignFieldWithMul.toConstant` #### Source [lib/provable/foreign-field.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L148) *** ### toFields() ```ts toFields(): Field[] ``` Instance version of `Provable.toFields`, see Provable.toFields #### Returns [`Field`](Field.mdx)[] #### Inherited from `ForeignFieldWithMul.toFields` #### Source [lib/provable/foreign-field.ts:406](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L406) *** ### assertAlmostReduced() ```ts static assertAlmostReduced(...xs: T): [...{ [i in string | number | symbol]: AlmostForeignField }[]] ``` Assert that one or more field elements lie in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. This is most efficient than when checking a multiple of 3 field elements at once. #### Type parameters • **T** *extends* `Tuple`\<[`ForeignField`](ForeignField.mdx)\> #### Parameters • ...**xs**: `T` #### Returns [...\{ [i in string \| number \| symbol]: AlmostForeignField \}[]] #### Inherited from `ForeignFieldWithMul.assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L187) *** ### check() ```ts static check(x: ForeignField): void ``` #### Parameters • **x**: [`ForeignField`](ForeignField.mdx) #### Returns `void` #### Overrides `ForeignFieldWithMul.check` #### Source [lib/provable/foreign-field.ts:541](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L541) *** ### from() #### from(x) ```ts static from(x: string | number | bigint): CanonicalForeignField ``` Coerce the input to a [ForeignField](ForeignField.mdx). ##### Parameters • **x**: `string` \| `number` \| `bigint` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.from` ##### Source [lib/provable/foreign-field.ts:124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L124) #### from(x) ```ts static from(x: string | number | bigint | ForeignField): ForeignField ``` ##### Parameters • **x**: `string` \| `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `ForeignFieldWithMul.from` ##### Source [lib/provable/foreign-field.ts:125](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L125) *** ### fromBits() ```ts static fromBits(bits: Bool[]): AlmostForeignField ``` Create a field element from its bits, as a `Bool[]` array. This method is provable! #### Parameters • **bits**: [`Bool`](Bool.mdx)[] #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `ForeignFieldWithMul.fromBits` #### Source [lib/provable/foreign-field.ts:388](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L388) *** ### random() ```ts static random(): CanonicalForeignField ``` #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `ForeignFieldWithMul.random` #### Source [lib/provable/foreign-field.ts:399](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L399) *** ### sum() ```ts static sum(xs: (number | bigint | ForeignField)[], operations: (-1 | 1)[]): UnreducedForeignField ``` Sum (or difference) of multiple finite field elements. #### Parameters • **xs**: (`number` \| `bigint` \| [`ForeignField`](ForeignField.mdx))[] • **operations**: (`-1` \| `1`)[] #### Returns `UnreducedForeignField` #### Inherited from `ForeignFieldWithMul.sum` #### Example ```ts let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 z.assertEquals(2); ``` This method expects a list of ForeignField-like values, `x0,...,xn`, and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), and returns `x0 + op1*x1 + ... + opn*xn` where the sum is computed in finite field arithmetic. **Important:** For more than two summands, this is significantly more efficient than chaining calls to [ForeignField.add](ForeignField.mdx#add) and [ForeignField.sub](ForeignField.mdx#sub). #### Source [lib/provable/foreign-field.ts:269](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L269) *** ### unsafeFrom() ```ts static unsafeFrom(x: ForeignField): CanonicalForeignField ``` Coerce the input to a [CanonicalForeignField](CanonicalForeignField.mdx) without additional assertions. **Warning:** Only use if you know what you're doing. #### Parameters • **x**: [`ForeignField`](ForeignField.mdx) #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:551](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L551) --- url: /zkapps/o1js-reference/classes/Character --- ## Extends - \{ `"value"`: `Field`; \} ## Constructors ### new Character() ```ts new Character(value: number | Field): Character ``` #### Parameters • **value**: `number` \| [`Field`](Field.mdx) #### Returns [`Character`](Character.mdx) #### Overrides `Struct({ value: Field }).constructor` #### Source [lib/provable/string.ts:13](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L13) ## Properties ### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field }).value` #### Source [lib/provable/string.ts:12](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L12) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct({ value: Field })._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### empty() ```ts static empty: () => { "value": Field; }; ``` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field }).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[]) => { "value": Field; }; ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field }).fromFields` #### Source [lib/provable/types/provable-intf.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L115) *** ### fromJSON() ```ts static fromJSON: (x: { "value": Field; }) => { "value": Field; }; ``` #### Parameters • **x** • **x.value**: `string`= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field }).fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: { "value": Field; } | { "value": Field; }) => { "value": Field; } & (value: { "value": Field; }) => { "value": Field; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct({ value: Field }).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "value": Field; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.value?**: [`Field`](Field.mdx)= `Field` #### Returns `any`[] #### Inherited from `Struct({ value: Field }).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "value": Field; }) => { "value": Field; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field }).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "value": Field; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.value**: [`Field`](Field.mdx)= `Field` #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct({ value: Field }).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toJSON() ```ts static toJSON: (x: { "value": Field; }) => { "value": Field; }; ``` #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: string = Field; ``` #### Inherited from `Struct({ value: Field }).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "value": Field; }) => { "value": Field; }; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: bigint = Field; ``` #### Inherited from `Struct({ value: Field }).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### isNull() ```ts isNull(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/string.ts:17](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L17) *** ### toField() ```ts toField(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/string.ts:21](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L21) *** ### toString() ```ts toString(): string ``` #### Returns `string` #### Source [lib/provable/string.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L25) *** ### check() ```ts static check(c: { "value": Field; }): void ``` #### Parameters • **c** • **c.value**: [`Field`](Field.mdx) #### Returns `void` #### Overrides `Struct({ value: Field }).check` #### Source [lib/provable/string.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L36) *** ### fromString() ```ts static fromString(str: string): Character ``` #### Parameters • **str**: `string` #### Returns [`Character`](Character.mdx) #### Source [lib/provable/string.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L30) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct({ value: Field }).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) *** ### toInput() ```ts static toInput(c: { "value": Field; }): HashInput ``` #### Parameters • **c** • **c.value**: [`Field`](Field.mdx) #### Returns `HashInput` #### Overrides `Struct({ value: Field }).toInput` #### Source [lib/provable/string.ts:40](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L40) --- url: /zkapps/o1js-reference/classes/Circuit --- ## Constructors ### new Circuit() ```ts new Circuit(): Circuit ``` #### Returns [`Circuit`](Circuit.mdx) ## Properties ### \_main ```ts static _main: CircuitData; ``` #### Source [lib/proof-system/circuit.ts:22](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L22) ## Methods ### generateKeypair() ```ts static generateKeypair(): Promise ``` Generates a proving key and a verification key for this circuit. #### Returns `Promise`\<[`Keypair`](Keypair.mdx)\> #### Example ```ts const keypair = await MyCircuit.generateKeypair(); ``` #### Source [lib/proof-system/circuit.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L31) *** ### prove() ```ts static prove( privateInput: any[], publicInput: any[], keypair: Keypair): Promise ``` Proves a statement using the private input, public input, and the [Keypair](Keypair.mdx) of the circuit. #### Parameters • **privateInput**: `any`[] • **publicInput**: `any`[] • **keypair**: [`Keypair`](Keypair.mdx) #### Returns `Promise`\<`Proof`\> #### Example ```ts const keypair = await MyCircuit.generateKeypair(); const proof = await MyCircuit.prove(privateInput, publicInput, keypair); ``` #### Source [lib/proof-system/circuit.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L51) *** ### verify() ```ts static verify( publicInput: any[], verificationKey: VerificationKey, proof: Proof): Promise ``` Verifies a proof using the public input, the proof, and the initial [Keypair](Keypair.mdx) of the circuit. #### Parameters • **publicInput**: `any`[] • **verificationKey**: `VerificationKey` • **proof**: `Proof` #### Returns `Promise`\<`boolean`\> #### Example ```ts const keypair = await MyCircuit.generateKeypair(); const proof = await MyCircuit.prove(privateInput, publicInput, keypair); const isValid = await MyCircuit.verify(publicInput, keypair.vk, proof); ``` #### Source [lib/proof-system/circuit.ts:82](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L82) --- url: /zkapps/o1js-reference/classes/CircuitString --- ## Extends - \{ `"values"`: [`Character`](Character.mdx)[]; \} ## Constructors ### new CircuitString() ```ts new CircuitString(value: { "values": Character[]; }): CircuitString ``` #### Parameters • **value** • **value.values**: [`Character`](Character.mdx)[] #### Returns [`CircuitString`](CircuitString.mdx) #### Inherited from `Struct(RawCircuitString).constructor` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) ## Properties ### values ```ts values: Character[]; ``` #### Inherited from `Struct(RawCircuitString).values` #### Source [lib/provable/string.ts:65](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L65) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct(RawCircuitString)._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### check() ```ts static check: (value: { "values": Character[]; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.values**: [`Character`](Character.mdx)[] #### Returns `void` #### Inherited from `Struct(RawCircuitString).check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### empty() ```ts static empty: () => { "values": Character[]; }; ``` #### Returns ```ts { "values": Character[]; } ``` ##### values ```ts values: Character[]; ``` #### Inherited from `Struct(RawCircuitString).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[]) => { "values": Character[]; }; ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns ```ts { "values": Character[]; } ``` ##### values ```ts values: Character[]; ``` #### Inherited from `Struct(RawCircuitString).fromFields` #### Source [lib/provable/types/provable-intf.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L115) *** ### fromJSON() ```ts static fromJSON: (x: { "values": { "value": Field; }[]; }) => { "values": Character[]; }; ``` #### Parameters • **x** • **x.values**: \{ `"value"`: `Field`; \}[]= `undefined` #### Returns ```ts { "values": Character[]; } ``` ##### values ```ts values: Character[]; ``` #### Inherited from `Struct(RawCircuitString).fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: string | { "values": Character[]; }) => { "values": Character[]; } & (value: string | { "values": Character[]; }) => { "values": Character[]; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct(RawCircuitString).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### maxLength ```ts static maxLength: number = DEFAULT_STRING_LENGTH; ``` #### Source [lib/provable/string.ts:72](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L72) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "values": Character[]; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.values?**: [`Character`](Character.mdx)[] #### Returns `any`[] #### Inherited from `Struct(RawCircuitString).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "values": Character[]; }) => { "values": Character[]; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.values**: [`Character`](Character.mdx)[] #### Returns ```ts { "values": Character[]; } ``` ##### values ```ts values: Character[]; ``` #### Inherited from `Struct(RawCircuitString).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "values": Character[]; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.values**: [`Character`](Character.mdx)[] #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct(RawCircuitString).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "values": Character[]; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.values**: [`Character`](Character.mdx)[] #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `Struct(RawCircuitString).toInput` #### Source [lib/provable/types/struct.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L152) *** ### toJSON() ```ts static toJSON: (x: { "values": Character[]; }) => { "values": { "value": Field; }[]; }; ``` #### Parameters • **x** • **x.values**: [`Character`](Character.mdx)[] #### Returns ```ts { "values": { "value": Field; }[]; } ``` ##### values ```ts values: { "value": Field; }[]; ``` #### Inherited from `Struct(RawCircuitString).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "values": Character[]; }) => string; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.values**: [`Character`](Character.mdx)[] #### Returns `string` #### Inherited from `Struct(RawCircuitString).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### append() ```ts append(str: CircuitString): CircuitString ``` appends another string to this one, returns the result and proves that it fits within the `maxLength` of this string (the other string can have a different maxLength) #### Parameters • **str**: [`CircuitString`](CircuitString.mdx) #### Returns [`CircuitString`](CircuitString.mdx) #### Source [lib/provable/string.ts:121](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L121) *** ### computeLengthAndMask() ```ts computeLengthAndMask(): { "length": Field; "mask": Bool[]; } ``` #### Returns ```ts { "length": Field; "mask": Bool[]; } ``` ##### length ```ts length: Field; ``` ##### mask ```ts mask: Bool[]; ``` #### Source [lib/provable/string.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L84) *** ### equals() ```ts equals(other: CircuitString): Bool ``` returns true if `this` has the same value as `other` #### Parameters • **other**: [`CircuitString`](CircuitString.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/string.ts:113](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L113) *** ### hash() ```ts hash(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/string.ts:147](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L147) *** ### length() ```ts length(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/string.ts:106](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L106) *** ### lengthMask() ```ts lengthMask(): Bool[] ``` #### Returns [`Bool`](Bool.mdx)[] #### Source [lib/provable/string.ts:103](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L103) *** ### maxLength() ```ts maxLength(): number ``` #### Returns `number` #### Source [lib/provable/string.ts:79](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L79) *** ### substring() ```ts substring(start: number, end: number): CircuitString ``` #### Parameters • **start**: `number` • **end**: `number` #### Returns [`CircuitString`](CircuitString.mdx) #### Source [lib/provable/string.ts:151](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L151) *** ### toString() ```ts toString(): string ``` #### Returns `string` #### Source [lib/provable/string.ts:155](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L155) *** ### fromCharacters() ```ts static fromCharacters(chars: Character[]): CircuitString ``` #### Parameters • **chars**: [`Character`](Character.mdx)[] #### Returns [`CircuitString`](CircuitString.mdx) #### Source [lib/provable/string.ts:75](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L75) *** ### fromString() ```ts static fromString(str: string): CircuitString ``` #### Parameters • **str**: `string` #### Returns [`CircuitString`](CircuitString.mdx) #### Source [lib/provable/string.ts:159](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/string.ts#L159) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct(RawCircuitString).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/classes/DynamicProof --- The `DynamicProof` class enables circuits to verify proofs using in-ciruit verfication keys. This is opposed to the baked-in verification keys of the `Proof` class. In order to use this, a subclass of DynamicProof that specifies the public input and output types along with the maxProofsVerified number has to be created. ```ts export class SideloadedProgramProof extends DynamicProof { static publicInputType = MyStruct; static publicOutputType = Field; static maxProofsVerified = 0 as const; } ``` The `maxProofsVerified` constant is a product of the child circuit and indicates the maximum number that that circuit verifies itself. If you are unsure about what that is for you, you should use `2`. Any `DynamicProof` subclass can be used as private input to ZkPrograms or SmartContracts along with a `VerificationKey` input. ```ts proof.verify(verificationKey) ``` NOTE: In the case of `DynamicProof`s, the circuit makes no assertions about the verificationKey used on its own. This is the responsibility of the application developer and should always implement appropriate checks. This pattern differs a lot from the usage of normal `Proof`, where the verification key is baked into the compiled circuit. ## See src/examples/zkprogram/dynamic-keys-merkletree.ts for an example of how this can be done using merkle trees Assertions generally only happen using the vk hash that is part of the `VerificationKey` struct along with the raw vk data as auxiliary data. When using verify() on a `DynamicProof`, Pickles makes sure that the verification key data matches the hash. Therefore all manual assertions have to be made on the vk's hash and it can be assumed that the vk's data is checked to match the hash if it is used with verify(). ## Extends - [`ProofBase`](ProofBase.mdx)\<`Input`, `Output`\> ## Type parameters • **Input** • **Output** ## Constructors ### new DynamicProof() ```ts new DynamicProof(__namedParameters: { "maxProofsVerified": 0 | 1 | 2; "proof": unknown; "publicInput": Input; "publicOutput": Output; }): DynamicProof ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.maxProofsVerified**: `0` \| `1` \| `2` • **\_\_namedParameters.proof**: `unknown` • **\_\_namedParameters.publicInput**: `Input` • **\_\_namedParameters.publicOutput**: `Output` #### Returns [`DynamicProof`](DynamicProof.mdx)\<`Input`, `Output`\> #### Inherited from [`ProofBase`](ProofBase.mdx).[`constructor`](ProofBase.mdx#constructors) #### Source [lib/proof-system/proof.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L49) ## Properties ### maxProofsVerified ```ts maxProofsVerified: 0 | 1 | 2; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`maxProofsVerified`](ProofBase.mdx#maxproofsverified) #### Source [lib/proof-system/proof.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L36) *** ### proof ```ts proof: unknown; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`proof`](ProofBase.mdx#proof) #### Source [lib/proof-system/proof.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L35) *** ### publicInput ```ts publicInput: Input; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicInput`](ProofBase.mdx#publicinput) #### Source [lib/proof-system/proof.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L33) *** ### publicOutput ```ts publicOutput: Output; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicOutput`](ProofBase.mdx#publicoutput) #### Source [lib/proof-system/proof.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L34) *** ### shouldVerify ```ts shouldVerify: Bool; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`shouldVerify`](ProofBase.mdx#shouldverify) #### Source [lib/proof-system/proof.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L37) *** ### usedVerificationKey? ```ts optional usedVerificationKey: VerificationKey; ``` #### Source [lib/proof-system/proof.ts:235](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L235) *** ### featureFlags ```ts static featureFlags: FeatureFlags = FeatureFlags.allNone; ``` As the name indicates, feature flags are features of the proof system. If we want to side load proofs and verification keys, we first have to tell Pickles what _shape_ of proofs it should expect. For example, if we want to side load proofs that use foreign field arithmetic custom gates, we have to make Pickles aware of that by defining these custom gates. _Note:_ Only proofs that use the exact same composition of custom gates which were expected by Pickles can be verified using side loading. If you want to verify _any_ proof, no matter what custom gates it uses, you can use FeatureFlags.allMaybe. Please note that this might incur a significant overhead. You can also toggle specific feature flags manually by specifying them here. Alternatively, you can use FeatureFlags.fromZkProgram to compute the set of feature flags that are compatible with a given program. #### Source [lib/proof-system/proof.ts:222](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L222) *** ### maxProofsVerified ```ts static maxProofsVerified: 0 | 1 | 2; ``` #### Source [lib/proof-system/proof.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L204) *** ### publicInputType ```ts static publicInputType: FlexibleProvablePure; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicInputType`](ProofBase.mdx#publicinputtype) #### Source [lib/proof-system/proof.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L25) *** ### publicOutputType ```ts static publicOutputType: FlexibleProvablePure; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicOutputType`](ProofBase.mdx#publicoutputtype) #### Source [lib/proof-system/proof.ts:26](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L26) ## Accessors ### provable ```ts get static provable(): ProvableProof, any, any> ``` #### Returns `ProvableProof`\<[`DynamicProof`](DynamicProof.mdx)\<`any`, `any`\>, `any`, `any`\> #### Source [lib/proof-system/proof.ts:309](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L309) ## Methods ### publicFields() ```ts publicFields(): { "input": Field[]; "output": Field[]; } ``` #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicFields`](ProofBase.mdx#publicfields) #### Source [lib/proof-system/proof.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L92) *** ### toJSON() ```ts toJSON(): JsonProof ``` #### Returns [`JsonProof`](../type-aliases/JsonProof.mdx) #### Inherited from [`ProofBase`](ProofBase.mdx).[`toJSON`](ProofBase.mdx#tojson) #### Source [lib/proof-system/proof.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L39) *** ### verify() ```ts verify(vk: VerificationKey): void ``` Verifies this DynamicProof using a given verification key #### Parameters • **vk**: [`VerificationKey`](VerificationKey.mdx) The verification key this proof will be verified against #### Returns `void` #### Source [lib/proof-system/proof.ts:241](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L241) *** ### verifyIf() ```ts verifyIf(vk: VerificationKey, condition: Bool): void ``` #### Parameters • **vk**: [`VerificationKey`](VerificationKey.mdx) • **condition**: [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/proof-system/proof.ts:245](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L245) *** ### dummy() ```ts static dummy( this: S, publicInput: InferProvable, publicOutput: InferProvable, maxProofsVerified: 0 | 1 | 2, domainLog2: number): Promise> ``` #### Type parameters • **S** *extends* `Subclass`\<*typeof* [`DynamicProof`](DynamicProof.mdx)\> #### Parameters • **this**: `S` • **publicInput**: [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicInputType"`\]\> • **publicOutput**: [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicOutputType"`\]\> • **maxProofsVerified**: `0` \| `1` \| `2` • **domainLog2**: `number`= `14` #### Returns `Promise`\<`InstanceType`\<`S`\>\> #### Source [lib/proof-system/proof.ts:274](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L274) *** ### fromJSON() ```ts static fromJSON(this: S, __namedParameters: JsonProof): Promise, InferProvable>> ``` #### Type parameters • **S** *extends* `Subclass`\<*typeof* [`DynamicProof`](DynamicProof.mdx)\> #### Parameters • **this**: `S` • **\_\_namedParameters**: [`JsonProof`](../type-aliases/JsonProof.mdx) #### Returns `Promise`\<[`DynamicProof`](DynamicProof.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicInputType"`\]\>, [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicOutputType"`\]\>\>\> #### Source [lib/proof-system/proof.ts:250](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L250) *** ### fromProof() ```ts static fromProof(this: S, proof: Proof, InferProvable>): InstanceType ``` Converts a Proof into a DynamicProof carrying over all relevant data. This method can be used to convert a Proof computed by a ZkProgram into a DynamicProof that is accepted in a circuit that accepts DynamicProofs #### Type parameters • **S** *extends* `Subclass`\<*typeof* [`DynamicProof`](DynamicProof.mdx)\> #### Parameters • **this**: `S` • **proof**: [`Proof`](Proof.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicInputType"`\]\>, [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicOutputType"`\]\>\> #### Returns `InstanceType`\<`S`\> #### Source [lib/proof-system/proof.ts:294](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L294) *** ### publicFields() ```ts static publicFields(value: ProofBase): { "input": Field[]; "output": Field[]; } ``` #### Parameters • **value**: [`ProofBase`](ProofBase.mdx)\<`any`, `any`\> #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicFields`](ProofBase.mdx#publicfields-1) #### Source [lib/proof-system/proof.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L84) *** ### tag() ```ts static tag(): { "name": string; } ``` #### Returns ```ts { "name": string; } ``` ##### name ```ts name: string; ``` #### Overrides `ProofBase.tag` #### Source [lib/proof-system/proof.ts:224](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L224) --- url: /zkapps/o1js-reference/classes/EcdsaSignature --- ## Constructors ### new EcdsaSignature() ```ts new EcdsaSignature(signature: { "r": number | bigint | Field3 | AlmostForeignField; "s": number | bigint | Field3 | AlmostForeignField; }): EcdsaSignature ``` Create a new [EcdsaSignature](EcdsaSignature.mdx) from an object containing the scalars r and s. Note: Inputs must be range checked if they originate from a different field with a different modulus or if they are not constants. Please refer to the [ForeignField](ForeignField.mdx) constructor comments for more details. #### Parameters • **signature** • **signature.r**: `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.mdx) • **signature.s**: `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L39) ## Properties ### r ```ts r: AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L31) *** ### s ```ts s: AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L32) *** ### \_Curve? ```ts static optional _Curve: typeof ForeignCurve; ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:220](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L220) *** ### \_provable? ```ts static optional _provable: ProvablePureExtended; ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:221](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L221) ## Accessors ### Constructor ```ts get Constructor(): typeof EcdsaSignature ``` #### Returns *typeof* [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:217](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L217) *** ### Curve ```ts get static Curve(): typeof ForeignCurve ``` The [ForeignCurve](ForeignCurve.mdx) on which the ECDSA signature is defined. #### Returns *typeof* [`ForeignCurve`](ForeignCurve.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L230) *** ### provable ```ts get static provable(): ProvablePureExtended ``` `Provable` #### Returns `ProvablePureExtended`\<[`EcdsaSignature`](EcdsaSignature.mdx), \{ `"r"`: `bigint`; `"s"`: `bigint`; \}, \{ `"r"`: `string`; `"s"`: `string`; \}\> #### Source [lib/provable/crypto/foreign-ecdsa.ts:237](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L237) ## Methods ### toBigInt() ```ts toBigInt(): { "r": bigint; "s": bigint; } ``` Convert this signature to an object with bigint fields. #### Returns ```ts { "r": bigint; "s": bigint; } ``` ##### r ```ts r: bigint; ``` ##### s ```ts s: bigint; ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:67](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L67) *** ### verify() ```ts verify(message: Bytes, publicKey: FlexiblePoint): Bool ``` Verify the ECDSA signature given the message (an array of bytes) and public key (a [Curve](EcdsaSignature.mdx#curve) point). **Important:** This method returns a [Bool](Bool.mdx) which indicates whether the signature is valid. So, to actually prove validity of a signature, you need to assert that the result is true. #### Parameters • **message**: `Bytes` • **publicKey**: `FlexiblePoint` #### Returns [`Bool`](Bool.mdx) #### Throws if one of the signature scalars is zero or if the public key is not on the curve. #### Example ```ts // create classes for your curve class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} class Scalar extends Secp256k1.Scalar {} class Ecdsa extends createEcdsa(Secp256k1) {} let message = 'my message'; let messageBytes = new TextEncoder().encode(message); // outside provable code: create inputs let privateKey = Scalar.random(); let publicKey = Secp256k1.generator.scale(privateKey); let signature = Ecdsa.sign(messageBytes, privateKey.toBigInt()); // ... // in provable code: create input witnesses (or use method inputs, or constants) let pk = Provable.witness(Secp256k1, () => publicKey); let msg = Provable.witness(Provable.Array(Field, 9), () => messageBytes.map(Field)); let sig = Provable.witness(Ecdsa, () => signature); // verify signature let isValid = sig.verify(msg, pk); isValid.assertTrue('signature verifies'); ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L105) *** ### verifyEthers() ```ts verifyEthers(message: Bytes, publicKey: FlexiblePoint): Bool ``` Verify an ECDSA signature generated by the ethers.js library, given the message (as a byte array) and a public key (a [Curve](EcdsaSignature.mdx#curve) point). The message digest used for signing follows the format defined in EIP-191, with the Ethereum-specific prefix. **Important:** This method returns a [Bool](Bool.mdx) which indicates whether the signature is valid. So, to actually prove validity of a signature, you need to assert that the result is true. **Note:** This method is specifically designed to verify signatures generated by ethers.js. Ensure that the curve being used is Secp256k1, as demonstrated in the example. #### Parameters • **message**: `Bytes` The original message as a byte array. • **publicKey**: `FlexiblePoint` The public key as a point on the Secp256k1 elliptic curve. #### Returns [`Bool`](Bool.mdx) - A [Bool](Bool.mdx) indicating the validity of the signature. #### Throws An error will be thrown if one of the signature scalars is zero or if the public key does not lie on the curve. #### Example ```ts // create the class for Secp256k1 curve class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} class Ecdsa extends createEcdsa(Secp256k1) {} // outside provable code: create inputs let message = 'my message'; let signatureRaw = await wallet.signMessage(message); let compressedPublicKey = wallet.signingKey.compressedPublicKey; // this also works for uncompressed public keys (wallet.signingKey.publicKey) let publicKey = Secp256k1.fromEthers(compressedPublicKey.slice(2)); let signature = Ecdsa.fromHex(signatureRaw); // ... // in provable code: create input witnesses (or use method inputs, or constants) // and verify the signature let isValid = signature.verifyEthers(Bytes.fromString(message), publicKey); isValid.assertTrue('signature verifies'); ``` #### Source [lib/provable/crypto/foreign-ecdsa.ts:151](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L151) *** ### verifySignedHash() ```ts verifySignedHash(msgHash: bigint | AlmostForeignField, publicKey: FlexiblePoint): Bool ``` Verify the ECDSA signature given the message hash (a [Scalar](Scalar.mdx)) and public key (a [Curve](EcdsaSignature.mdx#curve) point). This is a building block of [EcdsaSignature.verify](EcdsaSignature.mdx#verify), where the input message is also hashed. In contrast, this method just takes the message hash (a curve scalar) as input, giving you flexibility in choosing the hashing algorithm. #### Parameters • **msgHash**: `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) • **publicKey**: `FlexiblePoint` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:170](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L170) *** ### check() ```ts static check(signature: EcdsaSignature): void ``` #### Parameters • **signature**: [`EcdsaSignature`](EcdsaSignature.mdx) #### Returns `void` #### Source [lib/provable/crypto/foreign-ecdsa.ts:209](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L209) *** ### from() ```ts static from(signature: FlexibleSignature): EcdsaSignature ``` Coerce the input to a [EcdsaSignature](EcdsaSignature.mdx). #### Parameters • **signature**: `FlexibleSignature` #### Returns [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:50](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L50) *** ### fromHex() ```ts static fromHex(rawSignature: string): EcdsaSignature ``` Create an [EcdsaSignature](EcdsaSignature.mdx) from a raw 130-char hex string as used in [Ethereum transactions](https://ethereum.org/en/developers/docs/transactions/#typed-transaction-envelope). #### Parameters • **rawSignature**: `string` #### Returns [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L59) *** ### sign() ```ts static sign(message: Uint8Array | (number | bigint)[], privateKey: bigint): EcdsaSignature ``` Create an [EcdsaSignature](EcdsaSignature.mdx) by signing a message with a private key. Note: This method is not provable, and only takes JS bigints as input. #### Parameters • **message**: `Uint8Array` \| (`number` \| `bigint`)[] • **privateKey**: `bigint` #### Returns [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L189) *** ### signHash() ```ts static signHash(msgHash: bigint, privateKey: bigint): EcdsaSignature ``` Create an [EcdsaSignature](EcdsaSignature.mdx) by signing a message hash with a private key. This is a building block of [EcdsaSignature.sign](EcdsaSignature.mdx#sign), where the input message is also hashed. In contrast, this method just takes the message hash (a curve scalar) as input, giving you flexibility in choosing the hashing algorithm. Note: This method is not provable, and only takes JS bigints as input. #### Parameters • **msgHash**: `bigint` • **privateKey**: `bigint` #### Returns [`EcdsaSignature`](EcdsaSignature.mdx) #### Source [lib/provable/crypto/foreign-ecdsa.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L204) --- url: /zkapps/o1js-reference/classes/Field --- A [Field](Field.mdx) is an element of a prime order [finite field](https://en.wikipedia.org/wiki/Finite_field). Every other provable type is built using the [Field](Field.mdx) type. The field is the [pasta base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) of order 2^254 + 0x224698fc094cf91b992d30ed00000001 ([Field.ORDER](Field.mdx#order)). You can create a new Field from everything "field-like" (`bigint`, integer `number`, decimal `string`, `Field`). ## Example ``` Field(10n); // Field construction from a big integer Field(100); // Field construction from a number Field("1"); // Field construction from a decimal string ``` **Beware**: Fields _cannot_ be constructed from fractional numbers or alphanumeric strings: ```ts Field(3.141); // ERROR: Cannot convert a float to a field element Field("abc"); // ERROR: Invalid argument "abc" ``` Creating a Field from a negative number can result in unexpected behavior if you are not familiar with [modular arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic). ## Example ``` const x = Field(-1); // Valid Field construction from negative number const y = Field(Field.ORDER - 1n); // equivalent to `x` ``` **Important**: All the functions defined on a Field (arithmetic, logic, etc.) take their arguments as "field-like". A Field itself is also defined as a "field-like" element. ## Param the value to convert to a [Field](Field.mdx) ## Constructors ### new Field() ```ts new Field(x: | string | number | bigint | FieldConst | FieldVar | Field): Field ``` Coerce anything "field-like" (bigint, number, string, and [Field](Field.mdx)) to a Field. #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `FieldConst` \| `FieldVar` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) #### Source [lib/provable/field.ts:97](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L97) ## Properties ### value ```ts value: FieldVar; ``` #### Source [lib/provable/field.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L86) *** ### ORDER ```ts static ORDER: bigint = Fp.modulus; ``` The order of the pasta curve that [Field](Field.mdx) type build on as a `bigint`. Order of the [Field](Field.mdx) is 28948022309329048855892746252171976963363056481941560715954676764349967630337. #### Source [lib/provable/field.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L92) *** ### sizeInBits ```ts static sizeInBits: number = Fp.sizeInBits; ``` The size of a [Field](Field.mdx) element in bits - 255. #### Source [lib/provable/field.ts:1127](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1127) *** ### sizeInBytes ```ts static sizeInBytes: number = BinableFp.sizeInBytes; ``` The size of a [Field](Field.mdx) element in bytes - 32. #### Source [lib/provable/field.ts:1122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1122) ## Methods ### add() ```ts add(y: string | number | bigint | Field): Field ``` Add a field-like value to this [Field](Field.mdx) element. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the modular addition of the two value. #### Example ```ts const x = Field(3); const sum = x.add(5); sum.assertEquals(Field(8)); ``` **Warning**: This is a modular addition in the pasta field. #### Example ```ts const x = Field(1); const sum = x.add(Field(-7)); // If you try to print sum - `console.log(sum.toBigInt())` - you will realize that it prints a very big integer because this is modular arithmetic, and 1 + (-7) circles around the field to become p - 6. // You can use the reverse operation of addition (subtraction) to prove the sum is calculated correctly. sum.sub(x).assertEquals(Field(-7)); sum.sub(Field(-7)).assertEquals(x); ``` #### Source [lib/provable/field.ts:250](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L250) *** ### assertBool() ```ts assertBool(message?: string): Bool ``` Prove that this [Field](Field.mdx) is equal to 0 or 1. Returns the Field wrapped in a [Bool](Bool.mdx). If the assertion fails, the code throws an error. #### Parameters • **message?**: `string` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/field.ts:780](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L780) *** ### assertEquals() ```ts assertEquals(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) is equal another "field-like" value. Calling this function is equivalent to `Field(...).equals(...).assertEquals(Bool(true))`. See [Field.equals](Field.mdx#equals) for more details. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/field.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L208) *** ### assertGreaterThan() ```ts assertGreaterThan(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) is greater than another "field-like" value. Note: This uses fewer constraints than `x.greaterThan(y).assertTrue()`. See [Field.greaterThan](Field.mdx#greaterthan) for more details. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/field.ts:714](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L714) *** ### assertGreaterThanOrEqual() ```ts assertGreaterThanOrEqual(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) is greater than or equal to another "field-like" value. Note: This uses fewer constraints than `x.greaterThanOrEqual(y).assertTrue()`. See [Field.greaterThanOrEqual](Field.mdx#greaterthanorequal) for more details. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/field.ts:729](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L729) *** ### assertLessThan() ```ts assertLessThan(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) is less than another "field-like" value. Note: This uses fewer constraints than `x.lessThan(y).assertTrue()`. See [lessThan](Field.mdx#lessthan) for more details. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/field.ts:664](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L664) *** ### assertLessThanOrEqual() ```ts assertLessThanOrEqual(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) is less than or equal to another "field-like" value. Note: This uses fewer constraints than `x.lessThanOrEqual(y).assertTrue()`. See [Field.lessThanOrEqual](Field.mdx#lessthanorequal) for more details. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/field.ts:689](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L689) *** ### assertNotEquals() ```ts assertNotEquals(y: string | number | bigint | Field, message?: string): void ``` Assert that this [Field](Field.mdx) does not equal another field-like value. Note: This uses fewer constraints than `x.equals(y).assertFalse()`. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) • **message?**: `string` #### Returns `void` #### Example ```ts x.assertNotEquals(0, "expect x to be non-zero"); ``` #### Source [lib/provable/field.ts:746](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L746) *** ### div() ```ts div(y: string | number | bigint | Field): Field ``` Divide another "field-like" value through this [Field](Field.mdx). Proves that the denominator is non-zero, or throws a "Division by zero" error. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the modular division of the two value. #### Example ```ts const x = Field(6); const quotient = x.div(Field(3)); quotient.assertEquals(Field(2)); ``` **Warning**: This is a modular division in the pasta field. You can think this as the reverse operation of modular multiplication. #### Example ```ts const x = Field(2); const y = Field(5); const quotient = x.div(y); // If you try to print quotient - `console.log(quotient.toBigInt())` - you will realize that it prints a very big integer because this is a modular inverse. // You can use the reverse operation of division (multiplication) to prove the quotient is calculated correctly. quotient.mul(y).assertEquals(x); ``` #### Source [lib/provable/field.ts:442](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L442) *** ### equals() ```ts equals(y: string | number | bigint | Field): Bool ``` Check if this [Field](Field.mdx) is equal another "field-like" value. Returns a [Bool](Bool.mdx), which is a provable type and can be used to prove the validity of this statement. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) A [Bool](Bool.mdx) representing if this [Field](Field.mdx) is equal another "field-like" value. #### Example ```ts Field(5).equals(5).assertEquals(Bool(true)); ``` #### Source [lib/provable/field.ts:522](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L522) *** ### greaterThan() ```ts greaterThan(y: string | number | bigint | Field): Bool ``` Check if this [Field](Field.mdx) is greater than another "field-like" value. Returns a [Bool](Bool.mdx), which is a provable type and can be used to prove the validity of this statement. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) A [Bool](Bool.mdx) representing if this [Field](Field.mdx) is greater than another "field-like" value. #### Example ```ts let isTrue = Field(5).greaterThan(3); ``` **Warning**: As this method compares the bigint value of a [Field](Field.mdx), it can result in unexpected behaviour when used with negative inputs or modular division. #### Example ```ts let isFalse = Field(1).div(2).greaterThan(Field(1).div(3); // in fact, 1/3 > 1/2 ``` #### Source [lib/provable/field.ts:625](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L625) *** ### greaterThanOrEqual() ```ts greaterThanOrEqual(y: string | number | bigint | Field): Bool ``` Check if this [Field](Field.mdx) is greater than or equal another "field-like" value. Returns a [Bool](Bool.mdx), which is a provable type and can be used to prove the validity of this statement. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) A [Bool](Bool.mdx) representing if this [Field](Field.mdx) is greater than or equal another "field-like" value. #### Example ```ts let isTrue = Field(3).greaterThanOrEqual(3); ``` **Warning**: As this method compares the bigint value of a [Field](Field.mdx), it can result in unexpected behaviour when used with negative inputs or modular division. #### Example ```ts let isFalse = Field(1).div(2).greaterThanOrEqual(Field(1).div(3); // in fact, 1/3 > 1/2 ``` #### Source [lib/provable/field.ts:649](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L649) *** ### inv() ```ts inv(): Field ``` [Modular inverse](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse) of this [Field](Field.mdx) element. Equivalent to 1 divided by this [Field](Field.mdx), in the sense of modular arithmetic. Proves that this Field is non-zero, or throws a "Division by zero" error. #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element that is equivalent to one divided by this element. #### Example ```ts const someField = Field(42); const inverse = someField.inv(); inverse.assertEquals(Field(1).div(someField)); // This statement is always true regardless of the value of `someField` ``` **Warning**: This is a modular inverse. See [div](Field.mdx#div) method for more details. #### Source [lib/provable/field.ts:396](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L396) *** ### isConstant() ```ts isConstant(): this is Object ``` Check whether this [Field](Field.mdx) element is a hard-coded constant in the constraint system. If a [Field](Field.mdx) is constructed outside a zkApp method, it is a constant. #### Returns `this is Object` A `boolean` showing if this [Field](Field.mdx) is a constant or not. #### Example ```ts console.log(Field(42).isConstant()); // true ``` #### Example ```ts \@method myMethod(x: Field) { console.log(x.isConstant()); // false } ``` #### Source [lib/provable/field.ts:142](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L142) *** ### isEven() ```ts isEven(): Bool ``` Checks if this [Field](Field.mdx) is even. Returns `true` for even elements and `false` for odd elements. #### Returns [`Bool`](Bool.mdx) #### Example ```ts let a = Field(5); a.isEven(); // false let b = Field(4); b.isEven(); // true ``` #### Source [lib/provable/field.ts:339](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L339) *** ### isOdd() ```ts isOdd(): Bool ``` Checks if this [Field](Field.mdx) is odd. Returns `true` for odd elements and `false` for even elements. See [Field.isEven](Field.mdx#iseven) for examples. #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/field.ts:323](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L323) *** ### lessThan() ```ts lessThan(y: string | number | bigint | Field): Bool ``` Check if this [Field](Field.mdx) is less than another "field-like" value. Returns a [Bool](Bool.mdx), which is a provable type and can be used prove to the validity of this statement. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) A [Bool](Bool.mdx) representing if this [Field](Field.mdx) is less than another "field-like" value. #### Example ```ts let isTrue = Field(2).lessThan(3); ``` **Warning**: As this method compares the bigint value of a [Field](Field.mdx), it can result in unexpected behavior when used with negative inputs or modular division. #### Example ```ts let isFalse = Field(1).div(3).lessThan(Field(1).div(2)); // in fact, 1/3 > 1/2 ``` #### Source [lib/provable/field.ts:571](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L571) *** ### lessThanOrEqual() ```ts lessThanOrEqual(y: string | number | bigint | Field): Bool ``` Check if this [Field](Field.mdx) is less than or equal to another "field-like" value. Returns a [Bool](Bool.mdx), which is a provable type and can be used to prove the validity of this statement. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) A [Bool](Bool.mdx) representing if this [Field](Field.mdx) is less than or equal another "field-like" value. #### Example ```ts let isTrue = Field(3).lessThanOrEqual(3); ``` **Warning**: As this method compares the bigint value of a [Field](Field.mdx), it can result in unexpected behaviour when used with negative inputs or modular division. #### Example ```ts let isFalse = Field(1).div(3).lessThanOrEqual(Field(1).div(2)); // in fact, 1/3 > 1/2 ``` #### Source [lib/provable/field.ts:598](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L598) *** ### mul() ```ts mul(y: string | number | bigint | Field): Field ``` Multiply another "field-like" value with this [Field](Field.mdx) element. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the modular difference of the two value. #### Example ```ts const x = Field(3); const product = x.mul(Field(5)); product.assertEquals(Field(15)); ``` #### Source [lib/provable/field.ts:358](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L358) *** ### neg() ```ts neg(): Field ``` Negate a [Field](Field.mdx). This is equivalent to multiplying the [Field](Field.mdx) by -1. #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element that is equivalent to the element multiplied by -1. #### Example ```ts const negOne = Field(1).neg(); negOne.assertEquals(-1); ``` #### Example ```ts const someField = Field(42); someField.neg().assertEquals(someField.mul(Field(-1))); // This statement is always true regardless of the value of `someField` ``` **Warning**: This is a modular negation. For details, see the [sub](Field.mdx#sub) method. #### Source [lib/provable/field.ts:278](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L278) *** ### seal() ```ts seal(): VarField | ConstantField ``` **Warning**: This function is mainly for internal use. Normally it is not intended to be used by a zkApp developer. In o1js, addition and scaling (multiplication of variables by a constant) of variables is represented as an AST - [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree). For example, the expression `x.add(y).mul(2)` is represented as `Scale(2, Add(x, y))`. A new internal variable is created only when the variable is needed in a multiplicative or any higher level constraint (for example multiplication of two [Field](Field.mdx) elements) to represent the operation. The `seal()` function tells o1js to stop building an AST and create a new variable right away. #### Returns [`VarField`](../type-aliases/VarField.mdx) \| [`ConstantField`](../type-aliases/ConstantField.mdx) A [Field](Field.mdx) element that is equal to the result of AST that was previously on this [Field](Field.mdx) element. #### Source [lib/provable/field.ts:872](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L872) *** ### sqrt() ```ts sqrt(): Field ``` Take the square root of this [Field](Field.mdx) element. Proves that the Field element has a square root in the finite field, or throws if it doesn't. #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the square root of the [Field](Field.mdx) element. #### Example ```ts let z = x.sqrt(); z.mul(z).assertEquals(x); // true for every `x` ``` **Warning**: This is a modular square root, which is any number z that satisfies z*z = x (mod p). Note that, if a square root z exists, there also exists a second one, -z (which is different if z != 0). Therefore, this method leaves an adversarial prover the choice between two different values to return. #### Source [lib/provable/field.ts:492](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L492) *** ### square() ```ts square(): Field ``` Square this [Field](Field.mdx) element. #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the multiplication of the [Field](Field.mdx) element with itself. #### Example ```ts const someField = Field(7); const square = someField.square(); square.assertEquals(someField.mul(someField)); // This statement is always true regardless of the value of `someField` ``` ** Warning: This is a modular multiplication. See `mul()` method for more details. #### Source [lib/provable/field.ts:463](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L463) *** ### sub() ```ts sub(y: string | number | bigint | Field): Field ``` Subtract another "field-like" value from this [Field](Field.mdx) element. #### Parameters • **y**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element equivalent to the modular difference of the two value. #### Example ```ts const x = Field(3); const difference = x.sub(5); difference.assertEquals(Field(-2)); ``` **Warning**: This is a modular subtraction in the pasta field. #### Example ```ts const x = Field(1); const difference = x.sub(Field(2)); // If you try to print difference - `console.log(difference.toBigInt())` - you will realize that it prints a very big integer because this is modular arithmetic, and 1 - 2 circles around the field to become p - 1. // You can use the reverse operation of subtraction (addition) to prove the difference is calculated correctly. difference.add(Field(2)).assertEquals(x); ``` #### Source [lib/provable/field.ts:314](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L314) *** ### toAuxiliary() ```ts toAuxiliary(): [] ``` This function is the implementation of Provable.toAuxiliary for the [Field](Field.mdx) type. As the primitive [Field](Field.mdx) type has no auxiliary data associated with it, this function will always return an empty array. #### Returns [] #### Source [lib/provable/field.ts:1005](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1005) *** ### toBigInt() ```ts toBigInt(): bigint ``` Serialize the [Field](Field.mdx) to a bigint, e.g. for printing. Trying to print a [Field](Field.mdx) without this function will directly stringify the Field object, resulting in unreadable output. **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the bigint representation of the [Field](Field.mdx). Use the operation only during debugging. #### Returns `bigint` A bigint equivalent to the bigint representation of the Field. #### Example ```ts const someField = Field(42); console.log(someField.toBigInt()); ``` #### Source [lib/provable/field.ts:176](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L176) *** ### toBits() ```ts toBits(length: number): Bool[] ``` Returns an array of [Bool](Bool.mdx) elements representing [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) of this [Field](Field.mdx) element. If you use the optional `length` argument, proves that the field element fits in `length` bits. The `length` has to be between 0 and 254 and the method throws if it isn't. **Warning**: The cost of this operation in a zk proof depends on the `length` you specify, which by default is 254 bits. Prefer to pass a smaller `length` if possible. #### Parameters • **length**: `number`= `254` the number of bits to fit the element. If the element does not fit in `length` bits, the functions throws an error. #### Returns [`Bool`](Bool.mdx)[] An array of [Bool](Bool.mdx) element representing little endian binary representation of this [Field](Field.mdx). #### Source [lib/provable/field.ts:810](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L810) *** ### toConstant() ```ts toConstant(): ConstantField ``` Create a [Field](Field.mdx) element equivalent to this [Field](Field.mdx) element's value, but is a constant. See [Field.isConstant](Field.mdx#isconstant) for more information about what is a constant [Field](Field.mdx). #### Returns [`ConstantField`](../type-aliases/ConstantField.mdx) A constant [Field](Field.mdx) element equivalent to this [Field](Field.mdx) element. #### Example ```ts const someField = Field(42); someField.toConstant().assertEquals(someField); // Always true ``` #### Source [lib/provable/field.ts:159](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L159) *** ### toFields() ```ts toFields(): Field[] ``` This function is the implementation of Provable.toFields for the [Field](Field.mdx) type. The result will be always an array of length 1, where the first and only element equals the [Field](Field.mdx) itself. #### Returns [`Field`](Field.mdx)[] A [Field](Field.mdx) array of length 1 created from this [Field](Field.mdx). #### Source [lib/provable/field.ts:996](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L996) *** ### toJSON() ```ts toJSON(): string ``` Serialize the [Field](Field.mdx) to a JSON string, e.g. for printing. Trying to print a [Field](Field.mdx) without this function will directly stringify the Field object, resulting in unreadable output. **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the JSON string representation of the [Field](Field.mdx). Use the operation only during debugging. #### Returns `string` A string equivalent to the JSON representation of the [Field](Field.mdx). #### Example ```ts const someField = Field(42); console.log(someField.toJSON()); ``` #### Source [lib/provable/field.ts:1028](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1028) *** ### toString() ```ts toString(): string ``` Serialize the [Field](Field.mdx) to a string, e.g. for printing. Trying to print a [Field](Field.mdx) without this function will directly stringify the Field object, resulting in unreadable output. **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the [Field](Field.mdx). Use the operation only during debugging. #### Returns `string` A string equivalent to the string representation of the Field. #### Example ```ts const someField = Field(42); console.log(someField.toString()); ``` #### Source [lib/provable/field.ts:194](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L194) *** ### check() ```ts static check(): void ``` This function is the implementation of Provable.check in [Field](Field.mdx) type. As any field element can be a [Field](Field.mdx), this function does not create any assertions, so it does nothing. #### Returns `void` #### Source [lib/provable/field.ts:966](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L966) *** ### empty() ```ts static empty(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/field.ts:1011](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1011) *** ### from() ```ts static from(x: string | number | bigint | Field): Field ``` #### Parameters • **x**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) #### Source [lib/provable/field.ts:119](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L119) *** ### fromBits() ```ts static fromBits(bits: (boolean | Bool)[]): Field ``` Convert a bit array into a [Field](Field.mdx) element using [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) The method throws if the given bits do not fit in a single Field element. In this case, no more than 254 bits are allowed because some 255 bit integers do not fit into a single Field element. **Important**: If the given `bytes` array is an array of `booleans` or [Bool](Bool.mdx) elements that all are `constant`, the resulting [Field](Field.mdx) element will be a constant as well. Or else, if the given array is a mixture of constants and variables of [Bool](Bool.mdx) type, the resulting [Field](Field.mdx) will be a variable as well. #### Parameters • **bits**: (`boolean` \| [`Bool`](Bool.mdx))[] #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) element matching the [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) of the given `bytes` array. #### Source [lib/provable/field.ts:843](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L843) *** ### fromBytes() ```ts static fromBytes(bytes: number[]): Field ``` Coerce a new [Field](Field.mdx) element using the [little-endian](https://en.wikipedia.org/wiki/Endianness) representation of the given `bytes` array. Note that the given `bytes` array may have at most 32 elements as the [Field](Field.mdx) is a `finite-field` in the order of [Field.ORDER](Field.mdx#order). **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the byte representation of the [Field](Field.mdx). #### Parameters • **bytes**: `number`[] The bytes array to coerce the [Field](Field.mdx) from. #### Returns [`Field`](Field.mdx) A new [Field](Field.mdx) element created using the [little-endian](https://en.wikipedia.org/wiki/Endianness) representation of the given `bytes` array. #### Source [lib/provable/field.ts:1115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1115) *** ### fromFields() ```ts static fromFields(fields: Field[]): Field ``` Implementation of Provable.fromFields for the [Field](Field.mdx) type. **Warning**: This function is designed for internal use. It is not intended to be used by a zkApp developer. Creates a [Field](Field.mdx) from an array of Fields of length 1. #### Parameters • **fields**: [`Field`](Field.mdx)[] an array of length 1 serialized from [Field](Field.mdx) elements. #### Returns [`Field`](Field.mdx) The first [Field](Field.mdx) element of the given array. #### Source [lib/provable/field.ts:955](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L955) *** ### fromJSON() ```ts static fromJSON(json: string): Field ``` Deserialize a JSON string containing a "field-like" value into a [Field](Field.mdx) element. **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the [Field](Field.mdx). #### Parameters • **json**: `string` #### Returns [`Field`](Field.mdx) A [Field](Field.mdx) coerced from the given JSON string. #### Source [lib/provable/field.ts:1060](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1060) *** ### fromValue() ```ts static fromValue(x: string | number | bigint | Field): Field ``` `Provable.fromValue()` #### Parameters • **x**: `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx) #### Source [lib/provable/field.ts:985](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L985) *** ### random() ```ts static random(): Field ``` A random [Field](Field.mdx) element. #### Returns [`Field`](Field.mdx) A random [Field](Field.mdx) element. #### Example ```ts console.log(Field.random().toBigInt()); // Run this code twice! ``` #### Source [lib/provable/field.ts:894](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L894) *** ### readBytes() ```ts static readBytes(bytes: number[], offset: NonNegativeInteger): [Field, number] ``` Part of the `Binable` interface. **Warning**: This function is for internal use. It is not intended to be used by a zkApp developer. #### Type parameters • **N** *extends* `number` #### Parameters • **bytes**: `number`[] • **offset**: `NonNegativeInteger`\<`N`\> #### Returns [[`Field`](Field.mdx), `number`] #### Source [lib/provable/field.ts:1098](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1098) *** ### sizeInFields() ```ts static sizeInFields(): number ``` This function is the implementation of Provable.sizeInFields for the [Field](Field.mdx) type. Size of the [Field](Field.mdx) type is 1, as it is the primitive type. This function returns a regular number, so you cannot use it to prove something on chain. You can use it during debugging or to understand the memory complexity of some type. #### Returns `number` A number representing the size of the [Field](Field.mdx) type in terms of [Field](Field.mdx) type itself. #### Example ```ts console.log(Field.sizeInFields()); // Prints 1 ``` #### Source [lib/provable/field.ts:940](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L940) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` This function is the implementation of Provable.toAuxiliary for the [Field](Field.mdx) type. As the primitive [Field](Field.mdx) type has no auxiliary data associated with it, this function will always return an empty array. #### Returns [] #### Source [lib/provable/field.ts:923](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L923) *** ### toBigint() ```ts static toBigint(x: Field): bigint ``` Convert a [Field](Field.mdx) element to a bigint. #### Parameters • **x**: [`Field`](Field.mdx) #### Returns `bigint` #### Source [lib/provable/field.ts:978](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L978) *** ### toBytes() ```ts static toBytes(x: Field): number[] ``` Create an array of digits equal to the [little-endian](https://en.wikipedia.org/wiki/Endianness) byte order of the given [Field](Field.mdx) element. Note that the array has always 32 elements as the [Field](Field.mdx) is a `finite-field` in the order of [Field.ORDER](Field.mdx#order). #### Parameters • **x**: [`Field`](Field.mdx) #### Returns `number`[] An array of digits equal to the [little-endian](https://en.wikipedia.org/wiki/Endianness) byte order of the given [Field](Field.mdx) element. #### Source [lib/provable/field.ts:1089](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1089) *** ### toFields() ```ts static toFields(x: Field): Field[] ``` This function is the implementation of Provable.toFields for the [Field](Field.mdx) type. Static function to serializes a [Field](Field.mdx) into an array of [Field](Field.mdx) elements. This will be always an array of length 1, where the first and only element equals the given parameter itself. #### Parameters • **x**: [`Field`](Field.mdx) #### Returns [`Field`](Field.mdx)[] A [Field](Field.mdx) array of length 1 created from this [Field](Field.mdx). #### Source [lib/provable/field.ts:912](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L912) *** ### toInput() ```ts static toInput(x: Field): { "fields": Field[]; } ``` **Warning**: This function is mainly for internal use. Normally it is not intended to be used by a zkApp developer. This function is the implementation of `ProvableExtended.toInput()` for the [Field](Field.mdx) type. #### Parameters • **x**: [`Field`](Field.mdx) #### Returns ```ts { "fields": Field[]; } ``` An object where the `fields` key is a [Field](Field.mdx) array of length 1 created from this [Field](Field.mdx). ##### fields ```ts fields: Field[]; ``` #### Source [lib/provable/field.ts:1074](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1074) *** ### toJSON() ```ts static toJSON(x: Field): string ``` Serialize the given [Field](Field.mdx) element to a JSON string, e.g. for printing. Trying to print a [Field](Field.mdx) without this function will directly stringify the Field object, resulting in unreadable output. **Warning**: This operation does _not_ affect the circuit and can't be used to prove anything about the JSON string representation of the [Field](Field.mdx). Use the operation only during debugging. #### Parameters • **x**: [`Field`](Field.mdx) #### Returns `string` A string equivalent to the JSON representation of the given [Field](Field.mdx). #### Example ```ts const someField = Field(42); console.log(Field.toJSON(someField)); ``` #### Source [lib/provable/field.ts:1047](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1047) *** ### toValue() ```ts static toValue(x: Field): bigint ``` `Provable.toValue()` #### Parameters • **x**: [`Field`](Field.mdx) #### Returns `bigint` #### Source [lib/provable/field.ts:971](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L971) --- url: /zkapps/o1js-reference/classes/ForeignCurve --- ## Constructors ### new ForeignCurve() ```ts new ForeignCurve(g: { "x": number | bigint | Field3 | AlmostForeignField; "y": number | bigint | Field3 | AlmostForeignField; }): ForeignCurve ``` Create a new [ForeignCurve](ForeignCurve.mdx) from an object representing the (affine) x and y coordinates. Note: Inputs must be range checked if they originate from a different field with a different modulus or if they are not constants. Please refer to the [ForeignField](ForeignField.mdx) constructor comments for more details. #### Parameters • **g** • **g.x**: `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.mdx) • **g.y**: `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Example ```ts let x = new ForeignCurve({ x: 1n, y: 1n }); ``` **Important**: By design, there is no way for a `ForeignCurve` to represent the zero point. **Warning**: This fails for a constant input which does not represent an actual point on the curve. #### Source [lib/provable/crypto/foreign-curve.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L49) ## Properties ### x ```ts x: AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-curve.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L32) *** ### y ```ts y: AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-curve.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L33) *** ### \_Bigint? ```ts static optional _Bigint: {}; ``` #### Source [lib/provable/crypto/foreign-curve.ts:362](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L362) *** ### \_Field? ```ts static optional _Field: typeof AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-curve.ts:363](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L363) *** ### \_Scalar? ```ts static optional _Scalar: typeof AlmostForeignField; ``` #### Source [lib/provable/crypto/foreign-curve.ts:364](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L364) *** ### \_provable? ```ts static optional _provable: ProvablePureExtended; ``` #### Source [lib/provable/crypto/foreign-curve.ts:365](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L365) ## Accessors ### Constructor ```ts get Constructor(): typeof ForeignCurve ``` #### Returns *typeof* [`ForeignCurve`](ForeignCurve.mdx) #### Source [lib/provable/crypto/foreign-curve.ts:359](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L359) *** ### modulus ```ts get modulus(): bigint ``` The size of the curve's base field. #### Returns `bigint` #### Source [lib/provable/crypto/foreign-curve.ts:203](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L203) *** ### Bigint ```ts get static Bigint(): {} ``` Curve arithmetic on JS bigints. #### Returns ```ts {} ``` #### Source [lib/provable/crypto/foreign-curve.ts:374](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L374) *** ### Field ```ts get static Field(): typeof AlmostForeignField ``` The base field of this curve as a [ForeignField](ForeignField.mdx). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/crypto/foreign-curve.ts:381](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L381) *** ### Scalar ```ts get static Scalar(): typeof AlmostForeignField ``` The scalar field of this curve as a [ForeignField](ForeignField.mdx). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/crypto/foreign-curve.ts:388](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L388) *** ### generator ```ts get static generator(): ForeignCurve ``` The constant generator point. #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Source [lib/provable/crypto/foreign-curve.ts:191](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L191) *** ### modulus ```ts get static modulus(): bigint ``` The size of the curve's base field. #### Returns `bigint` #### Source [lib/provable/crypto/foreign-curve.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L197) *** ### provable ```ts get static provable(): ProvablePureExtended ``` `Provable` #### Returns `ProvablePureExtended`\<[`ForeignCurve`](ForeignCurve.mdx), \{ `"x"`: `bigint`; `"y"`: `bigint`; \}, \{ `"x"`: `string`; `"y"`: `string`; \}\> #### Source [lib/provable/crypto/foreign-curve.ts:395](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L395) ## Methods ### add() ```ts add(h: ForeignCurve | FlexiblePoint): ForeignCurve ``` Elliptic curve addition. ```ts let r = p.add(q); // r = p + q ``` **Important**: this is _incomplete addition_ and does not handle the degenerate cases: - Inputs are equal, `g = h` (where you would use [double](ForeignCurve.mdx#double)). In this case, the result of this method is garbage and can be manipulated arbitrarily by a malicious prover. - Inputs are inverses of each other, `g = -h`, so that the result would be the zero point. In this case, the proof fails. If you want guaranteed soundness regardless of the input, use [addSafe](ForeignCurve.mdx#addsafe) instead. #### Parameters • **h**: [`ForeignCurve`](ForeignCurve.mdx) \| `FlexiblePoint` #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Throws if the inputs are inverses of each other. #### Source [lib/provable/crypto/foreign-curve.ts:243](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L243) *** ### addSafe() ```ts addSafe(h: ForeignCurve | FlexiblePoint): ForeignCurve ``` Safe elliptic curve addition. This is the same as [add](ForeignCurve.mdx#add), but additionally proves that the inputs are not equal. Therefore, the method is guaranteed to either fail or return a valid addition result. **Beware**: this is more expensive than [add](ForeignCurve.mdx#add), and is still incomplete in that it does not succeed on equal or inverse inputs. #### Parameters • **h**: [`ForeignCurve`](ForeignCurve.mdx) \| `FlexiblePoint` #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Throws if the inputs are equal or inverses of each other. #### Source [lib/provable/crypto/foreign-curve.ts:261](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L261) *** ### assertInSubgroup() ```ts assertInSubgroup(): void ``` Assert that this point lies in the subgroup defined by `order*P = 0`. Note: this is a no-op if the curve has cofactor equal to 1. Otherwise it performs the full scalar multiplication `order*P` and is expensive. #### Returns `void` #### Source [lib/provable/crypto/foreign-curve.ts:341](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L341) *** ### assertOnCurve() ```ts assertOnCurve(): void ``` Assert that this point lies on the elliptic curve, which means it satisfies the equation `y^2 = x^3 + ax + b` #### Returns `void` #### Source [lib/provable/crypto/foreign-curve.ts:325](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L325) *** ### double() ```ts double(): ForeignCurve ``` Elliptic curve doubling. #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Example ```ts let r = p.double(); // r = 2 * p ``` #### Source [lib/provable/crypto/foreign-curve.ts:280](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L280) *** ### isConstant() ```ts isConstant(): boolean ``` Checks whether this curve point is constant. See FieldVar to understand constants vs variables. #### Returns `boolean` #### Source [lib/provable/crypto/foreign-curve.ts:212](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L212) *** ### negate() ```ts negate(): ForeignCurve ``` Elliptic curve negation. #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Example ```ts let r = p.negate(); // r = -p ``` #### Source [lib/provable/crypto/foreign-curve.ts:294](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L294) *** ### scale() ```ts scale(scalar: number | bigint | AlmostForeignField): ForeignCurve ``` Elliptic curve scalar multiplication, where the scalar is represented as a [ForeignField](ForeignField.mdx) element. **Important**: this proves that the result of the scalar multiplication is not the zero point. #### Parameters • **scalar**: `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.mdx) #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Throws if the scalar multiplication results in the zero point; for example, if the scalar is zero. #### Example ```ts let r = p.scale(s); // r = s * p ``` #### Source [lib/provable/crypto/foreign-curve.ts:310](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L310) *** ### toBigint() ```ts toBigint(): GroupAffine ``` Convert this curve point to a point with bigint coordinates. #### Returns `GroupAffine` #### Source [lib/provable/crypto/foreign-curve.ts:219](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L219) *** ### assertInSubgroup() ```ts static assertInSubgroup(g: ForeignCurve): void ``` #### Parameters • **g**: [`ForeignCurve`](ForeignCurve.mdx) #### Returns `void` #### Source [lib/provable/crypto/foreign-curve.ts:329](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L329) *** ### assertOnCurve() ```ts static assertOnCurve(g: ForeignCurve): void ``` #### Parameters • **g**: [`ForeignCurve`](ForeignCurve.mdx) #### Returns `void` #### Source [lib/provable/crypto/foreign-curve.ts:317](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L317) *** ### check() ```ts static check(g: ForeignCurveNotNeeded): void ``` Check that this is a valid element of the target subgroup of the curve: - Check that the coordinates are valid field elements - Use [()](ForeignCurve.mdx#assertoncurve-1) to check that the point lies on the curve - If the curve has cofactor unequal to 1, use [()](ForeignCurve.mdx#assertinsubgroup-1). #### Parameters • **g**: `ForeignCurveNotNeeded` #### Returns `void` #### Source [lib/provable/crypto/foreign-curve.ts:351](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L351) *** ### from() ```ts static from(g: ForeignCurve | FlexiblePoint): ForeignCurve ``` Coerce the input to a [ForeignCurve](ForeignCurve.mdx). #### Parameters • **g**: [`ForeignCurve`](ForeignCurve.mdx) \| `FlexiblePoint` #### Returns [`ForeignCurve`](ForeignCurve.mdx) #### Source [lib/provable/crypto/foreign-curve.ts:65](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L65) *** ### fromEthers() ```ts static fromEthers(hex: string): ForeignCurve ``` Create a new [ForeignCurve](ForeignCurve.mdx) instance from an Ethereum public key in hex format, which may be either compressed or uncompressed. This method is designed to handle the parsing of public keys as used by the ethers.js library. The input should represent the affine x and y coordinates of the point, in hexadecimal format. Compressed keys are 33 bytes long and begin with 0x02 or 0x03, while uncompressed keys are 65 bytes long and begin with 0x04. **Warning:** This method is specifically designed for use with the Secp256k1 curve. Using it with other curves may result in incorrect behavior or errors. Ensure that the curve setup matches Secp256k1, as shown in the example, to avoid unintended issues. #### Parameters • **hex**: `string` The public key as a hexadecimal string (without the "0x" prefix). #### Returns [`ForeignCurve`](ForeignCurve.mdx) A new instance of the curve representing the given public key. #### Example ```ts class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} const wallet = Wallet.createRandom(); const publicKey = Secp256k1.fromEthers(wallet.publicKey.slice(2)); ``` #### Source [lib/provable/crypto/foreign-curve.ts:143](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L143) *** ### fromHex() ```ts static fromHex(hex: string): ForeignCurve ``` Parses a hexadecimal string representing an uncompressed elliptic curve point and coerces it into a [ForeignCurve](ForeignCurve.mdx) point. The method extracts the x and y coordinates from the provided hex string and verifies that the resulting point lies on the curve. **Note:** This method only supports uncompressed elliptic curve points, which are 65 bytes in total (1-byte prefix + 32 bytes for x + 32 bytes for y). #### Parameters • **hex**: `string` The hexadecimal string representing the uncompressed elliptic curve point. #### Returns [`ForeignCurve`](ForeignCurve.mdx) - A point on the foreign curve, parsed from the given hexadecimal string. #### Throws - Throws an error if the input is not a valid public key. #### Example ```ts class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} const publicKeyHex = '04f8b8db25c619d0c66b2dc9e97ecbafafae...'; // Example hex string for uncompressed point const point = Secp256k1.fromHex(publicKeyHex); ``` **Important:** This method is only designed to handle uncompressed elliptic curve points in hex format. #### Source [lib/provable/crypto/foreign-curve.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L92) --- url: /zkapps/o1js-reference/classes/ForeignField --- ## Constructors ### new ForeignField() ```ts new ForeignField(x: | string | number | bigint | Field3 | ForeignField): ForeignField ``` Create a new [ForeignField](ForeignField.mdx) from a bigint, number, string or another ForeignField. #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `Field3` \| [`ForeignField`](ForeignField.mdx) #### Returns [`ForeignField`](ForeignField.mdx) #### Example ```ts let x = new ForeignField(5); ``` Note: Inputs must be range checked if they originate from a different field with a different modulus or if they are not constants. - When constructing from another [ForeignField](ForeignField.mdx) instance, ensure the modulus matches. If not, check the modulus using `Gadgets.ForeignField.assertLessThan()` and handle appropriately. - When constructing from a Field3 array, ensure all elements are valid Field elements and range checked. - Ensure constants are correctly reduced to the modulus of the field. #### Source [lib/provable/foreign-field.ts:101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L101) ## Properties ### value ```ts value: Field3; ``` The internal representation of a foreign field element, as a tuple of 3 limbs. #### Source [lib/provable/foreign-field.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L49) *** ### \_Bigint ```ts static _Bigint: undefined | {} = undefined; ``` #### Source [lib/provable/foreign-field.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L27) *** ### \_modulus ```ts static _modulus: undefined | bigint = undefined; ``` #### Source [lib/provable/foreign-field.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L28) *** ### \_provable ```ts static _provable: any = undefined; ``` #### Source [lib/provable/foreign-field.ts:414](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L414) *** ### \_variants ```ts static _variants: undefined | { "almostReduced": typeof AlmostForeignField; "canonical": typeof CanonicalForeignField; "unreduced": typeof UnreducedForeignField; } = undefined; ``` Sibling classes that represent different ranges of field elements. #### Source [lib/provable/foreign-field.ts:58](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L58) ## Accessors ### Constructor ```ts get Constructor(): typeof ForeignField ``` #### Returns *typeof* [`ForeignField`](ForeignField.mdx) #### Source [lib/provable/foreign-field.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L51) *** ### modulus ```ts get modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L39) *** ### AlmostReduced ```ts get static AlmostReduced(): typeof AlmostForeignField ``` Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L76) *** ### Bigint ```ts get static Bigint(): {} ``` #### Returns ```ts {} ``` #### Source [lib/provable/foreign-field.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L31) *** ### Canonical ```ts get static Canonical(): typeof CanonicalForeignField ``` Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). #### Returns *typeof* [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:83](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L83) *** ### Unreduced ```ts get static Unreduced(): typeof UnreducedForeignField ``` Constructor for unreduced field elements. #### Returns *typeof* `UnreducedForeignField` #### Source [lib/provable/foreign-field.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L69) *** ### modulus ```ts get static modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L35) *** ### provable ```ts get static provable(): any ``` `Provable`, see [Provable](../type-aliases/Provable.mdx) #### Returns `any` #### Source [lib/provable/foreign-field.ts:419](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L419) *** ### sizeInBits ```ts get static sizeInBits(): number ``` #### Returns `number` #### Source [lib/provable/foreign-field.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L42) ## Methods ### add() ```ts add(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field addition #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Example ```ts x.add(2); // x + 2 mod p ``` #### Source [lib/provable/foreign-field.ts:218](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L218) *** ### assertAlmostReduced() ```ts assertAlmostReduced(): AlmostForeignField ``` Assert that this field element lies in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. Returns the field element as a [AlmostForeignField](AlmostForeignField.mdx). For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1). Note: this does not ensure that the field elements is in the canonical range [0, p). To assert that stronger property, there is [assertCanonical](ForeignField.mdx#assertcanonical). You should typically use [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for ensuring validity of all our non-native field arithmetic methods. #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:173](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L173) *** ### assertCanonical() ```ts assertCanonical(): CanonicalForeignField ``` Assert that this field element is fully reduced, i.e. lies in the range [0, p), where p is the foreign field modulus. Returns the field element as a [CanonicalForeignField](CanonicalForeignField.mdx). #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L204) *** ### assertEquals() #### assertEquals(y, message) ```ts assertEquals(y: number | bigint | CanonicalForeignField, message?: string): CanonicalForeignField ``` Assert equality with a ForeignField-like value ##### Parameters • **y**: `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) • **message?**: `string` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Example ```ts x.assertEquals(0, "x is zero"); ``` Since asserting equality can also serve as a range check, this method returns `x` with the appropriate type: ##### Example ```ts let xChecked = x.assertEquals(1, "x is 1"); xChecked satisfies CanonicalForeignField; ``` ##### Source [lib/provable/foreign-field.ts:296](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L296) #### assertEquals(y, message) ```ts assertEquals(y: AlmostForeignField, message?: string): AlmostForeignField ``` ##### Parameters • **y**: [`AlmostForeignField`](AlmostForeignField.mdx) • **message?**: `string` ##### Returns [`AlmostForeignField`](AlmostForeignField.mdx) ##### Source [lib/provable/foreign-field.ts:300](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L300) #### assertEquals(y, message) ```ts assertEquals(y: ForeignField, message?: string): ForeignField ``` ##### Parameters • **y**: [`ForeignField`](ForeignField.mdx) • **message?**: `string` ##### Returns [`ForeignField`](ForeignField.mdx) ##### Source [lib/provable/foreign-field.ts:301](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L301) *** ### assertLessThan() ```ts assertLessThan(c: number | bigint, message?: string): void ``` Assert that this field element is less than a constant c: `x < c`. The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. #### Parameters • **c**: `number` \| `bigint` • **message?**: `string` #### Returns `void` #### Example ```ts x.assertLessThan(10); ``` #### Source [lib/provable/foreign-field.ts:339](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L339) *** ### isConstant() ```ts isConstant(): boolean ``` Checks whether this field element is a constant. See FieldVar to understand constants vs variables. #### Returns `boolean` #### Source [lib/provable/foreign-field.ts:136](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L136) *** ### neg() ```ts neg(): AlmostForeignField ``` Finite field negation #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Example ```ts x.neg(); // -x mod p = p - x ``` #### Source [lib/provable/foreign-field.ts:229](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L229) *** ### sub() ```ts sub(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field subtraction #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Example ```ts x.sub(1); // x - 1 mod p ``` #### Source [lib/provable/foreign-field.ts:244](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L244) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this field element to a bigint. #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L156) *** ### toBits() ```ts toBits(length?: number): Bool[] ``` Unpack a field element to its bits, as a [Bool](Bool.mdx)[] array. This method is provable! #### Parameters • **length?**: `number` #### Returns [`Bool`](Bool.mdx)[] #### Source [lib/provable/foreign-field.ts:358](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L358) *** ### toConstant() ```ts toConstant(): ForeignField ``` Convert this field element to a constant. See FieldVar to understand constants vs variables. **Warning**: This function is only useful in Provable.witness or Provable.asProver blocks, that is, in situations where the prover computes a value outside provable code. #### Returns [`ForeignField`](ForeignField.mdx) #### Source [lib/provable/foreign-field.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L148) *** ### toFields() ```ts toFields(): Field[] ``` Instance version of `Provable.toFields`, see Provable.toFields #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/foreign-field.ts:406](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L406) *** ### assertAlmostReduced() ```ts static assertAlmostReduced(...xs: T): [...{ [i in string | number | symbol]: AlmostForeignField }[]] ``` Assert that one or more field elements lie in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. This is most efficient than when checking a multiple of 3 field elements at once. #### Type parameters • **T** *extends* `Tuple`\<[`ForeignField`](ForeignField.mdx)\> #### Parameters • ...**xs**: `T` #### Returns [...\{ [i in string \| number \| symbol]: AlmostForeignField \}[]] #### Source [lib/provable/foreign-field.ts:187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L187) *** ### check() ```ts static check(_: ForeignField): void ``` #### Parameters • **\_**: [`ForeignField`](ForeignField.mdx) #### Returns `void` #### Source [lib/provable/foreign-field.ts:410](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L410) *** ### from() #### from(x) ```ts static from(x: string | number | bigint): CanonicalForeignField ``` Coerce the input to a [ForeignField](ForeignField.mdx). ##### Parameters • **x**: `string` \| `number` \| `bigint` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Source [lib/provable/foreign-field.ts:124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L124) #### from(x) ```ts static from(x: string | number | bigint | ForeignField): ForeignField ``` ##### Parameters • **x**: `string` \| `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) ##### Returns [`ForeignField`](ForeignField.mdx) ##### Source [lib/provable/foreign-field.ts:125](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L125) *** ### fromBits() ```ts static fromBits(bits: Bool[]): AlmostForeignField ``` Create a field element from its bits, as a `Bool[]` array. This method is provable! #### Parameters • **bits**: [`Bool`](Bool.mdx)[] #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:388](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L388) *** ### random() ```ts static random(): CanonicalForeignField ``` #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:399](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L399) *** ### sum() ```ts static sum(xs: (number | bigint | ForeignField)[], operations: (-1 | 1)[]): UnreducedForeignField ``` Sum (or difference) of multiple finite field elements. #### Parameters • **xs**: (`number` \| `bigint` \| [`ForeignField`](ForeignField.mdx))[] • **operations**: (`-1` \| `1`)[] #### Returns `UnreducedForeignField` #### Example ```ts let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 z.assertEquals(2); ``` This method expects a list of ForeignField-like values, `x0,...,xn`, and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), and returns `x0 + op1*x1 + ... + opn*xn` where the sum is computed in finite field arithmetic. **Important:** For more than two summands, this is significantly more efficient than chaining calls to [ForeignField.add](ForeignField.mdx#add) and [ForeignField.sub](ForeignField.mdx#sub). #### Source [lib/provable/foreign-field.ts:269](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L269) --- url: /zkapps/o1js-reference/classes/Group --- An element of a Group. ## Constructors ### new Group() ```ts new Group(__namedParameters: { "x": | string | number | bigint | FieldVar | Field; "y": | string | number | bigint | FieldVar | Field; }): Group ``` Coerces anything group-like to a [Group](Group.mdx). #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.x**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) • **\_\_namedParameters.y**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:50](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L50) ## Properties ### x ```ts x: Field; ``` #### Source [lib/provable/group.ts:21](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L21) *** ### y ```ts y: Field; ``` #### Source [lib/provable/group.ts:22](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L22) ## Accessors ### generator ```ts get static generator(): Group ``` The generator `g` of the Group. #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L27) *** ### zero ```ts get static zero(): Group ``` Unique representation of the `zero` element of the Group (the identity element of addition in this Group). **Note**: The `zero` element is represented as `(0, 0)`. ```typescript // g + -g = 0 g.add(g.neg()).assertEquals(zero); // g + 0 = g g.add(zero).assertEquals(g); ``` #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:43](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L43) ## Methods ### add() ```ts add(g: Group): Group ``` Adds this [Group](Group.mdx) element to another [Group](Group.mdx) element. ```ts let g1 = Group({ x: -1, y: 2}) let g2 = g1.add(g1) ``` #### Parameters • **g**: [`Group`](Group.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:97](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L97) *** ### addNonZero() ```ts addNonZero(g2: Group, allowZeroOutput: boolean): Group ``` Lower-level variant of [add](Group.mdx#add) which doesn't handle the case where one of the operands is zero, and asserts that the output is non-zero. Optionally, zero outputs can be allowed by setting `allowZeroOutput` to `true`. **Warning**: If one of the inputs is zero, the result will be garbage and the proof useless. This case has to be prevented or handled separately by the caller of this method. #### Parameters • **g2**: [`Group`](Group.mdx) • **allowZeroOutput**: `boolean`= `false` #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:136](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L136) *** ### assertEquals() ```ts assertEquals(g: Group, message?: string): void ``` Assert that this [Group](Group.mdx) element equals another [Group](Group.mdx) element. Throws an error if the assertion fails. ```ts g1.assertEquals(g2); ``` #### Parameters • **g**: [`Group`](Group.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/group.ts:200](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L200) *** ### equals() ```ts equals(g: Group): Bool ``` Check if this [Group](Group.mdx) element equals another [Group](Group.mdx) element. Returns a [Bool](Bool.mdx). ```ts g1.equals(g1); // Bool(true) ``` #### Parameters • **g**: [`Group`](Group.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/group.ts:216](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L216) *** ### isZero() ```ts isZero(): Bool ``` Checks if this element is the `zero` element `{x: 0, y: 0}`. #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/group.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L84) *** ### neg() ```ts neg(): Group ``` Negates this [Group](Group.mdx). Under the hood, it simply negates the `y` coordinate and leaves the `x` coordinate as is. #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:165](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L165) *** ### scale() ```ts scale(s: number | bigint | Field | Scalar): Group ``` Elliptic curve scalar multiplication. Scales the [Group](Group.mdx) element `n`-times by itself, where `n` is the [Scalar](Scalar.mdx). ```typescript let s = Scalar(5); let 5g = g.scale(s); ``` #### Parameters • **s**: `number` \| `bigint` \| [`Field`](Field.mdx) \| [`Scalar`](Scalar.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:179](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L179) *** ### sub() ```ts sub(g: Group): Group ``` Subtracts another [Group](Group.mdx) element from this one. #### Parameters • **g**: [`Group`](Group.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L158) *** ### toFields() ```ts toFields(): Field[] ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Returns an array containing this [Group](Group.mdx) element as an array of [Field](Field.mdx) elements. #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/group.ts:253](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L253) *** ### toJSON() ```ts toJSON(): { "x": string; "y": string; } ``` Serializes this [Group](Group.mdx) element to a JSON object. This operation does NOT affect the circuit and can't be used to prove anything about the representation of the element. #### Returns ```ts { "x": string; "y": string; } ``` ##### x ```ts x: string; ``` ##### y ```ts y: string; ``` #### Source [lib/provable/group.ts:238](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L238) *** ### check() ```ts static check(g: Group): unknown ``` Checks that a [Group](Group.mdx) element is constraint properly by checking that the element is on the curve. #### Parameters • **g**: [`Group`](Group.mdx) #### Returns `unknown` #### Source [lib/provable/group.ts:330](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L330) *** ### empty() ```ts static empty(): Group ``` #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:356](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L356) *** ### from() ```ts static from(x: | string | number | bigint | FieldVar | Field, y: | string | number | bigint | FieldVar | Field): Group ``` Coerces two x and y coordinates into a [Group](Group.mdx) element. #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) • **y**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:260](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L260) *** ### fromFields() ```ts static fromFields(__namedParameters: Field[]): Group ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Deserializes a [Group](Group.mdx) element from a list of field elements. #### Parameters • **\_\_namedParameters**: [`Field`](Field.mdx)[] #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:290](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L290) *** ### fromJSON() ```ts static fromJSON(__namedParameters: { "x": | string | number | bigint | FieldVar | Field; "y": | string | number | bigint | FieldVar | Field; }): Group ``` Deserializes a JSON-like structure to a [Group](Group.mdx) element. This operation does NOT affect the circuit and can't be used to prove anything about the representation of the element. #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.x**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) • **\_\_namedParameters.y**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`Field`](Field.mdx) #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:317](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L317) *** ### fromValue() ```ts static fromValue(g: Group | { "x": number | bigint | Field; "y": number | bigint | Field; }): Group ``` #### Parameters • **g**: [`Group`](Group.mdx) \| \{ `"x"`: `number` \| `bigint` \| [`Field`](Field.mdx); `"y"`: `number` \| `bigint` \| [`Field`](Field.mdx); \} #### Returns [`Group`](Group.mdx) #### Source [lib/provable/group.ts:227](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L227) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Returns 2. #### Returns `number` #### Source [lib/provable/group.ts:299](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L299) *** ### toAuxiliary() ```ts static toAuxiliary(g?: Group): never[] ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Returns an empty array. #### Parameters • **g?**: [`Group`](Group.mdx) #### Returns `never`[] #### Source [lib/provable/group.ts:281](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L281) *** ### toFields() ```ts static toFields(g: Group): Field[] ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Returns an array containing a [Group](Group.mdx) element as an array of [Field](Field.mdx) elements. #### Parameters • **g**: [`Group`](Group.mdx) #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/group.ts:272](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L272) *** ### toInput() ```ts static toInput(x: Group): { "fields": Field[]; } ``` #### Parameters • **x**: [`Group`](Group.mdx) #### Returns ```ts { "fields": Field[]; } ``` ##### fields ```ts fields: Field[]; ``` #### Source [lib/provable/group.ts:350](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L350) *** ### toJSON() ```ts static toJSON(g: Group): { "x": string; "y": string; } ``` Serializes a [Group](Group.mdx) element to a JSON object. This operation does NOT affect the circuit and can't be used to prove anything about the representation of the element. #### Parameters • **g**: [`Group`](Group.mdx) #### Returns ```ts { "x": string; "y": string; } ``` ##### x ```ts x: string; ``` ##### y ```ts y: string; ``` #### Source [lib/provable/group.ts:308](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L308) *** ### toValue() ```ts static toValue(__namedParameters: Group): { "x": bigint; "y": bigint; } ``` #### Parameters • **\_\_namedParameters**: [`Group`](Group.mdx) #### Returns ```ts { "x": bigint; "y": bigint; } ``` ##### x ```ts x: bigint; ``` ##### y ```ts y: bigint; ``` #### Source [lib/provable/group.ts:223](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/group.ts#L223) --- url: /zkapps/o1js-reference/classes/Hashed --- `Hashed` represents a type `T` by its hash. Since a hash is only a single field element, this can be more efficient in provable code where the number of constraints depends on the number of field elements per value. For example, `Provable.if(bool, x, y)` takes O(n) constraints, where n is the number of field elements in x and y. With Hashed, this is reduced to O(1). The downside is that you will pay the overhead of hashing your values, so it helps to experiment in which parts of your code a hashed representation is beneficial. Usage: ```ts // define a hashed type from a type let HashedType = Hashed.create(MyType); // hash a value let hashed = HashedType.hash(value); // ... operations on hashes, more efficient than on plain values ... // unhash to get the original value let value = hashed.unhash(); ``` **Warning**: When wrapping a type with `Hashed`, make sure that that type is safe to automatically _pack_ and _unpack_ in provable code. In particular, do not use `Hashed` with types that define a custom `toInput()` (specifying a certain bit packing) but no corresponding `check()` method (that constrains the bit lengths of the packed parts). ## Type parameters • **T** ## Constructors ### new Hashed() ```ts new Hashed(hash: Field, value: Unconstrained): Hashed ``` #### Parameters • **hash**: [`Field`](Field.mdx) • **value**: [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Returns [`Hashed`](Hashed.mdx)\<`T`\> #### Source [lib/provable/packed.ts:241](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L241) ## Properties ### hash ```ts hash: Field; ``` #### Source [lib/provable/packed.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L204) *** ### value ```ts value: Unconstrained; ``` #### Source [lib/provable/packed.ts:205](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L205) *** ### \_innerProvable ```ts static _innerProvable: undefined | ProvableHashable; ``` #### Source [lib/provable/packed.ts:288](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L288) *** ### \_provable ```ts static _provable: undefined | ProvableHashable>; ``` #### Source [lib/provable/packed.ts:287](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L287) ## Accessors ### Constructor ```ts get Constructor(): typeof Hashed ``` #### Returns *typeof* [`Hashed`](Hashed.mdx) #### Source [lib/provable/packed.ts:290](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L290) *** ### innerProvable ```ts get static innerProvable(): ProvableHashable ``` #### Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`any`\> #### Source [lib/provable/packed.ts:294](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L294) ## Methods ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/packed.ts:282](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L282) *** ### unhash() ```ts unhash(): T ``` Unwrap a value from its hashed variant. #### Returns `T` #### Source [lib/provable/packed.ts:270](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L270) *** ### \_hash() ```ts static _hash(_: any): Field ``` #### Parameters • **\_**: `any` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/packed.ts:246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L246) *** ### create() ```ts static create(type: WithProvable>, hash?: (t: T) => Field): typeof Hashed & { "provable": ProvableHashable>; "empty": Hashed; } ``` Create a hashed representation of `type`. You can then use `HashedType.hash(x)` to wrap a value in a `Hashed`. #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<[`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\>\> • **hash?** #### Returns *typeof* [`Hashed`](Hashed.mdx) & \{ `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`Hashed`](Hashed.mdx)\<`T`\>\>; `"empty"`: [`Hashed`](Hashed.mdx)\<`T`\>; \} #### Source [lib/provable/packed.ts:210](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L210) *** ### hash() ```ts static hash(value: T, hash?: Field): Hashed ``` Wrap a value, and represent it by its hash in provable code. ```ts let hashed = HashedType.hash(value); ``` Optionally, if you already have the hash, you can pass it in and avoid recomputing it. #### Type parameters • **T** #### Parameters • **value**: `T` • **hash?**: [`Field`](Field.mdx) #### Returns [`Hashed`](Hashed.mdx)\<`T`\> #### Source [lib/provable/packed.ts:259](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L259) --- url: /zkapps/o1js-reference/classes/Int64 --- A 64 bit signed integer with values ranging from -18,446,744,073,709,551,615 to 18,446,744,073,709,551,615. ## Extends - `CircuitValue` ## Implements - `BalanceChange` ## Constructors ### new Int64() ```ts new Int64(magnitude: UInt64, sgn?: Sign): Int64 ``` #### Parameters • **magnitude**: [`UInt64`](UInt64.mdx) The magnitude of the integer as a UInt64. • **sgn?**: [`Sign`](Sign.mdx)= `Sign.one` The sign of the integer. Default is positive (Sign.one). #### Returns [`Int64`](Int64.mdx) #### Overrides `CircuitValue.constructor` #### Deprecated Use [Int64.create](Int64.mdx#create) for safe creation. WARNING: This constructor allows for ambiguous representation of zero (both +0 and -0). This can lead to unexpected behavior in operations like [()](Int64.mdx#ispositive) and [()](Int64.mdx#mod). Security Implications: 1. A malicious prover could choose either positive or negative zero. 2. Arithmetic operations that result in 0 may allow an attacker to arbitrarily choose the sign. 3. This ambiguity could be exploited in protocols using Int64s for calculations like PNL tracking. Recommended Fix: Use Int64.create() which enforces a canonical representation of zero, or explicitly handle the zero case in operations like mod(). #### Source [lib/provable/int.ts:1141](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1141) ## Properties ### magnitude ```ts magnitude: UInt64; ``` #### Implementation of `BalanceChange.magnitude` #### Source [lib/provable/int.ts:1100](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1100) *** ### sgn ```ts sgn: Sign; ``` #### Implementation of `BalanceChange.sgn` #### Source [lib/provable/int.ts:1101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1101) *** ### Unsafe ```ts static Unsafe: { "fromObject": Int64; }; ``` #### fromObject() ##### Parameters • **obj** • **obj.magnitude**: [`UInt64`](UInt64.mdx) • **obj.sgn**: [`Sign`](Sign.mdx) ##### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1206](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1206) ## Accessors ### minusOne ```ts get static minusOne(): Int64 ``` Static method to create a [Int64](Int64.mdx) with value `-1`. #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1258](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1258) *** ### one ```ts get static one(): Int64 ``` Static method to create a [Int64](Int64.mdx) with value `1`. #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1252](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1252) *** ### zero ```ts get static zero(): Int64 ``` Static method to create a [Int64](Int64.mdx) with value `0`. #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1246) ## Methods ### add() ```ts add(y: | string | number | bigint | UInt64 | UInt32 | Int64): Int64 ``` Addition with overflow checking. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) #### Returns [`Int64`](Int64.mdx) #### Implementation of `BalanceChange.add` #### Source [lib/provable/int.ts:1309](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1309) *** ### assertEquals() ```ts assertEquals(y: | string | number | bigint | UInt64 | UInt32 | Int64, message?: string): void ``` Asserts that two values are equal. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) • **message?**: `string` #### Returns `void` #### Implementation of `BalanceChange.assertEquals` #### Overrides `CircuitValue.assertEquals` #### Source [lib/provable/int.ts:1391](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1391) *** ### div() ```ts div(y: | string | number | bigint | UInt64 | UInt32 | Int64): Int64 ``` Integer division with canonical zero representation. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) The divisor. Can be an Int64, number, string, bigint, UInt64, or UInt32. #### Returns [`Int64`](Int64.mdx) A new Int64 representing the quotient, with canonical zero representation. `x.div(y)` returns the floor of `x / y`, that is, the greatest *`z`* such that *`z * y <= x`. On negative numbers, this rounds towards zero. This method guarantees that all results, including zero, have a consistent representation, eliminating potential ambiguities in zero handling. #### Implementation of `BalanceChange.div` #### Source [lib/provable/int.ts:1341](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1341) *** ### equals() ```ts equals(y: | string | number | bigint | UInt64 | UInt32 | Int64): Bool ``` Checks if two values are equal. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) #### Returns [`Bool`](Bool.mdx) #### Implementation of `BalanceChange.equals` #### Overrides `CircuitValue.equals` #### Source [lib/provable/int.ts:1384](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1384) *** ### fromObject() ```ts fromObject(obj: { "magnitude": string | number | bigint | UInt64; "sgn": bigint | Sign; }): Int64 ``` #### Parameters • **obj** • **obj.magnitude**: `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) • **obj.sgn**: `bigint` \| [`Sign`](Sign.mdx) #### Returns [`Int64`](Int64.mdx) #### Implementation of `BalanceChange.fromObject` #### Source [lib/provable/int.ts:1212](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1212) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Implementation of `BalanceChange.isConstant` #### Overrides `CircuitValue.isConstant` #### Source [lib/provable/int.ts:1235](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1235) *** ### isNegative() ```ts isNegative(): Bool ``` Checks if the value is negative (x < 0). #### Returns [`Bool`](Bool.mdx) #### Implementation of `BalanceChange.isNegative` #### Source [lib/provable/int.ts:1424](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1424) *** ### isNonNegative() ```ts isNonNegative(): Bool ``` Checks if the value is non-negative (x >= 0). #### Returns [`Bool`](Bool.mdx) #### Implementation of `BalanceChange.isNonNegative` #### Source [lib/provable/int.ts:1416](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1416) *** ### isPositive() ```ts isPositive(): Bool ``` Checks if the value is strictly positive (x > 0). #### Returns [`Bool`](Bool.mdx) True if the value is greater than zero, false otherwise. #### Implementation of `BalanceChange.isPositive` #### Remarks This method considers zero as non-positive. It ensures consistency with the mathematical definition of "positive" as strictly greater than zero. This differs from some other methods which may treat zero as non-negative. #### Source [lib/provable/int.ts:1409](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1409) *** ### mod() ```ts mod(y: | string | number | bigint | UInt64 | UInt32): Int64 ``` Calculates the integer remainder of this Int64 divided by the given value. The result `z` satisfies the following conditions: 1. 0 ≤ z < |y| 2. x - z is divisible by y Note: This method follows the "truncate toward zero" convention for negative numbers. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) The divisor. Will be converted to UInt64 if not already. #### Returns [`Int64`](Int64.mdx) A new Int64 instance representing the remainder. #### Implementation of `BalanceChange.mod` #### Example ```ts const x1 = Int64.from(17); const y1 = UInt64.from(5); console.log(x1.mod(y1).toString()); // Output: 2 ``` #### Throws Implicitly, if y is zero or negative. #### Source [lib/provable/int.ts:1369](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1369) *** ### mul() ```ts mul(y: | string | number | bigint | UInt64 | UInt32 | Int64): Int64 ``` Multiplication with overflow checking. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) #### Returns [`Int64`](Int64.mdx) #### Implementation of `BalanceChange.mul` #### Source [lib/provable/int.ts:1323](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1323) *** ### neg() ```ts neg(): Int64 ``` Negates the current Int64 value. This method returns a new Int64 instance with the opposite sign of the current value. If the current value is zero, it returns zero. #### Returns [`Int64`](Int64.mdx) A new Int64 instance with the negated value. #### Implementation of `BalanceChange.neg` #### Example ```ts Int64.from(5).neg(); ``` #### See - Int64#from for creating Int64 instances - Int64#zero for the zero constant #### Throws Implicitly, if the internal Provable.if condition fails #### Source [lib/provable/int.ts:1298](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1298) *** ### sub() ```ts sub(y: | string | number | bigint | UInt64 | UInt32 | Int64): Int64 ``` Subtraction with underflow checking. #### Parameters • **y**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) #### Returns [`Int64`](Int64.mdx) #### Implementation of `BalanceChange.sub` #### Source [lib/provable/int.ts:1316](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1316) *** ### toBigint() ```ts toBigint(): bigint ``` Turns the [Int64](Int64.mdx) into a BigInt. #### Returns `bigint` #### Implementation of `BalanceChange.toBigint` #### Source [lib/provable/int.ts:1222](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1222) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Implementation of `BalanceChange.toConstant` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toField() ```ts toField(): Field ``` Returns the [Field](../variables/Field.mdx) value. #### Returns [`Field`](Field.mdx) #### Implementation of `BalanceChange.toField` #### Source [lib/provable/int.ts:1265](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1265) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Implementation of `BalanceChange.toFields` #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Implementation of `BalanceChange.toJSON` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### toString() ```ts toString(): string ``` Turns the [Int64](Int64.mdx) into a string. #### Returns `string` #### Implementation of `BalanceChange.toString` #### Source [lib/provable/int.ts:1231](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1231) *** ### check() ```ts static check(__namedParameters: { "magnitude": UInt64; "sgn": Sign; }): void ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.magnitude**: [`UInt64`](UInt64.mdx) • **\_\_namedParameters.sgn**: [`Sign`](Sign.mdx) #### Returns `void` #### Overrides `CircuitValue.check` #### Source [lib/provable/int.ts:1428](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1428) *** ### create() ```ts static create(magnitude: UInt64, sign: Sign): Int64 ``` Safely creates a new Int64 instance, enforcing canonical representation of zero. This is the recommended way to create Int64 instances. #### Parameters • **magnitude**: [`UInt64`](UInt64.mdx) The magnitude of the integer as a UInt64 • **sign**: [`Sign`](Sign.mdx)= `Sign.one` #### Returns [`Int64`](Int64.mdx) A new Int64 instance with a canonical representation. #### Example ```ts const x = Int64.create(0); // canonical representation of zero ``` #### Source [lib/provable/int.ts:1158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1158) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### from() ```ts static from(x: | string | number | bigint | Field | UInt64 | UInt32 | Int64): Int64 ``` Creates a new [Int64](Int64.mdx). Check the range if the argument is a constant. #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`Field`](Field.mdx) \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1198](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1198) *** ### fromField() ```ts static fromField(x: Field): Int64 ``` Static method to create a [Int64](Int64.mdx) from a [Field](../variables/Field.mdx). #### Parameters • **x**: [`Field`](Field.mdx) #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1271](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1271) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromJSON` #### Source [lib/provable/types/circuit-value.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L208) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromUnsigned() ```ts static fromUnsigned(x: UInt64 | UInt32): Int64 ``` Creates a new [Int64](Int64.mdx) from a [Field](../variables/Field.mdx). **Does not** check if the [Field](../variables/Field.mdx) is within range. #### Parameters • **x**: [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) #### Returns [`Int64`](Int64.mdx) #### Source [lib/provable/int.ts:1188](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1188) *** ### fromValue() ```ts static fromValue(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromValue` #### Source [lib/provable/types/circuit-value.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L98) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L197) *** ### toValue() ```ts static toValue(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toValue` #### Source [lib/provable/types/circuit-value.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L89) --- url: /zkapps/o1js-reference/classes/Keypair --- ## Constructors ### new Keypair() ```ts new Keypair(value: unknown): Keypair ``` #### Parameters • **value**: `unknown` #### Returns [`Keypair`](Keypair.mdx) #### Source [lib/proof-system/circuit.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L104) ## Properties ### value ```ts value: unknown; ``` #### Source [lib/proof-system/circuit.ts:102](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L102) ## Methods ### constraintSystem() ```ts constraintSystem(): Gate[] ``` Returns a low-level JSON representation of the [Circuit](Circuit.mdx) from its [Keypair](Keypair.mdx): a list of gates, each of which represents a row in a table, with certain coefficients and wires to other (row, column) pairs #### Returns `Gate`[] #### Example ```ts const keypair = await MyCircuit.generateKeypair(); const json = MyProvable.witnessFromKeypair(keypair); ``` #### Source [lib/proof-system/circuit.ts:123](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L123) *** ### verificationKey() ```ts verificationKey(): VerificationKey ``` #### Returns `VerificationKey` #### Source [lib/proof-system/circuit.ts:108](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L108) --- url: /zkapps/o1js-reference/classes/Ledger --- Represents the Mina ledger. ## Constructors ### new Ledger() ```ts new Ledger(): Ledger ``` #### Returns [`Ledger`](Ledger.mdx) ## Methods ### addAccount() ```ts addAccount(publicKey: MlPublicKey, balance: string): void ``` Adds an account and its balance to the ledger. #### Parameters • **publicKey**: `MlPublicKey` • **balance**: `string` #### Returns `void` #### Source [snarky.d.ts:492](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/snarky.d.ts#L492) *** ### applyJsonTransaction() ```ts applyJsonTransaction( txJson: string, accountCreationFee: string, networkState: string): void ``` Applies a JSON transaction to the ledger. #### Parameters • **txJson**: `string` • **accountCreationFee**: `string` • **networkState**: `string` #### Returns `void` #### Source [snarky.d.ts:497](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/snarky.d.ts#L497) *** ### getAccount() ```ts getAccount(publicKey: MlPublicKey, tokenId: FieldConst): undefined | Account ``` Returns an account. #### Parameters • **publicKey**: `MlPublicKey` • **tokenId**: `FieldConst` #### Returns `undefined` \| `Account` #### Source [snarky.d.ts:506](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/snarky.d.ts#L506) *** ### create() ```ts static create(): Ledger ``` Creates a fresh ledger. #### Returns [`Ledger`](Ledger.mdx) #### Source [snarky.d.ts:487](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/snarky.d.ts#L487) --- url: /zkapps/o1js-reference/classes/MerkleList --- Dynamic-length list which is represented as a single hash Supported operations are [()](MerkleList.mdx#push) and [()](MerkleList.mdx#pop) and some variants thereof. A Merkle list is generic over its element types, so before using it you must create a subclass for your element type: ```ts class MyList extends MerkleList.create(MyType) {} // now use it let list = MyList.empty(); list.push(new MyType(...)); let element = list.pop(); ``` Internal detail: `push()` adds elements to the _start_ of the internal array and `pop()` removes them from the start. This is so that the hash which represents the list is consistent with [MerkleListIterator](MerkleListIterator.mdx), and so a `MerkleList` can be used as input to `MerkleListIterator.startIterating(list)` (which will then iterate starting from the last pushed element). ## Extended by - [`AccountUpdateForest`](AccountUpdateForest.mdx) ## Type parameters • **T** ## Implements - [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\> ## Constructors ### new MerkleList() ```ts new MerkleList(__namedParameters: MerkleListBase): MerkleList ``` #### Parameters • **\_\_namedParameters**: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\> #### Returns [`MerkleList`](MerkleList.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L84) ## Properties ### data ```ts data: Unconstrained[]>; ``` #### Implementation of `MerkleListBase.data` #### Source [lib/provable/merkle-list.ts:82](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L82) *** ### hash ```ts hash: Field; ``` #### Implementation of `MerkleListBase.hash` #### Source [lib/provable/merkle-list.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L81) *** ### \_emptyHash ```ts static _emptyHash: undefined | Field; ``` #### Source [lib/provable/merkle-list.ts:350](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L350) *** ### \_innerProvable ```ts static _innerProvable: undefined | ProvableHashable; ``` #### Source [lib/provable/merkle-list.ts:353](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L353) *** ### \_nextHash ```ts static _nextHash: undefined | (hash: Field, t: any) => Field; ``` #### Source [lib/provable/merkle-list.ts:349](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L349) *** ### \_provable ```ts static _provable: undefined | ProvableHashable>; ``` #### Source [lib/provable/merkle-list.ts:352](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L352) ## Accessors ### Constructor ```ts get Constructor(): typeof MerkleList ``` #### Returns *typeof* [`MerkleList`](MerkleList.mdx) #### Source [lib/provable/merkle-list.ts:355](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L355) *** ### innerProvable ```ts get innerProvable(): ProvableHashable ``` #### Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:372](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L372) *** ### emptyHash ```ts get static emptyHash(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/merkle-list.ts:367](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L367) ## Methods ### clone() ```ts clone(): MerkleList ``` #### Returns [`MerkleList`](MerkleList.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:223](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L223) *** ### forEach() ```ts forEach(length: number, callback: (element: T, isDummy: Bool, i: number) => void): void ``` Iterate through the list in a fixed number of steps any apply a given callback on each element. Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback. Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the `isDummy` flag separately. #### Parameters • **length**: `number` • **callback** #### Returns `void` #### Source [lib/provable/merkle-list.ts:237](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L237) *** ### isEmpty() ```ts isEmpty(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/merkle-list.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L89) *** ### lengthUnconstrained() ```ts lengthUnconstrained(): Unconstrained ``` #### Returns [`Unconstrained`](Unconstrained.mdx)\<`number`\> #### Source [lib/provable/merkle-list.ts:267](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L267) *** ### nextHash() ```ts nextHash(hash: Field, value: T): Field ``` #### Parameters • **hash**: [`Field`](Field.mdx) • **value**: `T` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/merkle-list.ts:359](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L359) *** ### pop() ```ts pop(): T ``` Remove the last element from the list and return it. If the list is empty, returns a dummy element. #### Returns `T` #### Source [lib/provable/merkle-list.ts:155](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L155) *** ### popExn() ```ts popExn(): T ``` Remove the last element from the list and return it. This proves that the list is non-empty, and fails otherwise. #### Returns `T` #### Source [lib/provable/merkle-list.ts:140](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L140) *** ### popIf() ```ts popIf(condition: Bool): T ``` Return the last element, but only remove it if `condition` is true. If the list is empty, returns a dummy element. #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns `T` #### Source [lib/provable/merkle-list.ts:174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L174) *** ### popIfUnsafe() ```ts popIfUnsafe(shouldPop: Bool): T ``` Low-level, minimal version of `pop()` which lets the _caller_ decide whether there is an element to pop. I.e. this proves: - If the input condition is true, this returns the last element and removes it from the list. - If the input condition is false, the list is unchanged and the return value is garbage. Note that if the caller passes `true` but the list is empty, this will fail. If the caller passes `false` but the list is non-empty, this succeeds and just doesn't pop off an element. #### Parameters • **shouldPop**: [`Bool`](Bool.mdx) #### Returns `T` #### Source [lib/provable/merkle-list.ts:200](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L200) *** ### push() ```ts push(element: T): void ``` Push a new element to the list. #### Parameters • **element**: `T` #### Returns `void` #### Source [lib/provable/merkle-list.ts:96](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L96) *** ### pushIf() ```ts pushIf(condition: Bool, element: T): void ``` Push a new element to the list, if the `condition` is true. #### Parameters • **condition**: [`Bool`](Bool.mdx) • **element**: `T` #### Returns `void` #### Source [lib/provable/merkle-list.ts:108](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L108) *** ### startIterating() ```ts startIterating(): MerkleListIterator ``` #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:251](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L251) *** ### startIteratingFromLast() ```ts startIteratingFromLast(): MerkleListIterator ``` #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:256](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L256) *** ### toArrayUnconstrained() ```ts toArrayUnconstrained(): Unconstrained ``` #### Returns [`Unconstrained`](Unconstrained.mdx)\<`T`[]\> #### Source [lib/provable/merkle-list.ts:261](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L261) *** ### create() ```ts static create( type: WithProvable>, nextHash: (hash: Field, value: T) => Field, emptyHash_: Field): typeof MerkleList & { "empty": () => MerkleList; "from": (array: T[]) => MerkleList; "fromReverse": (array: T[]) => MerkleList; "provable": ProvableHashable>; } ``` Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<[`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\>\> • **nextHash**= `undefined` • **emptyHash\_**: [`Field`](Field.mdx)= `emptyHash` #### Returns *typeof* [`MerkleList`](MerkleList.mdx) & \{ `"empty"`: () => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"from"`: (`array`: `T`[]) => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"fromReverse"`: (`array`: `T`[]) => [`MerkleList`](MerkleList.mdx)\<`T`\>; `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`MerkleList`](MerkleList.mdx)\<`T`\>\>; \} #### Example ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` #### Source [lib/provable/merkle-list.ts:283](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L283) --- url: /zkapps/o1js-reference/classes/MerkleListIterator --- MerkleListIterator helps iterating through a Merkle list. This works similar to calling `list.pop()` or `list.push()` repeatedly, but maintaining the entire list instead of removing elements. The core methods that support iteration are [()](MerkleListIterator.mdx#next) and [()](MerkleListIterator.mdx#previous). ```ts let iterator = MerkleListIterator.startIterating(list); let firstElement = iterator.next(); ``` We maintain two commitments: - One to the entire array, to be able to prove that we end iteration at the correct point. - One to the array from the current index until the end, to efficiently step forward. ## Type parameters • **T** ## Implements - [`MerkleListIteratorBase`](../type-aliases/MerkleListIteratorBase.mdx)\<`T`\> ## Constructors ### new MerkleListIterator() ```ts new MerkleListIterator(value: MerkleListIteratorBase): MerkleListIterator ``` #### Parameters • **value**: [`MerkleListIteratorBase`](../type-aliases/MerkleListIteratorBase.mdx)\<`T`\> #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:426](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L426) ## Properties ### currentHash ```ts currentHash: Field; ``` #### Implementation of `MerkleListIteratorBase.currentHash` #### Source [lib/provable/merkle-list.ts:423](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L423) *** ### currentIndex ```ts currentIndex: Unconstrained; ``` #### Implementation of `MerkleListIteratorBase.currentIndex` #### Source [lib/provable/merkle-list.ts:424](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L424) *** ### data ```ts readonly data: Unconstrained[]>; ``` #### Implementation of `MerkleListIteratorBase.data` #### Source [lib/provable/merkle-list.ts:419](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L419) *** ### hash ```ts readonly hash: Field; ``` #### Implementation of `MerkleListIteratorBase.hash` #### Source [lib/provable/merkle-list.ts:420](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L420) *** ### \_emptyHash ```ts static _emptyHash: undefined | Field; ``` #### Source [lib/provable/merkle-list.ts:722](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L722) *** ### \_innerProvable ```ts static _innerProvable: undefined | ProvableHashable; ``` #### Source [lib/provable/merkle-list.ts:725](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L725) *** ### \_nextHash ```ts static _nextHash: undefined | (hash: Field, value: any) => Field; ``` #### Source [lib/provable/merkle-list.ts:721](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L721) *** ### \_provable ```ts static _provable: undefined | ProvableHashable>; ``` #### Source [lib/provable/merkle-list.ts:724](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L724) ## Accessors ### Constructor ```ts get Constructor(): typeof MerkleListIterator ``` #### Returns *typeof* [`MerkleListIterator`](MerkleListIterator.mdx) #### Source [lib/provable/merkle-list.ts:727](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L727) *** ### Unsafe ```ts get Unsafe(): { "next": { "element": T; "isDummy": Bool; }; "previous": { "element": T; "isDummy": Bool; }; } ``` Low-level APIs for advanced uses #### Returns ```ts { "next": { "element": T; "isDummy": Bool; }; "previous": { "element": T; "isDummy": Bool; }; } ``` ##### next() Version of next which doesn't guarantee anything about the returned element in case the iterator is at the end. Instead, the `isDummy` flag is also returned so that this case can be handled in a custom way. ###### Returns ```ts { "element": T; "isDummy": Bool; } ``` ###### element ```ts element: T; ``` ###### isDummy ```ts isDummy: Bool; ``` ##### previous() Version of previous which doesn't guarantee anything about the returned element in case the iterator is at the start. Instead, the `isDummy` flag is also returned so that this case can be handled in a custom way. ###### Returns ```ts { "element": T; "isDummy": Bool; } ``` ###### element ```ts element: T; ``` ###### isDummy ```ts isDummy: Bool; ``` #### Source [lib/provable/merkle-list.ts:556](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L556) *** ### innerProvable ```ts get innerProvable(): ProvableHashable ``` #### Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:744](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L744) *** ### emptyHash ```ts get static emptyHash(): Field ``` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/merkle-list.ts:739](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L739) ## Methods ### \_index() ```ts _index(direction: "next" | "previous", i?: number): number ``` #### Parameters • **direction**: `"next"` \| `"previous"` • **i?**: `number` #### Returns `number` #### Source [lib/provable/merkle-list.ts:483](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L483) *** ### \_updateIndex() ```ts _updateIndex(direction: "next" | "previous"): void ``` #### Parameters • **direction**: `"next"` \| `"previous"` #### Returns `void` #### Source [lib/provable/merkle-list.ts:491](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L491) *** ### assertAtEnd() ```ts assertAtEnd(message?: string): void ``` #### Parameters • **message?**: `string` #### Returns `void` #### Source [lib/provable/merkle-list.ts:452](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L452) *** ### assertAtStart() ```ts assertAtStart(): void ``` #### Returns `void` #### Source [lib/provable/merkle-list.ts:430](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L430) *** ### clone() ```ts clone(): MerkleListIterator ``` #### Returns [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\> #### Source [lib/provable/merkle-list.ts:613](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L613) *** ### isAtEnd() ```ts isAtEnd(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/merkle-list.ts:434](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L434) *** ### isAtStart() ```ts isAtStart(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/merkle-list.ts:459](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L459) *** ### jumpToEnd() ```ts jumpToEnd(): void ``` #### Returns `void` #### Source [lib/provable/merkle-list.ts:438](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L438) *** ### jumpToEndIf() ```ts jumpToEndIf(condition: Bool): void ``` #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/provable/merkle-list.ts:443](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L443) *** ### jumpToStart() ```ts jumpToStart(): void ``` #### Returns `void` #### Source [lib/provable/merkle-list.ts:463](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L463) *** ### jumpToStartIf() ```ts jumpToStartIf(condition: Bool): void ``` #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/provable/merkle-list.ts:470](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L470) *** ### next() ```ts next(): T ``` #### Returns `T` #### Source [lib/provable/merkle-list.ts:529](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L529) *** ### nextHash() ```ts nextHash(hash: Field, value: T): Field ``` #### Parameters • **hash**: [`Field`](Field.mdx) • **value**: `T` #### Returns [`Field`](Field.mdx) #### Source [lib/provable/merkle-list.ts:731](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L731) *** ### previous() ```ts previous(): T ``` #### Returns `T` #### Source [lib/provable/merkle-list.ts:498](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L498) *** ### create() ```ts static create( type: WithProvable>, nextHash: (hash: Field, value: T) => Field, emptyHash_: Field): typeof MerkleListIterator & { "empty": () => MerkleListIterator; "from": (array: T[]) => MerkleListIterator; "provable": ProvableHashable>; "startIterating": (list: MerkleListBase) => MerkleListIterator; "startIteratingFromLast": (list: MerkleListBase) => MerkleListIterator; } ``` Create a Merkle array type #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<[`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\>\> • **nextHash**= `undefined` • **emptyHash\_**: [`Field`](Field.mdx)= `emptyHash` #### Returns *typeof* [`MerkleListIterator`](MerkleListIterator.mdx) & \{ `"empty"`: () => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"from"`: (`array`: `T`[]) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>\>; `"startIterating"`: (`list`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\>) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"startIteratingFromLast"`: (`list`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\>) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; \} #### Source [lib/provable/merkle-list.ts:627](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L627) *** ### createFromList() ```ts static createFromList(merkleList: typeof MerkleList): (value: MerkleListIteratorBase) => MerkleListIterator & { "empty": () => MerkleListIterator; "from": (array: T[]) => MerkleListIterator; "provable": ProvableHashable>; "startIterating": (list: MerkleListBase) => MerkleListIterator; "startIteratingFromLast": (list: MerkleListBase) => MerkleListIterator; } ``` #### Type parameters • **T** #### Parameters • **merkleList**: *typeof* [`MerkleList`](MerkleList.mdx) #### Returns (`value`: [`MerkleListIteratorBase`](../type-aliases/MerkleListIteratorBase.mdx)\<`T`\>) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\> & \{ `"empty"`: () => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"from"`: (`array`: `T`[]) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>\>; `"startIterating"`: (`list`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\>) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; `"startIteratingFromLast"`: (`list`: [`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\>) => [`MerkleListIterator`](MerkleListIterator.mdx)\<`T`\>; \} #### Source [lib/provable/merkle-list.ts:712](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L712) --- url: /zkapps/o1js-reference/classes/MerkleMap --- ## Constructors ### new MerkleMap() ```ts new MerkleMap(): MerkleMap ``` Creates a new, empty Merkle Map. #### Returns [`MerkleMap`](MerkleMap.mdx) A new MerkleMap #### Example ```ts const merkleMap = new MerkleMap(); ``` #### Source [lib/provable/merkle-map.ts:21](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L21) ## Properties ### tree ```ts tree: MerkleTree; ``` #### Source [lib/provable/merkle-map.ts:11](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L11) ## Methods ### \_keyToIndex() ```ts _keyToIndex(key: Field): bigint ``` #### Parameters • **key**: [`Field`](Field.mdx) #### Returns `bigint` #### Source [lib/provable/merkle-map.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L25) *** ### get() ```ts get(key: Field): Field ``` Returns a value given a key. Values are by default Field(0). #### Parameters • **key**: [`Field`](Field.mdx) The key to get the value from. #### Returns [`Field`](Field.mdx) The value stored at the key. #### Example ```ts const key = Field(5); const value = merkleMap.get(key); console.log(value); // Output: the value at key 5 or Field(0) if key does not exist ``` #### Source [lib/provable/merkle-map.ts:71](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L71) *** ### getRoot() ```ts getRoot(): Field ``` Returns the root of the Merkle Map. #### Returns [`Field`](Field.mdx) The root of the Merkle Map. #### Example ```ts const root = merkleMap.getRoot(); ``` #### Source [lib/provable/merkle-map.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L84) *** ### getWitness() ```ts getWitness(key: Field): MerkleMapWitness ``` Returns a circuit-compatible witness (also known as [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof)) for the given key. #### Parameters • **key**: [`Field`](Field.mdx) The key to make a witness for. #### Returns [`MerkleMapWitness`](MerkleMapWitness.mdx) A MerkleMapWitness, which can be used to assert changes to the MerkleMap, and the witness's key. #### Example ```ts const key = Field(5); const witness = merkleMap.getWitness(key); ``` #### Source [lib/provable/merkle-map.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L98) *** ### set() ```ts set(key: Field, value: Field): void ``` Sets a key of the merkle map to a given value. #### Parameters • **key**: [`Field`](Field.mdx) The key to set in the map. • **value**: [`Field`](Field.mdx) The value to set. #### Returns `void` #### Example ```ts const key = Field(5); const value = Field(10); merkleMap.set(key, value); ``` #### Source [lib/provable/merkle-map.ts:55](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L55) --- url: /zkapps/o1js-reference/classes/MerkleMapWitness --- ## Extends - `CircuitValue` ## Constructors ### new MerkleMapWitness() ```ts new MerkleMapWitness(isLefts: Bool[], siblings: Field[]): MerkleMapWitness ``` #### Parameters • **isLefts**: [`Bool`](Bool.mdx)[] • **siblings**: [`Field`](Field.mdx)[] #### Returns [`MerkleMapWitness`](MerkleMapWitness.mdx) #### Overrides `CircuitValue.constructor` #### Source [lib/provable/merkle-map.ts:110](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L110) ## Properties ### isLefts ```ts isLefts: Bool[]; ``` #### Source [lib/provable/merkle-map.ts:107](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L107) *** ### siblings ```ts siblings: Field[]; ``` #### Source [lib/provable/merkle-map.ts:108](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L108) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### computeRootAndKey() ```ts computeRootAndKey(value: Field): Field[] ``` Computes the merkle tree root for a given value and the key for this witness #### Parameters • **value**: [`Field`](Field.mdx) The value to compute the root for. #### Returns [`Field`](Field.mdx)[] A tuple of the computed merkle root, and the key that is connected to the path updated by this witness. #### Source [lib/provable/merkle-map.ts:121](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-map.ts#L121) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### check() ```ts static check(this: T, v: InstanceType): void ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `void` #### Inherited from `CircuitValue.check` #### Source [lib/provable/types/circuit-value.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L163) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromJSON` #### Source [lib/provable/types/circuit-value.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L208) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromValue` #### Source [lib/provable/types/circuit-value.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L98) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L197) *** ### toValue() ```ts static toValue(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toValue` #### Source [lib/provable/types/circuit-value.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L89) --- url: /zkapps/o1js-reference/classes/MerkleTree --- A [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) is a binary tree in which every leaf is the cryptography hash of a piece of data, and every node is the hash of the concatenation of its two child nodes. A Merkle Tree allows developers to easily and securely verify the integrity of large amounts of data. Take a look at our [documentation](https://docs.minaprotocol.com/en/zkapps) on how to use Merkle Trees in combination with zkApps and zero knowledge programming! Levels are indexed from leaves (level 0) to root (level N - 1). ## Constructors ### new MerkleTree() ```ts new MerkleTree(height: number): MerkleTree ``` Creates a new, empty [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree). #### Parameters • **height**: `number` The height of Merkle Tree. #### Returns [`MerkleTree`](MerkleTree.mdx) A new MerkleTree #### Source [lib/provable/merkle-tree.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L37) ## Properties ### height ```ts readonly height: number; ``` The height of Merkle Tree. #### Source [lib/provable/merkle-tree.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L37) *** ### nodes ```ts nodes: Record> = {}; ``` #### Source [lib/provable/merkle-tree.ts:29](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L29) *** ### zeroes ```ts zeroes: Field[]; ``` #### Source [lib/provable/merkle-tree.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L30) ## Accessors ### leafCount ```ts get leafCount(): bigint ``` Returns the amount of leaf nodes. #### Returns `bigint` Amount of leaf nodes. #### Source [lib/provable/merkle-tree.ts:166](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L166) ## Methods ### clone() ```ts clone(): MerkleTree ``` Return a new MerkleTree with the same contents as this one. #### Returns [`MerkleTree`](MerkleTree.mdx) #### Source [lib/provable/merkle-tree.ts:48](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L48) *** ### fill() ```ts fill(leaves: Field[]): void ``` Fills all leaves of the tree. #### Parameters • **leaves**: [`Field`](Field.mdx)[] Values to fill the leaves with. #### Returns `void` #### Source [lib/provable/merkle-tree.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L156) *** ### getLeaf() ```ts getLeaf(key: bigint): Field ``` Returns a leaf at a given index. #### Parameters • **key**: `bigint` #### Returns [`Field`](Field.mdx) The data of the leaf. #### Source [lib/provable/merkle-tree.ts:71](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L71) *** ### getNode() ```ts getNode(level: number, index: bigint): Field ``` Returns a node which lives at a given index and level. #### Parameters • **level**: `number` Level of the node. • **index**: `bigint` Index of the node. #### Returns [`Field`](Field.mdx) The data of the node. #### Source [lib/provable/merkle-tree.ts:62](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L62) *** ### getRoot() ```ts getRoot(): Field ``` Returns the root of the [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree). #### Returns [`Field`](Field.mdx) The root of the Merkle Tree. #### Source [lib/provable/merkle-tree.ts:79](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L79) *** ### getWitness() ```ts getWitness(index: bigint): Witness ``` Returns the witness (also known as [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof)) for the leaf at the given index. #### Parameters • **index**: `bigint` Position of the leaf node. #### Returns [`Witness`](../type-aliases/Witness.mdx) The witness that belongs to the leaf. #### Source [lib/provable/merkle-tree.ts:117](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L117) *** ### setLeaf() ```ts setLeaf(index: bigint, leaf: Field): void ``` Sets the value of a leaf node at a given index to a given value. #### Parameters • **index**: `bigint` Position of the leaf node. • **leaf**: [`Field`](Field.mdx) New value. #### Returns `void` #### Source [lib/provable/merkle-tree.ts:94](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L94) *** ### validate() ```ts validate(index: bigint): boolean ``` Checks if the witness that belongs to the leaf at the given index is a valid witness. #### Parameters • **index**: `bigint` Position of the leaf node. #### Returns `boolean` True if the witness for the leaf node is valid. #### Source [lib/provable/merkle-tree.ts:139](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L139) --- url: /zkapps/o1js-reference/classes/Nullifier --- Nullifiers are used as a public commitment to a specific anonymous account, to forbid actions like double spending, or allow a consistent identity between anonymous actions. RFC: https://github.com/o1-labs/o1js/issues/756 Paper: https://eprint.iacr.org/2022/1255.pdf ## Extends - \{ `"private"`: \{ `"c"`: `Field`; `"g_r"`: `Group`; `"h_m_pk_r"`: `Group`; \}; `"public"`: \{ `"nullifier"`: `Group`; `"s"`: `Scalar`; \}; `"publicKey"`: `Group`; \} ## Constructors ### new Nullifier() ```ts new Nullifier(value: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }): Nullifier ``` #### Parameters • **value** • **value.private**= `undefined` • **value.private.c**: [`Field`](Field.mdx)= `Field` • **value.private.g\_r**: [`Group`](Group.mdx)= `Group` • **value.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **value.public**= `undefined` • **value.public.nullifier**: [`Group`](Group.mdx)= `Group` • **value.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **value.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns [`Nullifier`](Nullifier.mdx) #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).constructor` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) ## Properties ### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` #### c ```ts c: Field = Field; ``` #### g\_r ```ts g_r: Group = Group; ``` #### h\_m\_pk\_r ```ts h_m_pk_r: Group = Group; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).private` #### Source [lib/provable/crypto/nullifier.ts:26](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L26) *** ### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` #### nullifier ```ts nullifier: Group = Group; ``` #### s ```ts s: Scalar = Scalar; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).public` #### Source [lib/provable/crypto/nullifier.ts:22](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L22) *** ### publicKey ```ts publicKey: Group = Group; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).publicKey` #### Source [lib/provable/crypto/nullifier.ts:21](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L21) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, })._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### check() ```ts static check: (value: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.private**= `undefined` • **value.private.c**: [`Field`](Field.mdx)= `Field` • **value.private.g\_r**: [`Group`](Group.mdx)= `Group` • **value.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **value.public**= `undefined` • **value.public.nullifier**: [`Group`](Group.mdx)= `Group` • **value.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **value.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns `void` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### empty() ```ts static empty: () => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` #### Returns ```ts { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } ``` ##### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` ##### private.c ```ts c: Field = Field; ``` ##### private.g\_r ```ts g_r: Group = Group; ``` ##### private.h\_m\_pk\_r ```ts h_m_pk_r: Group = Group; ``` ##### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` ##### public.nullifier ```ts nullifier: Group = Group; ``` ##### public.s ```ts s: Scalar = Scalar; ``` ##### publicKey ```ts publicKey: Group = Group; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[]) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns ```ts { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } ``` ##### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` ##### private.c ```ts c: Field = Field; ``` ##### private.g\_r ```ts g_r: Group = Group; ``` ##### private.h\_m\_pk\_r ```ts h_m_pk_r: Group = Group; ``` ##### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` ##### public.nullifier ```ts nullifier: Group = Group; ``` ##### public.s ```ts s: Scalar = Scalar; ``` ##### publicKey ```ts publicKey: Group = Group; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).fromFields` #### Source [lib/provable/types/provable-intf.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L115) *** ### fromValue ```ts static fromValue: (x: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } | { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } & (value: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.private?**= `undefined` • **value.private.c?**: [`Field`](Field.mdx)= `Field` • **value.private.g\_r?**: [`Group`](Group.mdx)= `Group` • **value.private.h\_m\_pk\_r?**: [`Group`](Group.mdx)= `Group` • **value.public?**= `undefined` • **value.public.nullifier?**: [`Group`](Group.mdx)= `Group` • **value.public.s?**: [`Scalar`](Scalar.mdx)= `Scalar` • **value.publicKey?**: [`Group`](Group.mdx)= `Group` #### Returns `any`[] #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.private**= `undefined` • **x.private.c**: [`Field`](Field.mdx)= `Field` • **x.private.g\_r**: [`Group`](Group.mdx)= `Group` • **x.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **x.public**= `undefined` • **x.public.nullifier**: [`Group`](Group.mdx)= `Group` • **x.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **x.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns ```ts { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } ``` ##### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` ##### private.c ```ts c: Field = Field; ``` ##### private.g\_r ```ts g_r: Group = Group; ``` ##### private.h\_m\_pk\_r ```ts h_m_pk_r: Group = Group; ``` ##### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` ##### public.nullifier ```ts nullifier: Group = Group; ``` ##### public.s ```ts s: Scalar = Scalar; ``` ##### publicKey ```ts publicKey: Group = Group; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.private**= `undefined` • **value.private.c**: [`Field`](Field.mdx)= `Field` • **value.private.g\_r**: [`Group`](Group.mdx)= `Group` • **value.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **value.public**= `undefined` • **value.public.nullifier**: [`Group`](Group.mdx)= `Group` • **value.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **value.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.private**= `undefined` • **x.private.c**: [`Field`](Field.mdx)= `Field` • **x.private.g\_r**: [`Group`](Group.mdx)= `Group` • **x.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **x.public**= `undefined` • **x.public.nullifier**: [`Group`](Group.mdx)= `Group` • **x.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **x.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toInput` #### Source [lib/provable/types/struct.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L152) *** ### toJSON() ```ts static toJSON: (x: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` #### Parameters • **x** • **x.private**= `undefined` • **x.private.c**: [`Field`](Field.mdx)= `Field` • **x.private.g\_r**: [`Group`](Group.mdx)= `Group` • **x.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **x.public**= `undefined` • **x.public.nullifier**: [`Group`](Group.mdx)= `Group` • **x.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **x.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns ```ts { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } ``` ##### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` ##### private.c ```ts c: string = Field; ``` ##### private.g\_r ```ts g_r: { "x": string; "y": string; } = Group; ``` ##### private.g\_r.x ```ts x: string; ``` ##### private.g\_r.y ```ts y: string; ``` ##### private.h\_m\_pk\_r ```ts h_m_pk_r: { "x": string; "y": string; } = Group; ``` ##### private.h\_m\_pk\_r.x ```ts x: string; ``` ##### private.h\_m\_pk\_r.y ```ts y: string; ``` ##### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` ##### public.nullifier ```ts nullifier: { "x": string; "y": string; } = Group; ``` ##### public.nullifier.x ```ts x: string; ``` ##### public.nullifier.y ```ts y: string; ``` ##### public.s ```ts s: string = Scalar; ``` ##### publicKey ```ts publicKey: { "x": string; "y": string; } = Group; ``` ##### publicKey.x ```ts x: string; ``` ##### publicKey.y ```ts y: string; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }) => { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; }; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.private**= `undefined` • **x.private.c**: [`Field`](Field.mdx)= `Field` • **x.private.g\_r**: [`Group`](Group.mdx)= `Group` • **x.private.h\_m\_pk\_r**: [`Group`](Group.mdx)= `Group` • **x.public**= `undefined` • **x.public.nullifier**: [`Group`](Group.mdx)= `Group` • **x.public.s**: [`Scalar`](Scalar.mdx)= `Scalar` • **x.publicKey**: [`Group`](Group.mdx)= `Group` #### Returns ```ts { "private": { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; "public": { "nullifier": Group; "s": Scalar; }; "publicKey": Group; } ``` ##### private ```ts private: { "c": Field; "g_r": Group; "h_m_pk_r": Group; }; ``` ##### private.c ```ts c: bigint = Field; ``` ##### private.g\_r ```ts g_r: { "x": bigint; "y": bigint; } = Group; ``` ##### private.g\_r.x ```ts x: bigint; ``` ##### private.g\_r.y ```ts y: bigint; ``` ##### private.h\_m\_pk\_r ```ts h_m_pk_r: { "x": bigint; "y": bigint; } = Group; ``` ##### private.h\_m\_pk\_r.x ```ts x: bigint; ``` ##### private.h\_m\_pk\_r.y ```ts y: bigint; ``` ##### public ```ts public: { "nullifier": Group; "s": Scalar; }; ``` ##### public.nullifier ```ts nullifier: { "x": bigint; "y": bigint; } = Group; ``` ##### public.nullifier.x ```ts x: bigint; ``` ##### public.nullifier.y ```ts y: bigint; ``` ##### public.s ```ts s: bigint = Scalar; ``` ##### publicKey ```ts publicKey: { "x": bigint; "y": bigint; } = Group; ``` ##### publicKey.x ```ts x: bigint; ``` ##### publicKey.y ```ts y: bigint; ``` #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### assertUnused() ```ts assertUnused(witness: MerkleMapWitness, root: Field): void ``` Checks if the Nullifier has been used before. #### Parameters • **witness**: [`MerkleMapWitness`](MerkleMapWitness.mdx) • **root**: [`Field`](Field.mdx) #### Returns `void` #### Example ```ts // asserts that the nullifier has not been used before, throws an error otherwise nullifier.assertUnused(); ``` #### Source [lib/provable/crypto/nullifier.ts:128](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L128) *** ### getPublicKey() ```ts getPublicKey(): PublicKey ``` Returns the [PublicKey](PublicKey.mdx) that is associated with this Nullifier. #### Returns [`PublicKey`](PublicKey.mdx) #### Example ```ts let pk = nullifier.getPublicKey(); ``` #### Source [lib/provable/crypto/nullifier.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L157) *** ### isUnused() ```ts isUnused(witness: MerkleMapWitness, root: Field): Bool ``` Returns the state of the Nullifier. #### Parameters • **witness**: [`MerkleMapWitness`](MerkleMapWitness.mdx) • **root**: [`Field`](Field.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts // returns a Bool based on whether or not the nullifier has been used before let isUnused = nullifier.isUnused(); ``` #### Source [lib/provable/crypto/nullifier.ts:108](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L108) *** ### key() ```ts key(): Field ``` The key of the nullifier, which belongs to a unique message and a public key. Used as an index in Merkle trees. #### Returns [`Field`](Field.mdx) #### Example ```ts // returns the key of the nullifier which can be used as index in a Merkle tree/map let key = nullifier.key(); ``` #### Source [lib/provable/crypto/nullifier.ts:95](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L95) *** ### setUsed() ```ts setUsed(witness: MerkleMapWitness): Field ``` Sets the Nullifier, returns the new Merkle root. #### Parameters • **witness**: [`MerkleMapWitness`](MerkleMapWitness.mdx) #### Returns [`Field`](Field.mdx) #### Example ```ts // calculates the new root of the Merkle tree in which the nullifier is set to used let newRoot = nullifier.setUsed(witness); ``` #### Source [lib/provable/crypto/nullifier.ts:143](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L143) *** ### verify() ```ts verify(message: Field[]): void ``` Verifies that the Nullifier belongs to a specific message. Throws an error if the Nullifier is incorrect. #### Parameters • **message**: [`Field`](Field.mdx)[] #### Returns `void` #### Example ```ts let nullifierMessage = [voteId, ...otherData]; // throws an error if the nullifier is invalid or doesn't belong to this specific message nullifier.verify(nullifierMessage); ``` #### Source [lib/provable/crypto/nullifier.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L47) *** ### createTestNullifier() ```ts static createTestNullifier(message: Field[], sk: PrivateKey): Nullifier ``` _Note_: This is *not* the recommended way to create a Nullifier in production. Please use mina-signer to create Nullifiers. Also, this function cannot be run within provable code to avoid unintended creations of Nullifiers - a Nullifier should never be created inside proveable code (e.g. a smart contract) directly, but rather created inside the users wallet (or other secure enclaves, so the private key never leaves that enclave). PLUME: An ECDSA Nullifier Scheme for Unique Pseudonymity within Zero Knowledge Proofs https://eprint.iacr.org/2022/1255.pdf chapter 3 page 14 #### Parameters • **message**: [`Field`](Field.mdx)[] • **sk**: [`PrivateKey`](PrivateKey.mdx) #### Returns `Nullifier` #### Source [lib/provable/crypto/nullifier.ts:170](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L170) *** ### fromJSON() ```ts static fromJSON(json: Nullifier): Nullifier ``` #### Parameters • **json**: `Nullifier` #### Returns [`Nullifier`](Nullifier.mdx) #### Overrides `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).fromJSON` #### Source [lib/provable/crypto/nullifier.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/nullifier.ts#L32) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct({ publicKey: Group, public: { nullifier: Group, s: Scalar, }, private: { c: Field, g_r: Group, h_m_pk_r: Group, }, }).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/classes/Packed --- `Packed` is a "packed" representation of any type `T`. "Packed" means that field elements which take up fewer than 254 bits are packed together into as few field elements as possible. For example, you can pack several Bools (1 bit) or UInt32s (32 bits) into a single field element. Using a packed representation can make sense in provable code where the number of constraints depends on the number of field elements per value. For example, `Provable.if(bool, x, y)` takes O(n) constraints, where n is the number of field elements in x and y. Usage: ```ts // define a packed type from a type let PackedType = Packed.create(MyType); // pack a value let packed = PackedType.pack(value); // ... operations on packed values, more efficient than on plain values ... // unpack a value let value = packed.unpack(); ``` **Warning**: Packing only makes sense where packing actually reduces the number of field elements. For example, it doesn't make sense to pack a _single_ Bool, because it will be 1 field element before and after packing. On the other hand, it does makes sense to pack a type that holds 10 or 20 Bools. **Warning**: When wrapping a type with `Packed`, make sure that that type is safe to automatically _pack_ and _unpack_ in provable code. In particular, do not use `Packed` with types that define a custom `toInput()` (specifying a certain bit packing) but no corresponding `check()` method (that constrains the bit lengths of the packed parts). ## Type parameters • **T** ## Constructors ### new Packed() ```ts new Packed(packed: Field[], value: Unconstrained): Packed ``` #### Parameters • **packed**: [`Field`](Field.mdx)[] • **value**: [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Returns [`Packed`](Packed.mdx)\<`T`\> #### Source [lib/provable/packed.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L115) ## Properties ### packed ```ts packed: Field[]; ``` #### Source [lib/provable/packed.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L51) *** ### value ```ts value: Unconstrained; ``` #### Source [lib/provable/packed.ts:52](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L52) *** ### \_innerProvable ```ts static _innerProvable: undefined | ProvableHashable; ``` #### Source [lib/provable/packed.ts:144](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L144) *** ### \_provable ```ts static _provable: undefined | ProvableHashable>; ``` #### Source [lib/provable/packed.ts:143](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L143) ## Accessors ### Constructor ```ts get Constructor(): typeof Packed ``` #### Returns *typeof* [`Packed`](Packed.mdx) #### Source [lib/provable/packed.ts:146](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L146) *** ### innerProvable ```ts get static innerProvable(): ProvableHashable ``` #### Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`any`\> #### Source [lib/provable/packed.ts:150](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L150) ## Methods ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/packed.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L138) *** ### unpack() ```ts unpack(): T ``` Unpack a value. #### Returns `T` #### Source [lib/provable/packed.ts:123](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L123) *** ### create() ```ts static create(type: WithProvable>): typeof Packed & { "provable": ProvableHashable, V>; "pack": Packed; } ``` Create a packed representation of `type`. You can then use `PackedType.pack(x)` to pack a value. #### Type parameters • **T** • **V** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<[`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`, `V`\>\> #### Returns *typeof* [`Packed`](Packed.mdx) & \{ `"provable"`: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`Packed`](Packed.mdx)\<`T`\>, `V`\>; `"pack"`: [`Packed`](Packed.mdx)\<`T`\>; \} #### Source [lib/provable/packed.ts:57](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/packed.ts#L57) --- url: /zkapps/o1js-reference/classes/PrivateKey --- A signing key. You can generate one via [PrivateKey.random](PrivateKey.mdx#random). ## Extends - `CircuitValue` ## Constructors ### new PrivateKey() ```ts new PrivateKey(s: Scalar): PrivateKey ``` #### Parameters • **s**: [`Scalar`](Scalar.mdx) #### Returns [`PrivateKey`](PrivateKey.mdx) #### Overrides `CircuitValue.constructor` #### Source [lib/provable/crypto/signature.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L25) ## Properties ### s ```ts s: Scalar; ``` #### Source [lib/provable/crypto/signature.ts:23](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L23) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### toBase58() ```ts toBase58(): string ``` Encodes a [PrivateKey](PrivateKey.mdx) into a base58 string. #### Returns `string` a base58 encoded string #### Source [lib/provable/crypto/signature.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L105) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this [PrivateKey](PrivateKey.mdx) to a bigint #### Returns `bigint` #### Source [lib/provable/crypto/signature.ts:68](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L68) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### toPublicKey() ```ts toPublicKey(): PublicKey ``` Derives the associated public key. #### Returns [`PublicKey`](PublicKey.mdx) a [PublicKey](PublicKey.mdx). #### Source [lib/provable/crypto/signature.ts:87](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L87) *** ### check() ```ts static check(this: T, v: InstanceType): void ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `void` #### Inherited from `CircuitValue.check` #### Source [lib/provable/types/circuit-value.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L163) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### fromBase58() ```ts static fromBase58(privateKeyBase58: string): PrivateKey ``` Decodes a base58 string into a [PrivateKey](PrivateKey.mdx). #### Parameters • **privateKeyBase58**: `string` #### Returns [`PrivateKey`](PrivateKey.mdx) a [PrivateKey](PrivateKey.mdx). #### Source [lib/provable/crypto/signature.ts:96](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L96) *** ### fromBigInt() ```ts static fromBigInt(sk: bigint): PrivateKey ``` Create a [PrivateKey](PrivateKey.mdx) from a bigint **Warning**: Private keys should be sampled from secure randomness with sufficient entropy. Be careful that you don't use this method to create private keys that were sampled insecurely. #### Parameters • **sk**: `bigint` #### Returns [`PrivateKey`](PrivateKey.mdx) #### Source [lib/provable/crypto/signature.ts:78](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L78) *** ### fromBits() ```ts static fromBits(bs: Bool[]): PrivateKey ``` Deserializes a list of bits into a [PrivateKey](PrivateKey.mdx). #### Parameters • **bs**: [`Bool`](Bool.mdx)[] a list of [Bool](../variables/Bool.mdx). #### Returns [`PrivateKey`](PrivateKey.mdx) a [PrivateKey](PrivateKey.mdx). #### Source [lib/provable/crypto/signature.ts:61](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L61) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromJSON` #### Source [lib/provable/types/circuit-value.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L208) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(this: T, v: bigint | PrivateKey): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `bigint` \| [`PrivateKey`](PrivateKey.mdx) #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromValue` #### Source [lib/provable/crypto/signature.ts:121](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L121) *** ### random() ```ts static random(): PrivateKey ``` Generate a random private key. You can obtain the associated public key via [toPublicKey](PrivateKey.mdx#topublickey). And generate signatures via [Signature.create](Signature.mdx#create). Note: This uses node or browser built-in APIs to obtain cryptographically strong randomness, and can be safely used to generate a real private key. #### Returns [`PrivateKey`](PrivateKey.mdx) a new [PrivateKey](PrivateKey.mdx). #### Source [lib/provable/crypto/signature.ts:40](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L40) *** ### randomKeypair() ```ts static randomKeypair(): { "privateKey": PrivateKey; "publicKey": PublicKey; } ``` Create a random keypair `{ privateKey: PrivateKey, publicKey: PublicKey }`. Note: This uses node or browser built-in APIs to obtain cryptographically strong randomness, and can be safely used to generate a real keypair. #### Returns ```ts { "privateKey": PrivateKey; "publicKey": PublicKey; } ``` ##### privateKey ```ts privateKey: PrivateKey; ``` ##### publicKey ```ts publicKey: PublicKey; ``` #### Source [lib/provable/crypto/signature.ts:50](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L50) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toBase58() ```ts static toBase58(privateKey: { "s": Scalar; }): string ``` Static method to encode a [PrivateKey](PrivateKey.mdx) into a base58 string. #### Parameters • **privateKey** • **privateKey.s**: [`Scalar`](Scalar.mdx) #### Returns `string` a base58 encoded string #### Source [lib/provable/crypto/signature.ts:114](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L114) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L197) *** ### toValue() ```ts static toValue(v: PrivateKey): bigint ``` #### Parameters • **v**: [`PrivateKey`](PrivateKey.mdx) #### Returns `bigint` #### Overrides `CircuitValue.toValue` #### Source [lib/provable/crypto/signature.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L118) --- url: /zkapps/o1js-reference/classes/Proof --- ## Extends - [`ProofBase`](ProofBase.mdx)\<`Input`, `Output`\> ## Type parameters • **Input** • **Output** ## Constructors ### new Proof() ```ts new Proof(__namedParameters: { "maxProofsVerified": 0 | 1 | 2; "proof": unknown; "publicInput": Input; "publicOutput": Output; }): Proof ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.maxProofsVerified**: `0` \| `1` \| `2` • **\_\_namedParameters.proof**: `unknown` • **\_\_namedParameters.publicInput**: `Input` • **\_\_namedParameters.publicOutput**: `Output` #### Returns [`Proof`](Proof.mdx)\<`Input`, `Output`\> #### Inherited from [`ProofBase`](ProofBase.mdx).[`constructor`](ProofBase.mdx#constructors) #### Source [lib/proof-system/proof.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L49) ## Properties ### maxProofsVerified ```ts maxProofsVerified: 0 | 1 | 2; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`maxProofsVerified`](ProofBase.mdx#maxproofsverified) #### Source [lib/proof-system/proof.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L36) *** ### proof ```ts proof: unknown; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`proof`](ProofBase.mdx#proof) #### Source [lib/proof-system/proof.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L35) *** ### publicInput ```ts publicInput: Input; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicInput`](ProofBase.mdx#publicinput) #### Source [lib/proof-system/proof.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L33) *** ### publicOutput ```ts publicOutput: Output; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicOutput`](ProofBase.mdx#publicoutput) #### Source [lib/proof-system/proof.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L34) *** ### shouldVerify ```ts shouldVerify: Bool; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`shouldVerify`](ProofBase.mdx#shouldverify) #### Source [lib/proof-system/proof.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L37) *** ### publicInputType ```ts static publicInputType: FlexibleProvablePure; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicInputType`](ProofBase.mdx#publicinputtype) #### Source [lib/proof-system/proof.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L25) *** ### publicOutputType ```ts static publicOutputType: FlexibleProvablePure; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicOutputType`](ProofBase.mdx#publicoutputtype) #### Source [lib/proof-system/proof.ts:26](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L26) *** ### tag() ```ts static tag: () => { "name": string; }; ``` #### Returns ```ts { "name": string; } ``` ##### name ```ts name: string; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`tag`](ProofBase.mdx#tag) #### Source [lib/proof-system/proof.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L27) ## Accessors ### provable ```ts get static provable(): ProvableProof, any, any> ``` #### Returns `ProvableProof`\<[`Proof`](Proof.mdx)\<`any`, `any`\>, `any`, `any`\> #### Source [lib/proof-system/proof.ts:165](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L165) ## Methods ### publicFields() ```ts publicFields(): { "input": Field[]; "output": Field[]; } ``` #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicFields`](ProofBase.mdx#publicfields) #### Source [lib/proof-system/proof.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L92) *** ### toJSON() ```ts toJSON(): JsonProof ``` #### Returns [`JsonProof`](../type-aliases/JsonProof.mdx) #### Inherited from [`ProofBase`](ProofBase.mdx).[`toJSON`](ProofBase.mdx#tojson) #### Source [lib/proof-system/proof.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L39) *** ### verify() ```ts verify(): void ``` #### Returns `void` #### Source [lib/proof-system/proof.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L98) *** ### verifyIf() ```ts verifyIf(condition: Bool): void ``` #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns `void` #### Source [lib/proof-system/proof.ts:101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L101) *** ### dummy() ```ts static dummy( publicInput: Input, publicOutput: OutPut, maxProofsVerified: 0 | 1 | 2, domainLog2: number): Promise> ``` Dummy proof. This can be useful for ZkPrograms that handle the base case in the same method as the inductive case, using a pattern like this: ```ts method(proof: SelfProof, isRecursive: Bool) { proof.verifyIf(isRecursive); // ... } ``` To use such a method in the base case, you need a dummy proof: ```ts let dummy = await MyProof.dummy(publicInput, publicOutput, 1); await myProgram.myMethod(dummy, Bool(false)); ``` **Note**: The types of `publicInput` and `publicOutput`, as well as the `maxProofsVerified` parameter, must match your ZkProgram. `maxProofsVerified` is the maximum number of proofs that any of your methods take as arguments. #### Type parameters • **Input** • **OutPut** #### Parameters • **publicInput**: `Input` • **publicOutput**: `OutPut` • **maxProofsVerified**: `0` \| `1` \| `2` • **domainLog2**: `number`= `14` #### Returns `Promise`\<[`Proof`](Proof.mdx)\<`Input`, `OutPut`\>\> #### Source [lib/proof-system/proof.ts:150](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L150) *** ### fromJSON() ```ts static fromJSON(this: S, __namedParameters: JsonProof): Promise, InferProvable>> ``` #### Type parameters • **S** *extends* `Subclass`\<*typeof* [`Proof`](Proof.mdx)\> #### Parameters • **this**: `S` • **\_\_namedParameters**: [`JsonProof`](../type-aliases/JsonProof.mdx) #### Returns `Promise`\<[`Proof`](Proof.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicInputType"`\]\>, [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicOutputType"`\]\>\>\> #### Source [lib/proof-system/proof.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L105) *** ### publicFields() ```ts static publicFields(value: ProofBase): { "input": Field[]; "output": Field[]; } ``` #### Parameters • **value**: [`ProofBase`](ProofBase.mdx)\<`any`, `any`\> #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`ProofBase`](ProofBase.mdx).[`publicFields`](ProofBase.mdx#publicfields-1) #### Source [lib/proof-system/proof.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L84) --- url: /zkapps/o1js-reference/classes/ProofBase --- ## Extended by - [`Proof`](Proof.mdx) - [`DynamicProof`](DynamicProof.mdx) ## Type parameters • **Input** = `any` • **Output** = `any` ## Constructors ### new ProofBase() ```ts new ProofBase(__namedParameters: { "maxProofsVerified": 0 | 1 | 2; "proof": unknown; "publicInput": Input; "publicOutput": Output; }): ProofBase ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.maxProofsVerified**: `0` \| `1` \| `2` • **\_\_namedParameters.proof**: `unknown` • **\_\_namedParameters.publicInput**: `Input` • **\_\_namedParameters.publicOutput**: `Output` #### Returns [`ProofBase`](ProofBase.mdx)\<`Input`, `Output`\> #### Source [lib/proof-system/proof.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L49) ## Properties ### maxProofsVerified ```ts maxProofsVerified: 0 | 1 | 2; ``` #### Source [lib/proof-system/proof.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L36) *** ### proof ```ts proof: unknown; ``` #### Source [lib/proof-system/proof.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L35) *** ### publicInput ```ts publicInput: Input; ``` #### Source [lib/proof-system/proof.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L33) *** ### publicOutput ```ts publicOutput: Output; ``` #### Source [lib/proof-system/proof.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L34) *** ### shouldVerify ```ts shouldVerify: Bool; ``` #### Source [lib/proof-system/proof.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L37) *** ### publicInputType ```ts static publicInputType: FlexibleProvablePure; ``` #### Source [lib/proof-system/proof.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L25) *** ### publicOutputType ```ts static publicOutputType: FlexibleProvablePure; ``` #### Source [lib/proof-system/proof.ts:26](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L26) *** ### tag() ```ts static tag: () => { "name": string; }; ``` #### Returns ```ts { "name": string; } ``` ##### name ```ts name: string; ``` #### Source [lib/proof-system/proof.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L27) ## Accessors ### provable ```ts get static provable(): Provable ``` #### Returns `Provable`\<`any`\> #### Source [lib/proof-system/proof.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L66) ## Methods ### publicFields() ```ts publicFields(): { "input": Field[]; "output": Field[]; } ``` #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Source [lib/proof-system/proof.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L92) *** ### toJSON() ```ts toJSON(): JsonProof ``` #### Returns [`JsonProof`](../type-aliases/JsonProof.mdx) #### Source [lib/proof-system/proof.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L39) *** ### publicFields() ```ts static publicFields(value: ProofBase): { "input": Field[]; "output": Field[]; } ``` #### Parameters • **value**: [`ProofBase`](ProofBase.mdx)\<`any`, `any`\> #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Source [lib/proof-system/proof.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L84) --- url: /zkapps/o1js-reference/classes/PublicKey --- A public key, which is also an address on the Mina network. You can derive a [PublicKey](PublicKey.mdx) directly from a [PrivateKey](PrivateKey.mdx). ## Extends - `CircuitValue` ## Constructors ### new PublicKey() ```ts new PublicKey(...props: any[]): PublicKey ``` #### Parameters • ...**props**: `any`[] #### Returns [`PublicKey`](PublicKey.mdx) #### Inherited from `CircuitValue.constructor` #### Source [lib/provable/types/circuit-value.ts:13](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L13) ## Properties ### isOdd ```ts isOdd: Bool; ``` #### Source [lib/provable/crypto/signature.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L138) *** ### x ```ts x: Field; ``` #### Source [lib/provable/crypto/signature.ts:137](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L137) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### isEmpty() ```ts isEmpty(): Bool ``` Checks if a [PublicKey](PublicKey.mdx) is empty. #### Returns [`Bool`](Bool.mdx) a [Bool](../variables/Bool.mdx) #### Source [lib/provable/crypto/signature.ts:193](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L193) *** ### toBase58() ```ts toBase58(): string ``` Encodes a [PublicKey](PublicKey.mdx) in base58 format. #### Returns `string` a base58 encoded [PublicKey](PublicKey.mdx) #### Source [lib/provable/crypto/signature.ts:211](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L211) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toGroup() ```ts toGroup(): Group ``` Returns the [Group](../variables/Group.mdx) representation of this [PublicKey](PublicKey.mdx). #### Returns [`Group`](Group.mdx) A [Group](../variables/Group.mdx) #### Source [lib/provable/crypto/signature.ts:144](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L144) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### check() ```ts static check(this: T, v: InstanceType): void ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `void` #### Inherited from `CircuitValue.check` #### Source [lib/provable/types/circuit-value.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L163) *** ### empty() ```ts static empty(): InstanceType ``` Creates an empty [PublicKey](PublicKey.mdx). #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> an empty [PublicKey](PublicKey.mdx) #### Overrides `CircuitValue.empty` #### Source [lib/provable/crypto/signature.ts:185](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L185) *** ### from() ```ts static from(g: { "isOdd": boolean | Bool; "x": bigint | Field; }): PublicKey ``` Creates a [PublicKey](PublicKey.mdx) from a JSON structure element. #### Parameters • **g** • **g.isOdd**: `boolean` \| [`Bool`](Bool.mdx) • **g.x**: `bigint` \| [`Field`](Field.mdx) #### Returns [`PublicKey`](PublicKey.mdx) a [PublicKey](PublicKey.mdx). #### Source [lib/provable/crypto/signature.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L177) *** ### fromBase58() ```ts static fromBase58(publicKeyBase58: string): PublicKey ``` Decodes a base58 encoded [PublicKey](PublicKey.mdx) into a [PublicKey](PublicKey.mdx). #### Parameters • **publicKeyBase58**: `string` #### Returns [`PublicKey`](PublicKey.mdx) a [PublicKey](PublicKey.mdx) #### Source [lib/provable/crypto/signature.ts:202](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L202) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromGroup() ```ts static fromGroup(__namedParameters: Group): PublicKey ``` Creates a [PublicKey](PublicKey.mdx) from a [Group](../variables/Group.mdx) element. #### Parameters • **\_\_namedParameters**: [`Group`](Group.mdx) #### Returns [`PublicKey`](PublicKey.mdx) a [PublicKey](PublicKey.mdx). #### Source [lib/provable/crypto/signature.ts:161](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L161) *** ### fromJSON() ```ts static fromJSON(this: T, publicKey: string): InstanceType ``` Deserializes a JSON string into a [PublicKey](PublicKey.mdx). #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **publicKey**: `string` #### Returns `InstanceType`\<`T`\> a JSON string #### Overrides `CircuitValue.fromJSON` #### Source [lib/provable/crypto/signature.ts:239](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L239) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromPrivateKey() ```ts static fromPrivateKey(__namedParameters: PrivateKey): PublicKey ``` Derives a [PublicKey](PublicKey.mdx) from a [PrivateKey](PrivateKey.mdx). #### Parameters • **\_\_namedParameters**: [`PrivateKey`](PrivateKey.mdx) #### Returns [`PublicKey`](PublicKey.mdx) a [PublicKey](PublicKey.mdx). #### Source [lib/provable/crypto/signature.ts:169](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L169) *** ### fromValue() ```ts static fromValue(this: T, __namedParameters: { "isOdd": boolean | Bool; "x": bigint | Field; }): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **\_\_namedParameters** • **\_\_namedParameters.isOdd**: `boolean` \| [`Bool`](Bool.mdx) • **\_\_namedParameters.x**: `bigint` \| [`Field`](Field.mdx) #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromValue` #### Source [lib/provable/crypto/signature.ts:246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L246) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toBase58() ```ts static toBase58(__namedParameters: PublicKey): string ``` Static method to encode a [PublicKey](PublicKey.mdx) into base58 format. #### Parameters • **\_\_namedParameters**: [`PublicKey`](PublicKey.mdx) #### Returns `string` a base58 encoded [PublicKey](PublicKey.mdx) #### Source [lib/provable/crypto/signature.ts:219](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L219) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(publicKey: PublicKey): string ``` Serializes a [PublicKey](PublicKey.mdx) into its JSON representation. #### Parameters • **publicKey**: [`PublicKey`](PublicKey.mdx) #### Returns `string` a JSON string #### Overrides `CircuitValue.toJSON` #### Source [lib/provable/crypto/signature.ts:231](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L231) *** ### toValue() ```ts static toValue(__namedParameters: PublicKey): { "isOdd": boolean; "x": bigint; } ``` #### Parameters • **\_\_namedParameters**: [`PublicKey`](PublicKey.mdx) #### Returns ```ts { "isOdd": boolean; "x": bigint; } ``` ##### isOdd ```ts isOdd: boolean; ``` ##### x ```ts x: bigint; ``` #### Overrides `CircuitValue.toValue` #### Source [lib/provable/crypto/signature.ts:243](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L243) --- url: /zkapps/o1js-reference/classes/Scalar --- Represents a [Scalar](Scalar.mdx). ## Implements - `ShiftedScalar` ## Properties ### high254 ```ts high254: Field; ``` #### Implementation of `ShiftedScalar.high254` #### Source [lib/provable/scalar.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L32) *** ### lowBit ```ts lowBit: Bool; ``` We represent a scalar s in shifted form t = s - 2^255 mod q, split into its low bit (t & 1) and high 254 bits (t >> 1). The reason is that we can efficiently compute the scalar multiplication `(t + 2^255) * P = s * P`. #### Implementation of `ShiftedScalar.lowBit` #### Source [lib/provable/scalar.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L31) *** ### ORDER ```ts static ORDER: bigint = Fq.modulus; ``` #### Source [lib/provable/scalar.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L34) ## Methods ### add() ```ts add(y: Scalar): Scalar ``` Add scalar field elements. **Warning**: This method is not available for provable code. #### Parameters • **y**: [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:143](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L143) *** ### div() ```ts div(y: Scalar): Scalar ``` Divide scalar field elements. Throws if the denominator is zero. **Warning**: This method is not available for provable code. #### Parameters • **y**: [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:180](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L180) *** ### isConstant() ```ts isConstant(): boolean ``` Check whether this [Scalar](Scalar.mdx) is a hard-coded constant in the constraint system. If a [Scalar](Scalar.mdx) is constructed outside provable code, it is a constant. #### Returns `boolean` #### Source [lib/provable/scalar.ts:75](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L75) *** ### mul() ```ts mul(y: Scalar): Scalar ``` Multiply scalar field elements. **Warning**: This method is not available for provable code. #### Parameters • **y**: [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:167](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L167) *** ### neg() ```ts neg(): Scalar ``` Negate a scalar field element. **Warning**: This method is not available for provable code. #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:132](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L132) *** ### sub() ```ts sub(y: Scalar): Scalar ``` Subtract scalar field elements. **Warning**: This method is not available for provable code. #### Parameters • **y**: [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:155](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L155) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this [Scalar](Scalar.mdx) into a bigint #### Returns `bigint` #### Source [lib/provable/scalar.ts:95](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L95) *** ### toConstant() ```ts toConstant(): Scalar ``` Convert this [Scalar](Scalar.mdx) into a constant if it isn't already. If the scalar is a variable, this only works inside `asProver` or `witness` blocks. See FieldVar for an explanation of constants vs. variables. #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:87](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L87) *** ### toFields() ```ts toFields(): Field[] ``` Serialize this Scalar to Field elements. **Warning**: This function is for internal usage. It returns 255 field elements which represent the Scalar in a shifted, bitwise format. The fields are not constrained to be boolean. Check out [Scalar.toFieldsCompressed](Scalar.mdx#tofieldscompressed) for a user-friendly serialization that can be used outside proofs. #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/scalar.ts:233](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L233) *** ### toFieldsCompressed() ```ts toFieldsCompressed(): { "field": Field; "highBit": Bool; } ``` Serialize a Scalar into a Field element plus one bit, where the bit is represented as a Bool. **Warning**: This method is not available for provable code. Note: Since the Scalar field is slightly larger than the base Field, an additional high bit is needed to represent all Scalars. However, for a random Scalar, the high bit will be `false` with overwhelming probability. #### Returns ```ts { "field": Field; "highBit": Bool; } ``` ##### field ```ts field: Field; ``` ##### highBit ```ts highBit: Bool; ``` #### Source [lib/provable/scalar.ts:196](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L196) *** ### toJSON() ```ts toJSON(): string ``` Serializes this Scalar to a string #### Returns `string` #### Source [lib/provable/scalar.ts:325](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L325) *** ### check() ```ts static check(s: Scalar): void ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. #### Parameters • **s**: [`Scalar`](Scalar.mdx) #### Returns `void` #### Source [lib/provable/scalar.ts:287](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L287) *** ### empty() ```ts static empty(): Scalar ``` #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:337](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L337) *** ### from() ```ts static from(s: string | number | bigint | Scalar): Scalar ``` Create a constant [Scalar](Scalar.mdx) from a bigint, number, string or Scalar. If the input is too large, it is reduced modulo the scalar field size. #### Parameters • **s**: `string` \| `number` \| `bigint` \| [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:46](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L46) *** ### fromBits() ```ts static fromBits(bits: Bool[]): Scalar ``` Creates a Scalar from an array of [Bool](Bool.mdx). This method is provable. #### Parameters • **bits**: [`Bool`](Bool.mdx)[] #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L105) *** ### fromField() ```ts static fromField(s: Field): Scalar ``` Provable method to convert a [Field](Field.mdx) into a [Scalar](Scalar.mdx). This is always possible and unambiguous, since the scalar field is larger than the base field. #### Parameters • **s**: [`Field`](Field.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L66) *** ### fromFields() ```ts static fromFields(fields: Field[]): Scalar ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Creates a data structure from an array of serialized [Field](Field.mdx) elements. #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:265](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L265) *** ### fromJSON() ```ts static fromJSON(x: string): Scalar ``` Deserialize a JSON structure into a [Scalar](Scalar.mdx). This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Scalar. #### Parameters • **x**: `string` #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:333](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L333) *** ### fromShiftedScalar() ```ts static fromShiftedScalar(s: ShiftedScalar): Scalar ``` Provable method to convert a ShiftedScalar to a [Scalar](Scalar.mdx). #### Parameters • **s**: `ShiftedScalar` #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:57](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L57) *** ### fromValue() ```ts static fromValue(x: bigint): Scalar ``` #### Parameters • **x**: `bigint` #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:307](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L307) *** ### random() ```ts static random(): Scalar ``` Returns a random [Scalar](Scalar.mdx). Randomness can not be proven inside a circuit! #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:121](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L121) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Returns the size of this type in [Field](Field.mdx) elements. #### Returns `number` #### Source [lib/provable/scalar.ts:280](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L280) *** ### toAuxiliary() ```ts static toAuxiliary(): never[] ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Serialize a [Scalar](Scalar.mdx) into its auxiliary data, which are empty. #### Returns `never`[] #### Source [lib/provable/scalar.ts:256](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L256) *** ### toCanonical() ```ts static toCanonical(s: Scalar): Scalar ``` #### Parameters • **s**: [`Scalar`](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar.ts:295](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L295) *** ### toFields() ```ts static toFields(x: Scalar): Field[] ``` Part of the [Provable](../type-aliases/Provable.mdx) interface. Serialize a [Scalar](Scalar.mdx) into an array of [Field](Field.mdx) elements. **Warning**: This function is for internal usage. It returns 255 field elements which represent the Scalar in a shifted, bitwise format. The fields are not constrained to be boolean. #### Parameters • **x**: [`Scalar`](Scalar.mdx) #### Returns [`Field`](Field.mdx)[] #### Source [lib/provable/scalar.ts:219](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L219) *** ### toInput() ```ts static toInput(x: Scalar): HashInput ``` **Warning**: This function is mainly for internal use. Normally it is not intended to be used by a zkApp developer. This function is the implementation of `ProvableExtended.toInput()` for the [Scalar](Scalar.mdx) type. #### Parameters • **x**: [`Scalar`](Scalar.mdx) #### Returns `HashInput` An object where the `fields` key is a [Field](Field.mdx) array of length 1 created from this [Field](Field.mdx). #### Source [lib/provable/scalar.ts:247](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L247) *** ### toJSON() ```ts static toJSON(x: Scalar): string ``` Serialize a [Scalar](Scalar.mdx) to a JSON string. This operation does _not_ affect the circuit and can't be used to prove anything about the string representation of the Scalar. #### Parameters • **x**: [`Scalar`](Scalar.mdx) #### Returns `string` #### Source [lib/provable/scalar.ts:317](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L317) *** ### toValue() ```ts static toValue(x: Scalar): bigint ``` #### Parameters • **x**: [`Scalar`](Scalar.mdx) #### Returns `bigint` #### Source [lib/provable/scalar.ts:303](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L303) --- url: /zkapps/o1js-reference/classes/ScalarField --- ForeignField representing the scalar field of Pallas and the base field of Vesta ## Extends - `UnreducedForeignField`\<`this`\> ## Constructors ### new ScalarField() ```ts new ScalarField(x: | string | number | bigint | Field3 | ForeignField): ScalarField ``` Create a new [ForeignField](ForeignField.mdx) from a bigint, number, string or another ForeignField. #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `Field3` \| [`ForeignField`](ForeignField.mdx) #### Returns [`ScalarField`](ScalarField.mdx) #### Inherited from `createForeignField(Fq.modulus).constructor` #### Example ```ts let x = new ForeignField(5); ``` Note: Inputs must be range checked if they originate from a different field with a different modulus or if they are not constants. - When constructing from another [ForeignField](ForeignField.mdx) instance, ensure the modulus matches. If not, check the modulus using `Gadgets.ForeignField.assertLessThan()` and handle appropriately. - When constructing from a Field3 array, ensure all elements are valid Field elements and range checked. - Ensure constants are correctly reduced to the modulus of the field. #### Source [lib/provable/foreign-field.ts:101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L101) ## Properties ### type ```ts type: "Unreduced" | "AlmostReduced" | "FullyReduced" = 'Unreduced'; ``` #### Inherited from `createForeignField(Fq.modulus).type` #### Source [lib/provable/foreign-field.ts:469](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L469) *** ### value ```ts value: Field3; ``` The internal representation of a foreign field element, as a tuple of 3 limbs. #### Inherited from `createForeignField(Fq.modulus).value` #### Source [lib/provable/foreign-field.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L49) *** ### \_Bigint ```ts static _Bigint: undefined | {} = undefined; ``` #### Inherited from `createForeignField(Fq.modulus)._Bigint` #### Source [lib/provable/foreign-field.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L27) *** ### \_modulus ```ts static _modulus: undefined | bigint = undefined; ``` #### Inherited from `createForeignField(Fq.modulus)._modulus` #### Source [lib/provable/foreign-field.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L28) *** ### \_provable ```ts static _provable: undefined | ProvablePureExtended = undefined; ``` #### Inherited from `createForeignField(Fq.modulus)._provable` #### Source [lib/provable/foreign-field.ts:471](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L471) *** ### \_variants ```ts static _variants: undefined | { "almostReduced": typeof AlmostForeignField; "canonical": typeof CanonicalForeignField; "unreduced": typeof UnreducedForeignField; } = undefined; ``` Sibling classes that represent different ranges of field elements. #### Inherited from `createForeignField(Fq.modulus)._variants` #### Source [lib/provable/foreign-field.ts:58](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L58) ## Accessors ### Constructor ```ts get Constructor(): typeof ForeignField ``` #### Returns *typeof* [`ForeignField`](ForeignField.mdx) #### Source [lib/provable/foreign-field.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L51) *** ### modulus ```ts get modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L39) *** ### AlmostReduced ```ts get static AlmostReduced(): typeof AlmostForeignField ``` Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). #### Returns *typeof* [`AlmostForeignField`](AlmostForeignField.mdx) #### Source [lib/provable/foreign-field.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L76) *** ### Bigint ```ts get static Bigint(): {} ``` #### Returns ```ts {} ``` #### Source [lib/provable/foreign-field.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L31) *** ### Canonical ```ts get static Canonical(): typeof CanonicalForeignField ``` Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). #### Returns *typeof* [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Source [lib/provable/foreign-field.ts:83](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L83) *** ### Unreduced ```ts get static Unreduced(): typeof UnreducedForeignField ``` Constructor for unreduced field elements. #### Returns *typeof* `UnreducedForeignField` #### Source [lib/provable/foreign-field.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L69) *** ### modulus ```ts get static modulus(): bigint ``` #### Returns `bigint` #### Source [lib/provable/foreign-field.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L35) *** ### provable ```ts get static provable(): ProvablePureExtended ``` #### Returns `ProvablePureExtended`\<`UnreducedForeignField`, `bigint`, `string`\> #### Source [lib/provable/foreign-field.ts:474](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L474) *** ### sizeInBits ```ts get static sizeInBits(): number ``` #### Returns `number` #### Source [lib/provable/foreign-field.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L42) ## Methods ### add() ```ts add(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field addition #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `createForeignField(Fq.modulus).add` #### Example ```ts x.add(2); // x + 2 mod p ``` #### Source [lib/provable/foreign-field.ts:218](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L218) *** ### assertAlmostReduced() ```ts assertAlmostReduced(): AlmostForeignField ``` Assert that this field element lies in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. Returns the field element as a [AlmostForeignField](AlmostForeignField.mdx). For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1). Note: this does not ensure that the field elements is in the canonical range [0, p). To assert that stronger property, there is [assertCanonical](ForeignField.mdx#assertcanonical). You should typically use [assertAlmostReduced](ForeignField.mdx#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for ensuring validity of all our non-native field arithmetic methods. #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:173](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L173) *** ### assertCanonical() ```ts assertCanonical(): CanonicalForeignField ``` Assert that this field element is fully reduced, i.e. lies in the range [0, p), where p is the foreign field modulus. Returns the field element as a [CanonicalForeignField](CanonicalForeignField.mdx). #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).assertCanonical` #### Source [lib/provable/foreign-field.ts:204](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L204) *** ### assertEquals() #### assertEquals(y, message) ```ts assertEquals(y: number | bigint | CanonicalForeignField, message?: string): CanonicalForeignField ``` Assert equality with a ForeignField-like value ##### Parameters • **y**: `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.mdx) • **message?**: `string` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `createForeignField(Fq.modulus).assertEquals` ##### Example ```ts x.assertEquals(0, "x is zero"); ``` Since asserting equality can also serve as a range check, this method returns `x` with the appropriate type: ##### Example ```ts let xChecked = x.assertEquals(1, "x is 1"); xChecked satisfies CanonicalForeignField; ``` ##### Source [lib/provable/foreign-field.ts:296](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L296) #### assertEquals(y, message) ```ts assertEquals(y: AlmostForeignField, message?: string): AlmostForeignField ``` ##### Parameters • **y**: [`AlmostForeignField`](AlmostForeignField.mdx) • **message?**: `string` ##### Returns [`AlmostForeignField`](AlmostForeignField.mdx) ##### Inherited from `createForeignField(Fq.modulus).assertEquals` ##### Source [lib/provable/foreign-field.ts:300](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L300) #### assertEquals(y, message) ```ts assertEquals(y: ForeignField, message?: string): ForeignField ``` ##### Parameters • **y**: [`ForeignField`](ForeignField.mdx) • **message?**: `string` ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `createForeignField(Fq.modulus).assertEquals` ##### Source [lib/provable/foreign-field.ts:301](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L301) *** ### assertLessThan() ```ts assertLessThan(c: number | bigint, message?: string): void ``` Assert that this field element is less than a constant c: `x < c`. The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. #### Parameters • **c**: `number` \| `bigint` • **message?**: `string` #### Returns `void` #### Inherited from `createForeignField(Fq.modulus).assertLessThan` #### Example ```ts x.assertLessThan(10); ``` #### Source [lib/provable/foreign-field.ts:339](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L339) *** ### isConstant() ```ts isConstant(): boolean ``` Checks whether this field element is a constant. See FieldVar to understand constants vs variables. #### Returns `boolean` #### Inherited from `createForeignField(Fq.modulus).isConstant` #### Source [lib/provable/foreign-field.ts:136](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L136) *** ### neg() ```ts neg(): AlmostForeignField ``` Finite field negation #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).neg` #### Example ```ts x.neg(); // -x mod p = p - x ``` #### Source [lib/provable/foreign-field.ts:229](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L229) *** ### sub() ```ts sub(y: number | bigint | ForeignField): UnreducedForeignField ``` Finite field subtraction #### Parameters • **y**: `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) #### Returns `UnreducedForeignField` #### Inherited from `createForeignField(Fq.modulus).sub` #### Example ```ts x.sub(1); // x - 1 mod p ``` #### Source [lib/provable/foreign-field.ts:244](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L244) *** ### toBigInt() ```ts toBigInt(): bigint ``` Convert this field element to a bigint. #### Returns `bigint` #### Inherited from `createForeignField(Fq.modulus).toBigInt` #### Source [lib/provable/foreign-field.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L156) *** ### toBits() ```ts toBits(length?: number): Bool[] ``` Unpack a field element to its bits, as a [Bool](Bool.mdx)[] array. This method is provable! #### Parameters • **length?**: `number` #### Returns [`Bool`](Bool.mdx)[] #### Inherited from `createForeignField(Fq.modulus).toBits` #### Source [lib/provable/foreign-field.ts:358](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L358) *** ### toConstant() ```ts toConstant(): ForeignField ``` Convert this field element to a constant. See FieldVar to understand constants vs variables. **Warning**: This function is only useful in Provable.witness or Provable.asProver blocks, that is, in situations where the prover computes a value outside provable code. #### Returns [`ForeignField`](ForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).toConstant` #### Source [lib/provable/foreign-field.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L148) *** ### toFields() ```ts toFields(): Field[] ``` Instance version of `Provable.toFields`, see Provable.toFields #### Returns [`Field`](Field.mdx)[] #### Inherited from `createForeignField(Fq.modulus).toFields` #### Source [lib/provable/foreign-field.ts:406](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L406) *** ### toScalar() ```ts toScalar(): Scalar ``` Provable method to convert a [ScalarField](ScalarField.mdx) into a [Scalar](Scalar.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar-field.ts:16](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar-field.ts#L16) *** ### assertAlmostReduced() ```ts static assertAlmostReduced(...xs: T): [...{ [i in string | number | symbol]: AlmostForeignField }[]] ``` Assert that one or more field elements lie in the range [0, 2^k), where k = ceil(log2(p)) and p is the foreign field modulus. This is most efficient than when checking a multiple of 3 field elements at once. #### Type parameters • **T** *extends* `Tuple`\<[`ForeignField`](ForeignField.mdx)\> #### Parameters • ...**xs**: `T` #### Returns [...\{ [i in string \| number \| symbol]: AlmostForeignField \}[]] #### Inherited from `createForeignField(Fq.modulus).assertAlmostReduced` #### Source [lib/provable/foreign-field.ts:187](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L187) *** ### check() ```ts static check(x: ForeignField): void ``` #### Parameters • **x**: [`ForeignField`](ForeignField.mdx) #### Returns `void` #### Inherited from `createForeignField(Fq.modulus).check` #### Source [lib/provable/foreign-field.ts:479](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L479) *** ### from() #### from(x) ```ts static from(x: string | number | bigint): CanonicalForeignField ``` Coerce the input to a [ForeignField](ForeignField.mdx). ##### Parameters • **x**: `string` \| `number` \| `bigint` ##### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) ##### Inherited from `createForeignField(Fq.modulus).from` ##### Source [lib/provable/foreign-field.ts:124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L124) #### from(x) ```ts static from(x: string | number | bigint | ForeignField): ForeignField ``` ##### Parameters • **x**: `string` \| `number` \| `bigint` \| [`ForeignField`](ForeignField.mdx) ##### Returns [`ForeignField`](ForeignField.mdx) ##### Inherited from `createForeignField(Fq.modulus).from` ##### Source [lib/provable/foreign-field.ts:125](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L125) *** ### fromBits() ```ts static fromBits(bits: Bool[]): AlmostForeignField ``` Create a field element from its bits, as a `Bool[]` array. This method is provable! #### Parameters • **bits**: [`Bool`](Bool.mdx)[] #### Returns [`AlmostForeignField`](AlmostForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).fromBits` #### Source [lib/provable/foreign-field.ts:388](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L388) *** ### fromScalar() ```ts static fromScalar(s: Scalar): ScalarField ``` Converts this [Scalar](Scalar.mdx) into a [ScalarField](ScalarField.mdx) #### Parameters • **s**: [`Scalar`](Scalar.mdx) #### Returns [`ScalarField`](ScalarField.mdx) #### Source [lib/provable/scalar-field.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar-field.ts#L34) *** ### random() ```ts static random(): CanonicalForeignField ``` #### Returns [`CanonicalForeignField`](CanonicalForeignField.mdx) #### Inherited from `createForeignField(Fq.modulus).random` #### Source [lib/provable/foreign-field.ts:399](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L399) *** ### sum() ```ts static sum(xs: (number | bigint | ForeignField)[], operations: (-1 | 1)[]): UnreducedForeignField ``` Sum (or difference) of multiple finite field elements. #### Parameters • **xs**: (`number` \| `bigint` \| [`ForeignField`](ForeignField.mdx))[] • **operations**: (`-1` \| `1`)[] #### Returns `UnreducedForeignField` #### Inherited from `createForeignField(Fq.modulus).sum` #### Example ```ts let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 z.assertEquals(2); ``` This method expects a list of ForeignField-like values, `x0,...,xn`, and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), and returns `x0 + op1*x1 + ... + opn*xn` where the sum is computed in finite field arithmetic. **Important:** For more than two summands, this is significantly more efficient than chaining calls to [ForeignField.add](ForeignField.mdx#add) and [ForeignField.sub](ForeignField.mdx#sub). #### Source [lib/provable/foreign-field.ts:269](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L269) *** ### toScalar() ```ts static toScalar(field: ForeignField): Scalar ``` #### Parameters • **field**: [`ForeignField`](ForeignField.mdx) #### Returns [`Scalar`](Scalar.mdx) #### Source [lib/provable/scalar-field.ts:20](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar-field.ts#L20) --- url: /zkapps/o1js-reference/classes/SelfProof --- ## Extends - [`Proof`](Proof.mdx)\<`PublicInput`, `PublicOutput`\> ## Type parameters • **PublicInput** • **PublicOutput** ## Constructors ### new SelfProof() ```ts new SelfProof(__namedParameters: { "maxProofsVerified": 0 | 1 | 2; "proof": unknown; "publicInput": PublicInput; "publicOutput": PublicOutput; }): SelfProof ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.maxProofsVerified**: `0` \| `1` \| `2` • **\_\_namedParameters.proof**: `unknown` • **\_\_namedParameters.publicInput**: `PublicInput` • **\_\_namedParameters.publicOutput**: `PublicOutput` #### Returns [`SelfProof`](SelfProof.mdx)\<`PublicInput`, `PublicOutput`\> #### Inherited from [`Proof`](Proof.mdx).[`constructor`](Proof.mdx#constructors) #### Source [lib/proof-system/proof.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L49) ## Properties ### maxProofsVerified ```ts maxProofsVerified: 0 | 1 | 2; ``` #### Inherited from [`Proof`](Proof.mdx).[`maxProofsVerified`](Proof.mdx#maxproofsverified) #### Source [lib/proof-system/proof.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L36) *** ### proof ```ts proof: unknown; ``` #### Inherited from [`Proof`](Proof.mdx).[`proof`](Proof.mdx#proof) #### Source [lib/proof-system/proof.ts:35](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L35) *** ### publicInput ```ts publicInput: PublicInput; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicInput`](Proof.mdx#publicinput) #### Source [lib/proof-system/proof.ts:33](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L33) *** ### publicOutput ```ts publicOutput: PublicOutput; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicOutput`](Proof.mdx#publicoutput) #### Source [lib/proof-system/proof.ts:34](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L34) *** ### shouldVerify ```ts shouldVerify: Bool; ``` #### Inherited from [`Proof`](Proof.mdx).[`shouldVerify`](Proof.mdx#shouldverify) #### Source [lib/proof-system/proof.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L37) *** ### publicInputType ```ts static publicInputType: FlexibleProvablePure; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicInputType`](Proof.mdx#publicinputtype) #### Source [lib/proof-system/proof.ts:25](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L25) *** ### publicOutputType ```ts static publicOutputType: FlexibleProvablePure; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicOutputType`](Proof.mdx#publicoutputtype) #### Source [lib/proof-system/proof.ts:26](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L26) *** ### tag() ```ts static tag: () => { "name": string; }; ``` #### Returns ```ts { "name": string; } ``` ##### name ```ts name: string; ``` #### Inherited from [`Proof`](Proof.mdx).[`tag`](Proof.mdx#tag) #### Source [lib/proof-system/proof.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L27) ## Accessors ### provable ```ts get static provable(): ProvableProof, any, any> ``` #### Returns `ProvableProof`\<[`Proof`](Proof.mdx)\<`any`, `any`\>, `any`, `any`\> #### Source [lib/proof-system/proof.ts:165](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L165) ## Methods ### publicFields() ```ts publicFields(): { "input": Field[]; "output": Field[]; } ``` #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicFields`](Proof.mdx#publicfields) #### Source [lib/proof-system/proof.ts:92](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L92) *** ### toJSON() ```ts toJSON(): JsonProof ``` #### Returns [`JsonProof`](../type-aliases/JsonProof.mdx) #### Inherited from [`Proof`](Proof.mdx).[`toJSON`](Proof.mdx#tojson) #### Source [lib/proof-system/proof.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L39) *** ### verify() ```ts verify(): void ``` #### Returns `void` #### Inherited from [`Proof`](Proof.mdx).[`verify`](Proof.mdx#verify) #### Source [lib/proof-system/proof.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L98) *** ### verifyIf() ```ts verifyIf(condition: Bool): void ``` #### Parameters • **condition**: [`Bool`](Bool.mdx) #### Returns `void` #### Inherited from [`Proof`](Proof.mdx).[`verifyIf`](Proof.mdx#verifyif) #### Source [lib/proof-system/proof.ts:101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L101) *** ### dummy() ```ts static dummy( publicInput: Input, publicOutput: OutPut, maxProofsVerified: 0 | 1 | 2, domainLog2: number): Promise> ``` Dummy proof. This can be useful for ZkPrograms that handle the base case in the same method as the inductive case, using a pattern like this: ```ts method(proof: SelfProof, isRecursive: Bool) { proof.verifyIf(isRecursive); // ... } ``` To use such a method in the base case, you need a dummy proof: ```ts let dummy = await MyProof.dummy(publicInput, publicOutput, 1); await myProgram.myMethod(dummy, Bool(false)); ``` **Note**: The types of `publicInput` and `publicOutput`, as well as the `maxProofsVerified` parameter, must match your ZkProgram. `maxProofsVerified` is the maximum number of proofs that any of your methods take as arguments. #### Type parameters • **Input** • **OutPut** #### Parameters • **publicInput**: `Input` • **publicOutput**: `OutPut` • **maxProofsVerified**: `0` \| `1` \| `2` • **domainLog2**: `number`= `14` #### Returns `Promise`\<[`Proof`](Proof.mdx)\<`Input`, `OutPut`\>\> #### Inherited from [`Proof`](Proof.mdx).[`dummy`](Proof.mdx#dummy) #### Source [lib/proof-system/proof.ts:150](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L150) *** ### fromJSON() ```ts static fromJSON(this: S, __namedParameters: JsonProof): Promise, InferProvable>> ``` #### Type parameters • **S** *extends* `Subclass`\<*typeof* [`Proof`](Proof.mdx)\> #### Parameters • **this**: `S` • **\_\_namedParameters**: [`JsonProof`](../type-aliases/JsonProof.mdx) #### Returns `Promise`\<[`Proof`](Proof.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicInputType"`\]\>, [`InferProvable`](../type-aliases/InferProvable.mdx)\<`S`\[`"publicOutputType"`\]\>\>\> #### Inherited from [`Proof`](Proof.mdx).[`fromJSON`](Proof.mdx#fromjson) #### Source [lib/proof-system/proof.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L105) *** ### publicFields() ```ts static publicFields(value: ProofBase): { "input": Field[]; "output": Field[]; } ``` #### Parameters • **value**: [`ProofBase`](ProofBase.mdx)\<`any`, `any`\> #### Returns ```ts { "input": Field[]; "output": Field[]; } ``` ##### input ```ts input: Field[]; ``` ##### output ```ts output: Field[]; ``` #### Inherited from [`Proof`](Proof.mdx).[`publicFields`](Proof.mdx#publicfields-1) #### Source [lib/proof-system/proof.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/proof.ts#L84) --- url: /zkapps/o1js-reference/classes/Sign --- ## Extends - `CircuitValue` ## Constructors ### new Sign() ```ts new Sign(...props: any[]): Sign ``` #### Parameters • ...**props**: `any`[] #### Returns [`Sign`](Sign.mdx) #### Inherited from `CircuitValue.constructor` #### Source [lib/provable/types/circuit-value.ts:13](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L13) ## Properties ### value ```ts value: Field; ``` #### Source [lib/provable/int.ts:1034](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1034) ## Accessors ### minusOne ```ts get static minusOne(): Sign ``` #### Returns [`Sign`](Sign.mdx) #### Source [lib/provable/int.ts:1039](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1039) *** ### one ```ts get static one(): Sign ``` #### Returns [`Sign`](Sign.mdx) #### Source [lib/provable/int.ts:1036](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1036) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### isNegative() ```ts isNegative(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:1071](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1071) *** ### isPositive() ```ts isPositive(): Bool ``` #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:1068](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1068) *** ### mul() ```ts mul(y: Sign): Sign ``` #### Parameters • **y**: [`Sign`](Sign.mdx) #### Returns [`Sign`](Sign.mdx) #### Source [lib/provable/int.ts:1065](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1065) *** ### neg() ```ts neg(): Sign ``` #### Returns [`Sign`](Sign.mdx) #### Source [lib/provable/int.ts:1062](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1062) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### toString() ```ts toString(): string ``` #### Returns `string` #### Source [lib/provable/int.ts:1075](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1075) *** ### check() ```ts static check(x: Sign): void ``` #### Parameters • **x**: [`Sign`](Sign.mdx) #### Returns `void` #### Overrides `CircuitValue.check` #### Source [lib/provable/int.ts:1042](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1042) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.empty` #### Source [lib/provable/int.ts:1046](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1046) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(x: "Positive" | "Negative"): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `"Positive"` \| `"Negative"` #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromJSON` #### Source [lib/provable/int.ts:1057](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1057) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(x: bigint | Sign): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `bigint` \| [`Sign`](Sign.mdx) #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromValue` #### Source [lib/provable/int.ts:1083](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1083) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(x: Sign): HashInput ``` #### Parameters • **x**: [`Sign`](Sign.mdx) #### Returns `HashInput` #### Overrides `CircuitValue.toInput` #### Source [lib/provable/int.ts:1049](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1049) *** ### toJSON() ```ts static toJSON(x: Sign): "Positive" | "Negative" ``` #### Parameters • **x**: [`Sign`](Sign.mdx) #### Returns `"Positive"` \| `"Negative"` #### Overrides `CircuitValue.toJSON` #### Source [lib/provable/int.ts:1052](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1052) *** ### toValue() ```ts static toValue(x: Sign): Sign ``` #### Parameters • **x**: [`Sign`](Sign.mdx) #### Returns `Sign` #### Overrides `CircuitValue.toValue` #### Source [lib/provable/int.ts:1079](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1079) --- url: /zkapps/o1js-reference/classes/Signature --- A Schnorr [Signature](Signature.mdx) over the Pasta Curves. ## Extends - `CircuitValue` ## Constructors ### new Signature() ```ts new Signature(...props: any[]): Signature ``` #### Parameters • ...**props**: `any`[] #### Returns [`Signature`](Signature.mdx) #### Inherited from `CircuitValue.constructor` #### Source [lib/provable/types/circuit-value.ts:13](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L13) ## Properties ### r ```ts r: Field; ``` #### Source [lib/provable/crypto/signature.ts:258](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L258) *** ### s ```ts s: Scalar; ``` #### Source [lib/provable/crypto/signature.ts:259](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L259) ## Methods ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### toBase58() ```ts toBase58(): string ``` Encodes a [Signature](Signature.mdx) in base58 format. #### Returns `string` #### Source [lib/provable/crypto/signature.ts:321](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L321) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### verify() ```ts verify(publicKey: PublicKey, msg: Field[]): Bool ``` Verifies the [Signature](Signature.mdx) using a message and the corresponding [PublicKey](PublicKey.mdx). #### Parameters • **publicKey**: [`PublicKey`](PublicKey.mdx) • **msg**: [`Field`](Field.mdx)[] #### Returns [`Bool`](Bool.mdx) a [Bool](../variables/Bool.mdx) #### Source [lib/provable/crypto/signature.ts:296](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L296) *** ### check() ```ts static check(this: T, v: InstanceType): void ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `void` #### Inherited from `CircuitValue.check` #### Source [lib/provable/types/circuit-value.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L163) *** ### create() ```ts static create(privKey: PrivateKey, msg: Field[]): Signature ``` Signs a message using a [PrivateKey](PrivateKey.mdx). #### Parameters • **privKey**: [`PrivateKey`](PrivateKey.mdx) • **msg**: [`Field`](Field.mdx)[] #### Returns [`Signature`](Signature.mdx) a [Signature](Signature.mdx) #### Source [lib/provable/crypto/signature.ts:265](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L265) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### fromBase58() ```ts static fromBase58(signatureBase58: string): Signature ``` Decodes a base58 encoded signature into a [Signature](Signature.mdx). #### Parameters • **signatureBase58**: `string` #### Returns [`Signature`](Signature.mdx) #### Source [lib/provable/crypto/signature.ts:314](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/signature.ts#L314) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromJSON` #### Source [lib/provable/types/circuit-value.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L208) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(this: T, value: any): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `any` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromValue` #### Source [lib/provable/types/circuit-value.ts:98](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L98) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(this: T, v: InstanceType): HashInput ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `HashInput` #### Inherited from `CircuitValue.toInput` #### Source [lib/provable/types/circuit-value.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L63) *** ### toJSON() ```ts static toJSON(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L197) *** ### toValue() ```ts static toValue(this: T, v: InstanceType): any ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns `any` #### Inherited from `CircuitValue.toValue` #### Source [lib/provable/types/circuit-value.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L89) --- url: /zkapps/o1js-reference/classes/SmartContract --- The main zkapp class. To write a zkapp, extend this class as such: ``` class YourSmartContract extends SmartContract { // your smart contract code here } ``` ## Extends - `SmartContractBase` ## Constructors ### new SmartContract() ```ts new SmartContract(address: PublicKey, tokenId?: Field): SmartContract ``` #### Parameters • **address**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`SmartContract`](SmartContract.mdx) #### Overrides `SmartContractBase.constructor` #### Source [lib/mina/zkapp.ts:614](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L614) ## Properties ### address ```ts address: PublicKey; ``` #### Source [lib/mina/zkapp.ts:579](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L579) *** ### events ```ts events: {} = {}; ``` A list of event types that can be emitted using this.emitEvent()`. #### Index signature \[`key`: `string`\]: [`FlexibleProvablePure`](../type-aliases/FlexibleProvablePure.mdx)\<`any`\> #### Source [lib/mina/zkapp.ts:979](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L979) *** ### sender ```ts sender: { "self": SmartContract; "getAndRequireSignature": PublicKey; "getUnconstrained": PublicKey; }; ``` #### self ```ts self: SmartContract; ``` #### getAndRequireSignature() Return a public key that is forced to sign this transaction. Note: This doesn't prove that the return value is the transaction sender, but it proves that whoever created the transaction controls the private key associated with the returned public key. ##### Returns [`PublicKey`](PublicKey.mdx) #### getUnconstrained() 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. Consider using `this.sender.getAndRequireSignature()` if you need to prove that the sender controls this account. ##### Returns [`PublicKey`](PublicKey.mdx) #### Source [lib/mina/zkapp.ts:868](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L868) *** ### tokenId ```ts tokenId: Field; ``` #### Source [lib/mina/zkapp.ts:580](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L580) *** ### \_maxProofsVerified? ```ts static optional _maxProofsVerified: 0 | 2 | 1; ``` #### Source [lib/mina/zkapp.ts:599](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L599) *** ### \_methodMetadata? ```ts static optional _methodMetadata: Record; ``` #### Source [lib/mina/zkapp.ts:589](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L589) *** ### \_methods? ```ts static optional _methods: MethodInterface[]; ``` #### Source [lib/mina/zkapp.ts:588](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L588) *** ### \_provers? ```ts static optional _provers: Prover[]; ``` #### Source [lib/mina/zkapp.ts:598](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L598) *** ### \_verificationKey? ```ts static optional _verificationKey: { "data": string; "hash": Field; }; ``` #### data ```ts data: string; ``` #### hash ```ts hash: Field; ``` #### Source [lib/mina/zkapp.ts:600](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L600) ## Accessors ### account ```ts get account(): Account ``` Current account of the [SmartContract](SmartContract.mdx). #### Returns `Account` #### Source [lib/mina/zkapp.ts:920](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L920) *** ### balance ```ts get balance(): { "addInPlace": void; "subInPlace": void; } ``` Balance of this [SmartContract](SmartContract.mdx). #### Returns ```ts { "addInPlace": void; "subInPlace": void; } ``` ##### addInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` ##### subInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` #### Source [lib/mina/zkapp.ts:973](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L973) *** ### currentSlot ```ts 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` #### Source [lib/mina/zkapp.ts:934](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L934) *** ### network ```ts get network(): Network ``` Current network state of the [SmartContract](SmartContract.mdx). #### Returns `Network` #### Source [lib/mina/zkapp.ts:926](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L926) *** ### self ```ts get self(): AccountUpdate ``` Returns the current [AccountUpdate](AccountUpdate.mdx) associated to this [SmartContract](SmartContract.mdx). #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/zkapp.ts:823](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L823) ## Methods ### approve() ```ts approve(update: AccountUpdate | AccountUpdateTree | AccountUpdateForest): 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. ```ts `@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](AccountUpdateTree.mdx), 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 • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) \| [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Returns `void` #### Source [lib/mina/zkapp.ts:959](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L959) *** ### deploy() ```ts deploy(__namedParameters: { "verificationKey": { "data": string; "hash": string | Field; }; }): Promise ``` Deploys a [SmartContract](SmartContract.mdx). ```ts let tx = await Mina.transaction(sender, async () => { AccountUpdate.fundNewAccount(sender); await zkapp.deploy(); }); tx.sign([senderKey, zkAppKey]); ``` #### Parameters • **\_\_namedParameters**= `{}` • **\_\_namedParameters.verificationKey?** • **\_\_namedParameters.verificationKey.data**: `string` • **\_\_namedParameters.verificationKey.hash**: `string` \| [`Field`](Field.mdx) #### Returns `Promise`\<`void`\> #### Source [lib/mina/zkapp.ts:703](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L703) *** ### emitEvent() ```ts emitEvent(type: K, event: any): void ``` Emits an event. Events will be emitted as a part of the transaction and can be collected by archive nodes. #### Type parameters • **K** *extends* `string` \| `number` #### Parameters • **type**: `K` • **event**: `any` #### Returns `void` #### Source [lib/mina/zkapp.ts:1030](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1030) *** ### emitEventIf() ```ts emitEventIf( condition: Bool, type: K, event: any): void ``` Conditionally emits an event. Events will be emitted as a part of the transaction and can be collected by archive nodes. #### Type parameters • **K** *extends* `string` \| `number` #### Parameters • **condition**: [`Bool`](Bool.mdx) • **type**: `K` • **event**: `any` #### Returns `void` #### Source [lib/mina/zkapp.ts:987](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L987) *** ### fetchEvents() ```ts fetchEvents(start?: UInt32, end?: UInt32): Promise<{ "blockHash": string; "blockHeight": UInt32; "chainStatus": string; "event": { "data": ProvablePure; "transactionInfo": { "transactionHash": string; "transactionMemo": string; "transactionStatus": string; }; }; "globalSlot": UInt32; "parentBlockHash": string; "type": string; }[]> ``` Asynchronously fetches events emitted by this [SmartContract](SmartContract.mdx) and returns an array of events with their corresponding types. #### Parameters • **start?**: [`UInt32`](UInt32.mdx)= `undefined` The start height of the events to fetch. • **end?**: [`UInt32`](UInt32.mdx) The end height of the events to fetch. If not provided, fetches events up to the latest height. #### Returns `Promise`\<\{ `"blockHash"`: `string`; `"blockHeight"`: [`UInt32`](UInt32.mdx); `"chainStatus"`: `string`; `"event"`: \{ `"data"`: [`ProvablePure`](../type-aliases/ProvablePure.mdx)\<`any`\>; `"transactionInfo"`: \{ `"transactionHash"`: `string`; `"transactionMemo"`: `string`; `"transactionStatus"`: `string`; \}; \}; `"globalSlot"`: [`UInt32`](UInt32.mdx); `"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 ```ts const startHeight = UInt32.from(1000); const endHeight = UInt32.from(2000); const events = await myZkapp.fetchEvents(startHeight, endHeight); console.log(events); ``` #### Source [lib/mina/zkapp.ts:1047](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1047) *** ### init() ```ts init(): void ``` `SmartContract.init()` will be called only when a [SmartContract](SmartContract.mdx) 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` #### Source [lib/mina/zkapp.ts:771](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L771) *** ### newSelf() ```ts newSelf(methodName?: string): AccountUpdate ``` Same as `SmartContract.self` but explicitly creates a new [AccountUpdate](AccountUpdate.mdx). #### Parameters • **methodName?**: `string` #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/zkapp.ts:858](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L858) *** ### requireSignature() ```ts 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](../variables/Permissions.mdx) 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` #### Source [lib/mina/zkapp.ts:804](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L804) *** ### send() ```ts send(args: { "amount": number | bigint | UInt64; "to": PublicKey | AccountUpdate | SmartContract; }): AccountUpdate ``` #### Parameters • **args** • **args.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) • **args.to**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/zkapp.ts:963](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L963) *** ### skipAuthorization() ```ts 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` #### Source [lib/mina/zkapp.ts:816](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L816) *** ### Proof() ```ts static Proof(): typeof __class ``` Returns a Proof type that belongs to this [SmartContract](SmartContract.mdx). #### Returns *typeof* `__class` #### Source [lib/mina/zkapp.ts:605](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L605) *** ### analyzeMethods() ```ts static analyzeMethods(__namedParameters: { "printSummary": false; }): Promise> ``` 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 • **\_\_namedParameters**= `{}` • **\_\_namedParameters.printSummary**: `undefined` \| `boolean`= `false` #### Returns `Promise`\<`Record`\<`string`, \{ `"actions"`: `number`; `"digest"`: `string`; `"gates"`: `Gate`[]; `"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 - `actions` the number of actions the method dispatches - `gates` the constraint system, represented as an array of gates #### Source [lib/mina/zkapp.ts:1178](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1178) *** ### compile() ```ts static compile(__namedParameters: { "cache": Cache.FileSystemDefault; "forceRecompile": false; }): Promise<{ "provers": Prover[]; "verificationKey": { "data": string; "hash": Field; }; "verify": (statement: Statement, proof: unknown) => Promise; }> ``` Compile your smart contract. This generates both the prover functions, needed to create proofs for running `@method`s, 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](https://o1-labs.github.io/proof-systems/kimchi/overview.html) 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 • **\_\_namedParameters**= `{}` • **\_\_namedParameters.cache**: `undefined` \| [`Cache`](../type-aliases/Cache.mdx)= `Cache.FileSystemDefault` • **\_\_namedParameters.forceRecompile**: `undefined` \| `boolean`= `false` #### Returns `Promise`\<\{ `"provers"`: `Prover`[]; `"verificationKey"`: \{ `"data"`: `string`; `"hash"`: [`Field`](Field.mdx); \}; `"verify"`: (`statement`: `Statement`\<`FieldConst`\>, `proof`: `unknown`) => `Promise`\<`boolean`\>; \}\> > ##### provers > > ```ts > provers: Prover[]; > ``` > > ##### verificationKey > > ```ts > verificationKey: { > "data": string; > "hash": Field; > }; > ``` > > ##### verificationKey.data > > ```ts > data: string; > ``` > > ##### verificationKey.hash > > ```ts > hash: Field; > ``` > > ##### verify() > > ```ts > verify: (statement: Statement, proof: unknown) => Promise; > ``` > > ###### Parameters > > • **statement**: `Statement`\<`FieldConst`\> > > • **proof**: `unknown` > > ###### Returns > > `Promise`\<`boolean`\> > #### Source [lib/mina/zkapp.ts:642](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L642) *** ### digest() ```ts static digest(): Promise ``` 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 `Promise`\<`string`\> the digest, as a hex string #### Source [lib/mina/zkapp.ts:683](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L683) *** ### runOutsideCircuit() ```ts static runOutsideCircuit(run: () => void): void ``` #### Parameters • **run** #### Returns `void` #### Source [lib/mina/zkapp.ts:1153](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1153) --- url: /zkapps/o1js-reference/classes/TokenAccountUpdateIterator --- Data structure to represent a forest of account updates that is being iterated over, in the context of a token manager contract. The iteration is done in a depth-first manner. ```ts let forest: AccountUpdateForest = ...; let tokenIterator = TokenAccountUpdateIterator.create(forest, tokenId); // process the first 5 account updates in the tree for (let i = 0; i < 5; i++) { let { accountUpdate, usesThisToken } = tokenIterator.next(); // ... do something with the account update ... } ``` **Important**: Since this is specifically used by token manager contracts to process their entire subtree of account updates, the iterator skips subtrees that don't inherit token permissions and can therefore definitely not use the token. So, the assumption is that the consumer of this iterator is only interested in account updates that use the token. We still can't avoid processing some account updates that don't use the token, therefore the iterator returns a boolean `usesThisToken` alongside each account update. ## Constructors ### new TokenAccountUpdateIterator() ```ts new TokenAccountUpdateIterator( forest: MerkleListIterator, mayUseToken: MayUseToken, selfToken: Field): TokenAccountUpdateIterator ``` #### Parameters • **forest**: [`MerkleListIterator`](MerkleListIterator.mdx)\<`AccountUpdateTreeBase`\> • **mayUseToken**: `MayUseToken` • **selfToken**: [`Field`](Field.mdx) #### Returns [`TokenAccountUpdateIterator`](TokenAccountUpdateIterator.mdx) #### Source [lib/mina/token/forest-iterator.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L59) ## Properties ### currentLayer ```ts currentLayer: Layer; ``` #### Source [lib/mina/token/forest-iterator.ts:55](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L55) *** ### selfToken ```ts selfToken: Field; ``` #### Source [lib/mina/token/forest-iterator.ts:57](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L57) *** ### unfinishedParentLayers ```ts unfinishedParentLayers: MerkleList; ``` #### Source [lib/mina/token/forest-iterator.ts:56](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L56) ## Methods ### assertFinished() ```ts assertFinished(message?: string): void ``` #### Parameters • **message?**: `string` #### Returns `void` #### Source [lib/mina/token/forest-iterator.ts:140](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L140) *** ### next() ```ts next(): { "accountUpdate": update; "usesThisToken": Bool; } ``` Make a single step along a tree of account updates. This function is guaranteed to visit each account update in the tree that uses the token exactly once, when called repeatedly. The method makes a best effort to avoid visiting account updates that are not using the token, and in particular, to avoid returning dummy updates. However, neither can be ruled out. We're returning `{ update, usesThisToken: Bool }` and let the caller handle the irrelevant case where `usesThisToken` is false. #### Returns ```ts { "accountUpdate": update; "usesThisToken": Bool; } ``` ##### accountUpdate ```ts accountUpdate: AccountUpdate = update; ``` ##### usesThisToken ```ts usesThisToken: Bool; ``` #### Source [lib/mina/token/forest-iterator.ts:88](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L88) *** ### create() ```ts static create(forest: AccountUpdateForest, selfToken: Field): TokenAccountUpdateIterator ``` #### Parameters • **forest**: [`AccountUpdateForest`](AccountUpdateForest.mdx) • **selfToken**: [`Field`](Field.mdx) #### Returns [`TokenAccountUpdateIterator`](TokenAccountUpdateIterator.mdx) #### Source [lib/mina/token/forest-iterator.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/forest-iterator.ts#L69) --- url: /zkapps/o1js-reference/classes/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 ## Extends - [`SmartContract`](SmartContract.mdx) ## Constructors ### new TokenContract() ```ts new TokenContract(address: PublicKey, tokenId?: Field): TokenContract ``` #### Parameters • **address**: [`PublicKey`](PublicKey.mdx) • **tokenId?**: [`Field`](Field.mdx) #### Returns [`TokenContract`](TokenContract.mdx) #### Inherited from [`SmartContract`](SmartContract.mdx).[`constructor`](SmartContract.mdx#constructors) #### Source [lib/mina/zkapp.ts:614](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L614) ## Properties ### address ```ts address: PublicKey; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`address`](SmartContract.mdx#address) #### Source [lib/mina/zkapp.ts:579](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L579) *** ### events ```ts events: {} = {}; ``` A list of event types that can be emitted using this.emitEvent()`. #### Index signature \[`key`: `string`\]: [`FlexibleProvablePure`](../type-aliases/FlexibleProvablePure.mdx)\<`any`\> #### Inherited from [`SmartContract`](SmartContract.mdx).[`events`](SmartContract.mdx#events) #### Source [lib/mina/zkapp.ts:979](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L979) *** ### sender ```ts sender: { "self": SmartContract; "getAndRequireSignature": PublicKey; "getUnconstrained": PublicKey; }; ``` #### self ```ts self: SmartContract; ``` #### getAndRequireSignature() Return a public key that is forced to sign this transaction. Note: This doesn't prove that the return value is the transaction sender, but it proves that whoever created the transaction controls the private key associated with the returned public key. ##### Returns [`PublicKey`](PublicKey.mdx) #### getUnconstrained() 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. Consider using `this.sender.getAndRequireSignature()` if you need to prove that the sender controls this account. ##### Returns [`PublicKey`](PublicKey.mdx) #### Inherited from [`SmartContract`](SmartContract.mdx).[`sender`](SmartContract.mdx#sender) #### Source [lib/mina/zkapp.ts:868](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L868) *** ### tokenId ```ts tokenId: Field; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`tokenId`](SmartContract.mdx#tokenid) #### Source [lib/mina/zkapp.ts:580](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L580) *** ### MAX\_ACCOUNT\_UPDATES ```ts static MAX_ACCOUNT_UPDATES: number = 9; ``` The maximum number of account updates using the token in a single transaction that this contract supports. #### Source [lib/mina/token/token-contract.ts:29](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L29) *** ### \_maxProofsVerified? ```ts static optional _maxProofsVerified: 0 | 2 | 1; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`_maxProofsVerified`](SmartContract.mdx#_maxproofsverified) #### Source [lib/mina/zkapp.ts:599](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L599) *** ### \_methodMetadata? ```ts static optional _methodMetadata: Record; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`_methodMetadata`](SmartContract.mdx#_methodmetadata) #### Source [lib/mina/zkapp.ts:589](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L589) *** ### \_methods? ```ts static optional _methods: MethodInterface[]; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`_methods`](SmartContract.mdx#_methods) #### Source [lib/mina/zkapp.ts:588](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L588) *** ### \_provers? ```ts static optional _provers: Prover[]; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`_provers`](SmartContract.mdx#_provers) #### Source [lib/mina/zkapp.ts:598](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L598) *** ### \_verificationKey? ```ts static optional _verificationKey: { "data": string; "hash": Field; }; ``` #### data ```ts data: string; ``` #### hash ```ts hash: Field; ``` #### Inherited from [`SmartContract`](SmartContract.mdx).[`_verificationKey`](SmartContract.mdx#_verificationkey) #### Source [lib/mina/zkapp.ts:600](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L600) ## Accessors ### account ```ts get account(): Account ``` Current account of the [SmartContract](SmartContract.mdx). #### Returns `Account` #### Source [lib/mina/zkapp.ts:920](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L920) *** ### balance ```ts get balance(): { "addInPlace": void; "subInPlace": void; } ``` Balance of this [SmartContract](SmartContract.mdx). #### Returns ```ts { "addInPlace": void; "subInPlace": void; } ``` ##### addInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` ##### subInPlace() ###### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`Int64`](Int64.mdx) ###### Returns `void` #### Source [lib/mina/zkapp.ts:973](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L973) *** ### currentSlot ```ts 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` #### Source [lib/mina/zkapp.ts:934](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L934) *** ### internal ```ts get internal(): { "burn": AccountUpdate; "mint": AccountUpdate; "send": AccountUpdate; } ``` Helper methods to use from within a token contract. #### Returns ```ts { "burn": AccountUpdate; "mint": AccountUpdate; "send": AccountUpdate; } ``` ##### burn() Burn token balance on `address`. Returns the burn account update. ###### Parameters • **\_\_namedParameters** • **\_\_namedParameters.address**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) • **\_\_namedParameters.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) ###### Returns [`AccountUpdate`](AccountUpdate.mdx) ##### mint() Mints token balance to `address`. Returns the mint account update. ###### Parameters • **\_\_namedParameters** • **\_\_namedParameters.address**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) • **\_\_namedParameters.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) ###### Returns [`AccountUpdate`](AccountUpdate.mdx) ##### send() Move token balance from `from` to `to`. Returns the `to` account update. ###### Parameters • **\_\_namedParameters** • **\_\_namedParameters.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) • **\_\_namedParameters.from**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) • **\_\_namedParameters.to**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) ###### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/token/token-contract.ts:77](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L77) *** ### network ```ts get network(): Network ``` Current network state of the [SmartContract](SmartContract.mdx). #### Returns `Network` #### Source [lib/mina/zkapp.ts:926](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L926) *** ### self ```ts get self(): AccountUpdate ``` Returns the current [AccountUpdate](AccountUpdate.mdx) associated to this [SmartContract](SmartContract.mdx). #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Source [lib/mina/zkapp.ts:823](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L823) ## Methods ### approve() ```ts approve(update: AccountUpdate | AccountUpdateTree | AccountUpdateForest): 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. ```ts `@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](AccountUpdateTree.mdx), 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 • **update**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) \| [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Returns `void` #### Inherited from [`SmartContract`](SmartContract.mdx).[`approve`](SmartContract.mdx#approve) #### Source [lib/mina/zkapp.ts:959](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L959) *** ### approveAccountUpdate() ```ts approveAccountUpdate(accountUpdate: AccountUpdate | AccountUpdateTree): Promise ``` Approve a single account update (with arbitrarily many children). #### Parameters • **accountUpdate**: [`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx) #### Returns `Promise`\<`void`\> #### Source [lib/mina/token/token-contract.ts:144](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L144) *** ### approveAccountUpdates() ```ts approveAccountUpdates(accountUpdates: (AccountUpdate | AccountUpdateTree)[]): Promise ``` Approve a list of account updates (with arbitrarily many children). #### Parameters • **accountUpdates**: ([`AccountUpdate`](AccountUpdate.mdx) \| [`AccountUpdateTree`](AccountUpdateTree.mdx))[] #### Returns `Promise`\<`void`\> #### Source [lib/mina/token/token-contract.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L152) *** ### approveBase() ```ts abstract approveBase(forest: AccountUpdateForest): Promise ``` #### Parameters • **forest**: [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Returns `Promise`\<`void`\> #### Source [lib/mina/token/token-contract.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L84) *** ### checkZeroBalanceChange() ```ts checkZeroBalanceChange(updates: AccountUpdateForest): 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 • **updates**: [`AccountUpdateForest`](AccountUpdateForest.mdx) #### Returns `void` #### Source [lib/mina/token/token-contract.ts:128](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L128) *** ### deploy() ```ts deploy(args?: DeployArgs): Promise ``` Deploys a [TokenContract](TokenContract.mdx). 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: ```ts async deploy() { await super.deploy(); // DON'T DO THIS ON THE INITIAL DEPLOYMENT! this.account.isNew.requireNothing(); } ``` #### Parameters • **args?**: [`DeployArgs`](../type-aliases/DeployArgs.mdx) #### Returns `Promise`\<`void`\> #### Overrides [`SmartContract`](SmartContract.mdx).[`deploy`](SmartContract.mdx#deploy) #### Source [lib/mina/token/token-contract.ts:52](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L52) *** ### deriveTokenId() ```ts deriveTokenId(): Field ``` Returns the `tokenId` of the token managed by this contract. #### Returns [`Field`](Field.mdx) #### Source [lib/mina/token/token-contract.ts:70](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L70) *** ### emitEvent() ```ts emitEvent(type: K, event: any): void ``` Emits an event. Events will be emitted as a part of the transaction and can be collected by archive nodes. #### Type parameters • **K** *extends* `string` \| `number` #### Parameters • **type**: `K` • **event**: `any` #### Returns `void` #### Inherited from [`SmartContract`](SmartContract.mdx).[`emitEvent`](SmartContract.mdx#emitevent) #### Source [lib/mina/zkapp.ts:1030](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1030) *** ### emitEventIf() ```ts emitEventIf( condition: Bool, type: K, event: any): void ``` Conditionally emits an event. Events will be emitted as a part of the transaction and can be collected by archive nodes. #### Type parameters • **K** *extends* `string` \| `number` #### Parameters • **condition**: [`Bool`](Bool.mdx) • **type**: `K` • **event**: `any` #### Returns `void` #### Inherited from [`SmartContract`](SmartContract.mdx).[`emitEventIf`](SmartContract.mdx#emiteventif) #### Source [lib/mina/zkapp.ts:987](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L987) *** ### fetchEvents() ```ts fetchEvents(start?: UInt32, end?: UInt32): Promise<{ "blockHash": string; "blockHeight": UInt32; "chainStatus": string; "event": { "data": ProvablePure; "transactionInfo": { "transactionHash": string; "transactionMemo": string; "transactionStatus": string; }; }; "globalSlot": UInt32; "parentBlockHash": string; "type": string; }[]> ``` Asynchronously fetches events emitted by this [SmartContract](SmartContract.mdx) and returns an array of events with their corresponding types. #### Parameters • **start?**: [`UInt32`](UInt32.mdx)= `undefined` The start height of the events to fetch. • **end?**: [`UInt32`](UInt32.mdx) The end height of the events to fetch. If not provided, fetches events up to the latest height. #### Returns `Promise`\<\{ `"blockHash"`: `string`; `"blockHeight"`: [`UInt32`](UInt32.mdx); `"chainStatus"`: `string`; `"event"`: \{ `"data"`: [`ProvablePure`](../type-aliases/ProvablePure.mdx)\<`any`\>; `"transactionInfo"`: \{ `"transactionHash"`: `string`; `"transactionMemo"`: `string`; `"transactionStatus"`: `string`; \}; \}; `"globalSlot"`: [`UInt32`](UInt32.mdx); `"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. #### Inherited from [`SmartContract`](SmartContract.mdx).[`fetchEvents`](SmartContract.mdx#fetchevents) #### Async #### Throws If there is an error fetching events from the Mina network. #### Example ```ts const startHeight = UInt32.from(1000); const endHeight = UInt32.from(2000); const events = await myZkapp.fetchEvents(startHeight, endHeight); console.log(events); ``` #### Source [lib/mina/zkapp.ts:1047](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1047) *** ### forEachUpdate() ```ts forEachUpdate(updates: AccountUpdateForest, callback: (update: AccountUpdate, usesToken: Bool) => void): 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 • **updates**: [`AccountUpdateForest`](AccountUpdateForest.mdx) • **callback** #### Returns `void` #### Source [lib/mina/token/token-contract.ts:91](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L91) *** ### init() ```ts init(): void ``` `SmartContract.init()` will be called only when a [SmartContract](SmartContract.mdx) 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`](SmartContract.mdx).[`init`](SmartContract.mdx#init) #### Source [lib/mina/zkapp.ts:771](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L771) *** ### newSelf() ```ts newSelf(methodName?: string): AccountUpdate ``` Same as `SmartContract.self` but explicitly creates a new [AccountUpdate](AccountUpdate.mdx). #### Parameters • **methodName?**: `string` #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Inherited from [`SmartContract`](SmartContract.mdx).[`newSelf`](SmartContract.mdx#newself) #### Source [lib/mina/zkapp.ts:858](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L858) *** ### requireSignature() ```ts 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](../variables/Permissions.mdx) 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`](SmartContract.mdx).[`requireSignature`](SmartContract.mdx#requiresignature) #### Source [lib/mina/zkapp.ts:804](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L804) *** ### send() ```ts send(args: { "amount": number | bigint | UInt64; "to": PublicKey | AccountUpdate | SmartContract; }): AccountUpdate ``` #### Parameters • **args** • **args.amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) • **args.to**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) \| [`SmartContract`](SmartContract.mdx) #### Returns [`AccountUpdate`](AccountUpdate.mdx) #### Inherited from [`SmartContract`](SmartContract.mdx).[`send`](SmartContract.mdx#send) #### Source [lib/mina/zkapp.ts:963](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L963) *** ### skipAuthorization() ```ts 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`](SmartContract.mdx).[`skipAuthorization`](SmartContract.mdx#skipauthorization) #### Source [lib/mina/zkapp.ts:816](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L816) *** ### transfer() ```ts transfer( from: PublicKey | AccountUpdate, to: PublicKey | AccountUpdate, amount: number | bigint | UInt64): Promise ``` Transfer `amount` of tokens from `from` to `to`. #### Parameters • **from**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) • **to**: [`PublicKey`](PublicKey.mdx) \| [`AccountUpdate`](AccountUpdate.mdx) • **amount**: `number` \| `bigint` \| [`UInt64`](UInt64.mdx) #### Returns `Promise`\<`void`\> #### Source [lib/mina/token/token-contract.ts:164](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/token/token-contract.ts#L164) *** ### Proof() ```ts static Proof(): typeof __class ``` Returns a Proof type that belongs to this [SmartContract](SmartContract.mdx). #### Returns *typeof* `__class` #### Inherited from [`SmartContract`](SmartContract.mdx).[`Proof`](SmartContract.mdx#proof) #### Source [lib/mina/zkapp.ts:605](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L605) *** ### analyzeMethods() ```ts static analyzeMethods(__namedParameters: { "printSummary": false; }): Promise> ``` 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 • **\_\_namedParameters**= `{}` • **\_\_namedParameters.printSummary**: `undefined` \| `boolean`= `false` #### Returns `Promise`\<`Record`\<`string`, \{ `"actions"`: `number`; `"digest"`: `string`; `"gates"`: `Gate`[]; `"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 - `actions` the number of actions the method dispatches - `gates` the constraint system, represented as an array of gates #### Inherited from [`SmartContract`](SmartContract.mdx).[`analyzeMethods`](SmartContract.mdx#analyzemethods) #### Source [lib/mina/zkapp.ts:1178](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1178) *** ### compile() ```ts static compile(__namedParameters: { "cache": Cache.FileSystemDefault; "forceRecompile": false; }): Promise<{ "provers": Prover[]; "verificationKey": { "data": string; "hash": Field; }; "verify": (statement: Statement, proof: unknown) => Promise; }> ``` Compile your smart contract. This generates both the prover functions, needed to create proofs for running `@method`s, 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](https://o1-labs.github.io/proof-systems/kimchi/overview.html) 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 • **\_\_namedParameters**= `{}` • **\_\_namedParameters.cache**: `undefined` \| [`Cache`](../type-aliases/Cache.mdx)= `Cache.FileSystemDefault` • **\_\_namedParameters.forceRecompile**: `undefined` \| `boolean`= `false` #### Returns `Promise`\<\{ `"provers"`: `Prover`[]; `"verificationKey"`: \{ `"data"`: `string`; `"hash"`: [`Field`](Field.mdx); \}; `"verify"`: (`statement`: `Statement`\<`FieldConst`\>, `proof`: `unknown`) => `Promise`\<`boolean`\>; \}\> > ##### provers > > ```ts > provers: Prover[]; > ``` > > ##### verificationKey > > ```ts > verificationKey: { > "data": string; > "hash": Field; > }; > ``` > > ##### verificationKey.data > > ```ts > data: string; > ``` > > ##### verificationKey.hash > > ```ts > hash: Field; > ``` > > ##### verify() > > ```ts > verify: (statement: Statement, proof: unknown) => Promise; > ``` > > ###### Parameters > > • **statement**: `Statement`\<`FieldConst`\> > > • **proof**: `unknown` > > ###### Returns > > `Promise`\<`boolean`\> > #### Inherited from [`SmartContract`](SmartContract.mdx).[`compile`](SmartContract.mdx#compile) #### Source [lib/mina/zkapp.ts:642](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L642) *** ### digest() ```ts static digest(): Promise ``` 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 `Promise`\<`string`\> the digest, as a hex string #### Inherited from [`SmartContract`](SmartContract.mdx).[`digest`](SmartContract.mdx#digest) #### Source [lib/mina/zkapp.ts:683](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L683) *** ### runOutsideCircuit() ```ts static runOutsideCircuit(run: () => void): void ``` #### Parameters • **run** #### Returns `void` #### Inherited from [`SmartContract`](SmartContract.mdx).[`runOutsideCircuit`](SmartContract.mdx#runoutsidecircuit) #### Source [lib/mina/zkapp.ts:1153](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1153) --- url: /zkapps/o1js-reference/classes/TokenSymbol --- ## Extends - \{ `"field"`: [`Field`](Field.mdx); `"symbol"`: `string`; \} ## Constructors ### new TokenSymbol() ```ts new TokenSymbol(value: { "field": Field; "symbol": string; }): TokenSymbol ``` #### Parameters • **value** • **value.field**: [`Field`](Field.mdx) • **value.symbol**: `string` #### Returns [`TokenSymbol`](TokenSymbol.mdx) #### Inherited from `Struct(TokenSymbolPure).constructor` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) ## Properties ### field ```ts field: Field; ``` #### Inherited from `Struct(TokenSymbolPure).field` #### Source [lib/provable/crypto/poseidon.ts:212](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/poseidon.ts#L212) *** ### symbol ```ts symbol: string; ``` #### Inherited from `Struct(TokenSymbolPure).symbol` #### Source [lib/provable/crypto/poseidon.ts:212](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/poseidon.ts#L212) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct(TokenSymbolPure)._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### check() ```ts static check: (value: { "field": Field; "symbol": string; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.field**: [`Field`](Field.mdx) • **value.symbol**: `string` #### Returns `void` #### Inherited from `Struct(TokenSymbolPure).check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### empty() ```ts static empty: () => { "field": Field; "symbol": string; }; ``` #### Returns ```ts { "field": Field; "symbol": string; } ``` ##### field ```ts field: Field; ``` ##### symbol ```ts symbol: string; ``` #### Inherited from `Struct(TokenSymbolPure).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[], aux: any[]) => { "field": Field; "symbol": string; }; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling [toFields](TokenSymbol.mdx#tofields) and toAuxilary methods on an element of type `T`. #### Parameters • **fields**: [`Field`](Field.mdx)[] an array of [Field](Field.mdx) elements describing the provable data of the new `T` element. • **aux**: `any`[] an array of any type describing the "auxiliary" data of the new `T` element, optional. #### Returns ```ts { "field": Field; "symbol": string; } ``` ##### field ```ts field: Field; ``` ##### symbol ```ts symbol: string; ``` #### Inherited from `Struct(TokenSymbolPure).fromFields` #### Source [lib/provable/types/provable-intf.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L59) *** ### fromJSON() ```ts static fromJSON: (x: string) => { "field": Field; "symbol": string; }; ``` #### Parameters • **x**: `string` #### Returns ```ts { "field": Field; "symbol": string; } ``` ##### field ```ts field: Field; ``` ##### symbol ```ts symbol: string; ``` #### Inherited from `Struct(TokenSymbolPure).fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: string | { "field": Field; "symbol": string; }) => { "field": Field; "symbol": string; } & (value: string | { "field": Field; "symbol": string; }) => { "field": Field; "symbol": string; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct(TokenSymbolPure).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "field": Field; "symbol": string; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.field?**: [`Field`](Field.mdx) • **value.symbol?**: `string` #### Returns `any`[] #### Inherited from `Struct(TokenSymbolPure).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "field": Field; "symbol": string; }) => { "field": Field; "symbol": string; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.field**: [`Field`](Field.mdx) • **x.symbol**: `string` #### Returns ```ts { "field": Field; "symbol": string; } ``` ##### field ```ts field: Field; ``` ##### symbol ```ts symbol: string; ``` #### Inherited from `Struct(TokenSymbolPure).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "field": Field; "symbol": string; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.field**: [`Field`](Field.mdx) • **value.symbol**: `string` #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct(TokenSymbolPure).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "field": Field; "symbol": string; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.field**: [`Field`](Field.mdx) • **x.symbol**: `string` #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `Struct(TokenSymbolPure).toInput` #### Source [lib/provable/types/struct.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L152) *** ### toJSON() ```ts static toJSON: (x: { "field": Field; "symbol": string; }) => string; ``` #### Parameters • **x** • **x.field**: [`Field`](Field.mdx) • **x.symbol**: `string` #### Returns `string` #### Inherited from `Struct(TokenSymbolPure).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "field": Field; "symbol": string; }) => string; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.field**: [`Field`](Field.mdx) • **x.symbol**: `string` #### Returns `string` #### Inherited from `Struct(TokenSymbolPure).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### from() ```ts static from(value: string | TokenSymbol): TokenSymbol ``` #### Parameters • **value**: `string` \| [`TokenSymbol`](TokenSymbol.mdx) #### Returns [`TokenSymbol`](TokenSymbol.mdx) #### Source [lib/provable/crypto/poseidon.ts:259](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/poseidon.ts#L259) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct(TokenSymbolPure).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/classes/UInt32 --- A 32 bit unsigned integer with values ranging from 0 to 4,294,967,295. ## Extends - `CircuitValue` ## Constructors ### new UInt32() ```ts new UInt32(x: | string | number | bigint | FieldVar | UInt32): UInt32 ``` Create a [UInt32](UInt32.mdx). The max value of a [UInt32](UInt32.mdx) is `2^32 - 1 = UInt32.MAXINT()`. **Warning**: Cannot overflow, an error is thrown if the result is greater than UInt32.MAXINT() #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Overrides `CircuitValue.constructor` #### Source [lib/provable/int.ts:540](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L540) ## Properties ### value ```ts value: Field; ``` #### Source [lib/provable/int.ts:531](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L531) *** ### NUM\_BITS ```ts static NUM_BITS: number = 32; ``` #### Source [lib/provable/int.ts:532](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L532) *** ### Unsafe ```ts static Unsafe: { "fromField": UInt32; }; ``` #### fromField() Create a [UInt32](UInt32.mdx) from a [Field](../variables/Field.mdx) without constraining its range. **Warning**: This is unsafe, because it does not prove that the input [Field](../variables/Field.mdx) actually fits in 32 bits.\ Only use this if you know what you are doing, otherwise use the safe [UInt32.from](UInt32.mdx#from). ##### Parameters • **x**: [`Field`](Field.mdx) ##### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:548](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L548) ## Accessors ### one ```ts get static one(): UInt32 ``` Static method to create a [UInt32](UInt32.mdx) with value `0`. #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:570](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L570) *** ### zero ```ts get static zero(): UInt32 ``` Static method to create a [UInt32](UInt32.mdx) with value `0`. #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:563](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L563) ## Methods ### add() ```ts add(y: number | UInt32): UInt32 ``` Addition with overflow checking. #### Parameters • **y**: `number` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:717](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L717) *** ### addMod32() ```ts addMod32(y: UInt32): UInt32 ``` Addition modulo 2^32. Check Gadgets.addMod32 for a detailed description. #### Parameters • **y**: [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:643](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L643) *** ### and() ```ts and(x: UInt32): UInt32 ``` Bitwise AND gadget on [UInt32](UInt32.mdx) elements. Equivalent to the [bitwise AND `&` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND). The AND gate works by comparing two bits and returning `1` if both bits are `1`, and `0` otherwise. It can be checked by a double generic gate that verifies the following relationship between the values below. The generic gate verifies:\ `a + b = sum` and the conjunction equation `2 * and = sum - xor`\ Where:\ `a + b = sum`\ `a ^ b = xor`\ `a & b = and` You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#and) #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Example ```typescript let a = UInt32.from(3); // ... 000011 let b = UInt32.from(5); // ... 000101 let c = a.and(b, 2); // ... 000001 c.assertEquals(1); ``` #### Source [lib/provable/int.ts:888](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L888) *** ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### assertGreaterThan() ```ts assertGreaterThan(y: UInt32, message?: string): void ``` Asserts that a [UInt32](UInt32.mdx) is greater than another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:975](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L975) *** ### assertGreaterThanOrEqual() ```ts assertGreaterThanOrEqual(y: UInt32, message?: string): void ``` Asserts that a [UInt32](UInt32.mdx) is greater than or equal to another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:989](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L989) *** ### assertLessThan() ```ts assertLessThan(y: UInt32, message?: string): void ``` Asserts that a [UInt32](UInt32.mdx) is less than another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:952](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L952) *** ### assertLessThanOrEqual() ```ts assertLessThanOrEqual(y: UInt32, message?: string): void ``` Asserts that a [UInt32](UInt32.mdx) is less than or equal to another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:924](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L924) *** ### div() ```ts div(y: number | UInt32): UInt32 ``` Integer division. `x.div(y)` returns the floor of `x / y`, that is, the greatest `z` such that `x * y <= x`. #### Parameters • **y**: `number` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:694](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L694) *** ### divMod() ```ts divMod(y: string | number | UInt32): { "quotient": UInt32; "rest": UInt32; } ``` Integer division with remainder. `x.divMod(y)` returns the quotient and the remainder. #### Parameters • **y**: `string` \| `number` \| [`UInt32`](UInt32.mdx) #### Returns ```ts { "quotient": UInt32; "rest": UInt32; } ``` ##### quotient ```ts quotient: UInt32; ``` ##### rest ```ts rest: UInt32; ``` #### Source [lib/provable/int.ts:652](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L652) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### greaterThan() ```ts greaterThan(y: UInt32): Bool ``` Checks if a [UInt32](UInt32.mdx) is greater than another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:968](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L968) *** ### greaterThanOrEqual() ```ts greaterThanOrEqual(y: UInt32): Bool ``` Checks if a [UInt32](UInt32.mdx) is greater than or equal to another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:982](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L982) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### leftShift() ```ts leftShift(bits: number): UInt32 ``` Performs a left shift operation on the provided [UInt32](UInt32.mdx) element. This operation is similar to the `<<` shift operation in JavaScript, where bits are shifted to the left, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 32-bit representation of the number, where the most significant (32th) bit is on the left end and the least significant bit is on the right end. The operation expects the input to be range checked to 32 bit. #### Parameters • **bits**: `number` Amount of bits to shift the [UInt32](UInt32.mdx) element to the left. The amount should be between 0 and 32 (or else the shift will fail). #### Returns [`UInt32`](UInt32.mdx) #### Example ```ts const x = UInt32.from(0b001100); // 12 in binary const y = x.leftShift(2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary ``` #### Source [lib/provable/int.ts:836](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L836) *** ### lessThan() ```ts lessThan(y: UInt32): Bool ``` Checks if a [UInt32](UInt32.mdx) is less than another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:940](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L940) *** ### lessThanOrEqual() ```ts lessThanOrEqual(y: UInt32): Bool ``` Checks if a [UInt32](UInt32.mdx) is less than or equal to another one. #### Parameters • **y**: [`UInt32`](UInt32.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:912](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L912) *** ### mod() ```ts mod(y: number | UInt32): UInt32 ``` Integer remainder. `x.mod(y)` returns the value `z` such that `0 <= z < y` and `x - z` is divisible by `y`. #### Parameters • **y**: `number` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:703](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L703) *** ### mul() ```ts mul(y: number | UInt32): UInt32 ``` Multiplication with overflow checking. #### Parameters • **y**: `number` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:709](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L709) *** ### not() ```ts not(): UInt32 ``` Bitwise NOT gate on [UInt32](UInt32.mdx) elements. Similar to the [bitwise NOT `~` operator in JavaScript](https://developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/Operators/Bitwise_NOT). **Note:** The NOT gate operates over 32 bit for UInt32 types. A NOT gate works by returning `1` in each bit position if the corresponding bit of the operand is `0`, and returning `0` if the corresponding bit of the operand is `1`. NOT is implemented as a subtraction of the input from the all one bitmask. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#not) #### Returns [`UInt32`](UInt32.mdx) #### Example ```ts // NOTing 4 bits with the unchecked version let a = UInt32.from(0b0101); let b = a.not(); console.log(b.toBigInt().toString(2)); // 11111111111111111111111111111010 ``` #### Source [lib/provable/int.ts:781](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L781) *** ### or() ```ts or(x: UInt32): UInt32 ``` Bitwise OR gadget on [UInt32](UInt32.mdx) elements. Equivalent to the [bitwise OR `|` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR). The OR gate works by comparing two bits and returning `1` if at least one bit is `1`, and `0` otherwise. #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Example ```typescript let a = UInt32.from(3); // ... 000011 let b = UInt32.from(5); // ... 000101 let c = a.or(b); // ... 000111 c.assertEquals(7); ``` #### Source [lib/provable/int.ts:905](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L905) *** ### rightShift() ```ts rightShift(bits: number): UInt32 ``` Performs a left right operation on the provided [UInt32](UInt32.mdx) element. This operation is similar to the `>>` shift operation in JavaScript, where bits are shifted to the right, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 32-bit representation of the number, where the most significant (32th) bit is on the left end and the least significant bit is on the right end. #### Parameters • **bits**: `number` Amount of bits to shift the [UInt32](UInt32.mdx) element to the right. The amount should be between 0 and 32 (or else the shift will fail). The operation expects the input to be range checked to 32 bit. #### Returns [`UInt32`](UInt32.mdx) #### Example ```ts const x = UInt32.from(0b001100); // 12 in binary const y = x.rightShift(2); // left shift by 2 bits y.assertEquals(0b000011); // 48 in binary ``` #### Source [lib/provable/int.ts:859](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L859) *** ### rotate() ```ts rotate(bits: number, direction: "left" | "right"): UInt32 ``` A (left and right) rotation operates similarly to the shift operation (`<<` for left and `>>` for right) in JavaScript, with the distinction that the bits are circulated to the opposite end of a 64-bit representation rather than being discarded. For a left rotation, this means that bits shifted off the left end reappear at the right end. Conversely, for a right rotation, bits shifted off the right end reappear at the left end. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. The `direction` parameter is a string that accepts either `'left'` or `'right'`, determining the direction of the rotation. To safely use `rotate()`, you need to make sure that the value passed in is range-checked to 64 bits; for example, using Gadgets.rangeCheck64. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#rotation) #### Parameters • **bits**: `number` amount of bits to rotate this [UInt32](UInt32.mdx) element with. • **direction**: `"left"` \| `"right"`= `'left'` left or right rotation direction. #### Returns [`UInt32`](UInt32.mdx) #### Example ```ts const x = UInt32.from(0b001100); const y = x.rotate(2, 'left'); const z = x.rotate(2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); ``` #### Source [lib/provable/int.ts:813](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L813) *** ### sub() ```ts sub(y: number | UInt32): UInt32 ``` Subtraction with underflow checking. #### Parameters • **y**: `number` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:725](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L725) *** ### toBigint() ```ts toBigint(): bigint ``` Turns the [UInt32](UInt32.mdx) into a BigInt. #### Returns `bigint` #### Source [lib/provable/int.ts:582](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L582) *** ### toBytes() ```ts toBytes(): [UInt8, UInt8, UInt8, UInt8] ``` Split a UInt32 into 4 UInt8s, in little-endian order. #### Returns [[`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx)] #### Source [lib/provable/int.ts:1006](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1006) *** ### toBytesBE() ```ts toBytesBE(): [UInt8, UInt8, UInt8, UInt8] ``` Split a UInt32 into 4 UInt8s, in big-endian order. #### Returns [[`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx), [`UInt8`](UInt8.mdx)] #### Source [lib/provable/int.ts:1013](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1013) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### toString() ```ts toString(): string ``` Turns the [UInt32](UInt32.mdx) into a string. #### Returns `string` #### Source [lib/provable/int.ts:576](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L576) *** ### toUInt64() ```ts toUInt64(): UInt64 ``` Turns the [UInt32](UInt32.mdx) into a [UInt64](UInt64.mdx). #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:588](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L588) *** ### xor() ```ts xor(x: UInt32): UInt32 ``` Bitwise XOR gadget on [UInt32](UInt32.mdx) elements. Equivalent to the [bitwise XOR `^` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR). A XOR gate works by comparing two bits and returning `1` if two bits differ, and `0` if two bits are equal. This gadget builds a chain of XOR gates recursively. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#xor-1) #### Parameters • **x**: [`UInt32`](UInt32.mdx) [UInt32](UInt32.mdx) element to compare. #### Returns [`UInt32`](UInt32.mdx) #### Example ```ts let a = UInt32.from(0b0101); let b = UInt32.from(0b0011); let c = a.xor(b); c.assertEquals(0b0110); ``` #### Source [lib/provable/int.ts:750](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L750) *** ### MAXINT() ```ts static MAXINT(): UInt32 ``` Creates a [UInt32](UInt32.mdx) with a value of 4,294,967,295. #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:636](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L636) *** ### check() ```ts static check(x: UInt32): void ``` #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns `void` #### Overrides `CircuitValue.check` #### Source [lib/provable/int.ts:593](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L593) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### from() ```ts static from(x: string | number | bigint | UInt32): UInt32 ``` Creates a new [UInt32](UInt32.mdx). #### Parameters • **x**: `string` \| `number` \| `bigint` \| [`UInt32`](UInt32.mdx) #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:628](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L628) *** ### fromBytes() ```ts static fromBytes(bytes: UInt8[]): UInt32 ``` Combine 4 UInt8s into a UInt32, in little-endian order. #### Parameters • **bytes**: [`UInt8`](UInt8.mdx)[] #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:1020](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1020) *** ### fromBytesBE() ```ts static fromBytesBE(bytes: UInt8[]): UInt32 ``` Combine 4 UInt8s into a UInt32, in big-endian order. #### Parameters • **bytes**: [`UInt8`](UInt8.mdx)[] #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:1028](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1028) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(x: string): InstanceType ``` Decodes a JSON-like object into this structure. #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `string` #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromJSON` #### Source [lib/provable/int.ts:609](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L609) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(x: bigint | UInt32): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `bigint` \| [`UInt32`](UInt32.mdx) #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromValue` #### Source [lib/provable/int.ts:997](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L997) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(x: UInt32): HashInput ``` #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns `HashInput` #### Overrides `CircuitValue.toInput` #### Source [lib/provable/int.ts:596](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L596) *** ### toJSON() ```ts static toJSON(x: UInt32): string ``` Encodes this structure into a JSON-like object. #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns `string` #### Overrides `CircuitValue.toJSON` #### Source [lib/provable/int.ts:602](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L602) *** ### toValue() ```ts static toValue(x: UInt32): bigint ``` #### Parameters • **x**: [`UInt32`](UInt32.mdx) #### Returns `bigint` #### Overrides `CircuitValue.toValue` #### Source [lib/provable/int.ts:993](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L993) --- url: /zkapps/o1js-reference/classes/UInt64 --- A 64 bit unsigned integer with values ranging from 0 to 18,446,744,073,709,551,615. ## Extends - `CircuitValue` ## Constructors ### new UInt64() ```ts new UInt64(x: | string | number | bigint | FieldVar | UInt64 | UInt32): UInt64 ``` Create a [UInt64](UInt64.mdx). The max value of a [UInt64](UInt64.mdx) is `2^64 - 1 = UInt64.MAXINT()`. **Warning**: Cannot overflow, an error is thrown if the result is greater than UInt64.MAXINT() #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| `FieldVar` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Overrides `CircuitValue.constructor` #### Source [lib/provable/int.ts:40](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L40) ## Properties ### value ```ts value: Field; ``` #### Source [lib/provable/int.ts:31](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L31) *** ### NUM\_BITS ```ts static NUM_BITS: number = 64; ``` #### Source [lib/provable/int.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L32) *** ### Unsafe ```ts static Unsafe: { "fromField": UInt64; }; ``` #### fromField() Create a [UInt64](UInt64.mdx) from a [Field](../variables/Field.mdx) without constraining its range. **Warning**: This is unsafe, because it does not prove that the input [Field](../variables/Field.mdx) actually fits in 64 bits.\ Only use this if you know what you are doing, otherwise use the safe [UInt64.from](UInt64.mdx#from). ##### Parameters • **x**: [`Field`](Field.mdx) ##### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:48](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L48) ## Accessors ### one ```ts get static one(): UInt64 ``` Static method to create a [UInt64](UInt64.mdx) with value `1`. #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L69) *** ### zero ```ts get static zero(): UInt64 ``` Static method to create a [UInt64](UInt64.mdx) with value `0`. #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:63](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L63) ## Methods ### add() ```ts add(y: number | UInt64): UInt64 ``` Addition with overflow checking. #### Parameters • **y**: `number` \| [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:241](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L241) *** ### addMod64() ```ts addMod64(y: UInt64): UInt64 ``` Addition modulo 2^64. Check Gadgets.addMod64 for a detailed description. #### Parameters • **y**: [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L163) *** ### and() ```ts and(x: UInt64): UInt64 ``` Bitwise AND gadget on [UInt64](UInt64.mdx) elements. Equivalent to the [bitwise AND `&` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND). The AND gate works by comparing two bits and returning `1` if both bits are `1`, and `0` otherwise. It can be checked by a double generic gate that verifies the following relationship between the values below. The generic gate verifies:\ `a + b = sum` and the conjunction equation `2 * and = sum - xor`\ Where:\ `a + b = sum`\ `a ^ b = xor`\ `a & b = and` You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#and) #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Example ```typescript let a = UInt64.from(3); // ... 000011 let b = UInt64.from(5); // ... 000101 let c = a.and(b); // ... 000001 c.assertEquals(1); ``` #### Source [lib/provable/int.ts:411](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L411) *** ### assertEquals() ```ts assertEquals(x: this): void ``` #### Parameters • **x**: `this` #### Returns `void` #### Inherited from `CircuitValue.assertEquals` #### Source [lib/provable/types/circuit-value.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L130) *** ### assertGreaterThan() ```ts assertGreaterThan(y: UInt64, message?: string): void ``` Asserts that a [UInt64](UInt64.mdx) is greater than another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:499](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L499) *** ### assertGreaterThanOrEqual() ```ts assertGreaterThanOrEqual(y: UInt64, message?: string): void ``` Asserts that a [UInt64](UInt64.mdx) is greater than or equal to another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:513](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L513) *** ### assertLessThan() ```ts assertLessThan(y: UInt64, message?: string): void ``` Asserts that a [UInt64](UInt64.mdx) is less than another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:476](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L476) *** ### assertLessThanOrEqual() ```ts assertLessThanOrEqual(y: UInt64, message?: string): void ``` Asserts that a [UInt64](UInt64.mdx) is less than or equal to another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:447](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L447) *** ### div() ```ts div(y: number | UInt64): UInt64 ``` Integer division. `x.div(y)` returns the floor of `x / y`, that is, the greatest `z` such that `z * y <= x`. #### Parameters • **y**: `number` \| [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:215](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L215) *** ### divMod() ```ts divMod(y: string | number | UInt64): { "quotient": UInt64; "rest": UInt64; } ``` Integer division with remainder. `x.divMod(y)` returns the quotient and the remainder. #### Parameters • **y**: `string` \| `number` \| [`UInt64`](UInt64.mdx) #### Returns ```ts { "quotient": UInt64; "rest": UInt64; } ``` ##### quotient ```ts quotient: UInt64; ``` ##### rest ```ts rest: UInt64; ``` #### Source [lib/provable/int.ts:172](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L172) *** ### equals() ```ts equals(x: this): Bool ``` #### Parameters • **x**: `this` #### Returns [`Bool`](Bool.mdx) #### Inherited from `CircuitValue.equals` #### Source [lib/provable/types/circuit-value.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L126) *** ### greaterThan() ```ts greaterThan(y: UInt64): Bool ``` Checks if a [UInt64](UInt64.mdx) is greater than another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:492](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L492) *** ### greaterThanOrEqual() ```ts greaterThanOrEqual(y: UInt64): Bool ``` Checks if a [UInt64](UInt64.mdx) is greater than or equal to another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:506](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L506) *** ### isConstant() ```ts isConstant(): boolean ``` #### Returns `boolean` #### Inherited from `CircuitValue.isConstant` #### Source [lib/provable/types/circuit-value.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L134) *** ### leftShift() ```ts leftShift(bits: number): UInt64 ``` Performs a left shift operation on the provided [UInt64](UInt64.mdx) element. This operation is similar to the `<<` shift operation in JavaScript, where bits are shifted to the left, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. #### Parameters • **bits**: `number` Amount of bits to shift the [UInt64](UInt64.mdx) element to the left. The amount should be between 0 and 64 (or else the shift will fail). #### Returns [`UInt64`](UInt64.mdx) #### Example ```ts const x = UInt64.from(0b001100); // 12 in binary const y = x.leftShift(2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary ``` #### Source [lib/provable/int.ts:361](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L361) *** ### lessThan() ```ts lessThan(y: UInt64): Bool ``` Checks if a [UInt64](UInt64.mdx) is less than another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:464](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L464) *** ### lessThanOrEqual() ```ts lessThanOrEqual(y: UInt64): Bool ``` Checks if a [UInt64](UInt64.mdx) is less than or equal to another one. #### Parameters • **y**: [`UInt64`](UInt64.mdx) #### Returns [`Bool`](Bool.mdx) #### Source [lib/provable/int.ts:435](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L435) *** ### mod() ```ts mod(y: number | UInt64): UInt64 ``` Integer remainder. `x.mod(y)` returns the value `z` such that `0 <= z < y` and `x - z` is divisible by `y`. #### Parameters • **y**: `number` \| [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:225](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L225) *** ### mul() ```ts mul(y: number | UInt64): UInt64 ``` Multiplication with overflow checking. #### Parameters • **y**: `number` \| [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:232](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L232) *** ### not() ```ts not(): UInt64 ``` Bitwise NOT gate on [Field](../variables/Field.mdx) elements. Similar to the [bitwise NOT `~` operator in JavaScript](https://developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/Operators/Bitwise_NOT). **Note:** The NOT gate operates over 64 bit for UInt64 types. A NOT gate works by returning `1` in each bit position if the corresponding bit of the operand is `0`, and returning `0` if the corresponding bit of the operand is `1`. NOT is implemented as a subtraction of the input from the all one bitmask You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#not) #### Returns [`UInt64`](UInt64.mdx) #### Example ```ts // NOTing 4 bits with the unchecked version let a = UInt64.from(0b0101); let b = a.not(false); console.log(b.toBigInt().toString(2)); // 1111111111111111111111111111111111111111111111111111111111111010 ``` #### Source [lib/provable/int.ts:308](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L308) *** ### or() ```ts or(x: UInt64): UInt64 ``` Bitwise OR gadget on [UInt64](UInt64.mdx) elements. Equivalent to the [bitwise OR `|` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR). The OR gate works by comparing two bits and returning `1` if at least one bit is `1`, and `0` otherwise. #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Example ```typescript let a = UInt64.from(3); // ... 000011 let b = UInt64.from(5); // ... 000101 let c = a.or(b); // ... 000111 c.assertEquals(7); ``` #### Source [lib/provable/int.ts:428](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L428) *** ### rightShift() ```ts rightShift(bits: number): UInt64 ``` Performs a right shift operation on the provided [UInt64](UInt64.mdx) element. This operation is similar to the `>>` shift operation in JavaScript, where bits are shifted to the right, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. #### Parameters • **bits**: `number` Amount of bits to shift the [UInt64](UInt64.mdx) element to the right. The amount should be between 0 and 64 (or else the shift will fail). #### Returns [`UInt64`](UInt64.mdx) #### Example ```ts const x = UInt64.from(0b001100); // 12 in binary const y = x.rightShift(2); // right shift by 2 bits y.assertEquals(0b000011); // 3 in binary ``` #### Source [lib/provable/int.ts:382](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L382) *** ### rotate() ```ts rotate(bits: number, direction: "left" | "right"): UInt64 ``` A (left and right) rotation operates similarly to the shift operation (`<<` for left and `>>` for right) in JavaScript, with the distinction that the bits are circulated to the opposite end of a 64-bit representation rather than being discarded. For a left rotation, this means that bits shifted off the left end reappear at the right end. Conversely, for a right rotation, bits shifted off the right end reappear at the left end. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. The `direction` parameter is a string that accepts either `'left'` or `'right'`, determining the direction of the rotation. To safely use `rotate()`, you need to make sure that the value passed in is range-checked to 64 bits; for example, using Gadgets.rangeCheck64. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#rotation) #### Parameters • **bits**: `number` amount of bits to rotate this [UInt64](UInt64.mdx) element with. • **direction**: `"left"` \| `"right"`= `'left'` left or right rotation direction. #### Returns [`UInt64`](UInt64.mdx) #### Example ```ts const x = UInt64.from(0b001100); const y = x.rotate(2, 'left'); const z = x.rotate(2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); ``` #### Source [lib/provable/int.ts:340](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L340) *** ### sub() ```ts sub(y: number | UInt64): UInt64 ``` Subtraction with underflow checking. #### Parameters • **y**: `number` \| [`UInt64`](UInt64.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:250](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L250) *** ### toBigInt() ```ts toBigInt(): bigint ``` Turns the [UInt64](UInt64.mdx) into a BigInt. #### Returns `bigint` #### Source [lib/provable/int.ts:83](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L83) *** ### toConstant() ```ts toConstant(): this ``` #### Returns `this` #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:122](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L122) *** ### toFields() ```ts toFields(): Field[] ``` #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L85) *** ### toJSON() ```ts toJSON(): any ``` #### Returns `any` #### Inherited from `CircuitValue.toJSON` #### Source [lib/provable/types/circuit-value.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L118) *** ### toString() ```ts toString(): string ``` Turns the [UInt64](UInt64.mdx) into a string. #### Returns `string` #### Source [lib/provable/int.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L76) *** ### toUInt32() ```ts toUInt32(): UInt32 ``` Turns the [UInt64](UInt64.mdx) into a [UInt32](UInt32.mdx), asserting that it fits in 32 bits. #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:90](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L90) *** ### toUInt32Clamped() ```ts toUInt32Clamped(): UInt32 ``` Turns the [UInt64](UInt64.mdx) into a [UInt32](UInt32.mdx), clamping to the 32 bits range if it's too large. ```ts UInt64.from(4294967296).toUInt32Clamped().toString(); // "4294967295" ``` #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:102](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L102) *** ### xor() ```ts xor(x: UInt64): UInt64 ``` Bitwise XOR gadget on [Field](../variables/Field.mdx) elements. Equivalent to the [bitwise XOR `^` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR). A XOR gate works by comparing two bits and returning `1` if two bits differ, and `0` if two bits are equal. This gadget builds a chain of XOR gates recursively. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#xor-1) #### Parameters • **x**: [`UInt64`](UInt64.mdx) [UInt64](UInt64.mdx) element to XOR. #### Returns [`UInt64`](UInt64.mdx) #### Example ```ts let a = UInt64.from(0b0101); let b = UInt64.from(0b0011); let c = a.xor(b); c.assertEquals(0b0110); ``` #### Source [lib/provable/int.ts:275](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L275) *** ### MAXINT() ```ts static MAXINT(): UInt64 ``` Creates a [UInt64](UInt64.mdx) with a value of 18,446,744,073,709,551,615. #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L156) *** ### check() ```ts static check(x: UInt64): void ``` #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns `void` #### Overrides `CircuitValue.check` #### Source [lib/provable/int.ts:112](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L112) *** ### empty() ```ts static empty(): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.empty` #### Source [lib/provable/types/circuit-value.ts:230](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L230) *** ### from() ```ts static from(x: | string | number | bigint | UInt64 | UInt32): UInt64 ``` Creates a new [UInt64](UInt64.mdx). #### Parameters • **x**: \| `string` \| `number` \| `bigint` \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L148) *** ### fromFields() ```ts static fromFields(this: T, xs: Field[]): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **xs**: [`Field`](Field.mdx)[] #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromFields` #### Source [lib/provable/types/circuit-value.ts:138](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L138) *** ### fromJSON() ```ts static fromJSON(x: string): InstanceType ``` Decodes a JSON-like object into this structure. #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `string` #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromJSON` #### Source [lib/provable/int.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L130) *** ### fromObject() ```ts static fromObject(this: T, value: NonMethods>): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `NonMethods`\<`InstanceType`\<`T`\>\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.fromObject` #### Source [lib/provable/types/circuit-value.ts:30](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L30) *** ### fromValue() ```ts static fromValue(x: bigint | UInt64): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **x**: `bigint` \| [`UInt64`](UInt64.mdx) #### Returns `InstanceType`\<`T`\> #### Overrides `CircuitValue.fromValue` #### Source [lib/provable/int.ts:521](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L521) *** ### sizeInFields() ```ts static sizeInFields(): number ``` #### Returns `number` #### Inherited from `CircuitValue.sizeInFields` #### Source [lib/provable/types/circuit-value.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L37) *** ### toAuxiliary() ```ts static toAuxiliary(): [] ``` #### Returns [] #### Inherited from `CircuitValue.toAuxiliary` #### Source [lib/provable/types/circuit-value.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L59) *** ### toCanonical() ```ts static toCanonical(this: T, value: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **value**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toCanonical` #### Source [lib/provable/types/circuit-value.ts:177](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L177) *** ### toConstant() ```ts static toConstant(this: T, t: InstanceType): InstanceType ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **t**: `InstanceType`\<`T`\> #### Returns `InstanceType`\<`T`\> #### Inherited from `CircuitValue.toConstant` #### Source [lib/provable/types/circuit-value.ts:189](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L189) *** ### toFields() ```ts static toFields(this: T, v: InstanceType): Field[] ``` #### Type parameters • **T** *extends* `AnyConstructor` #### Parameters • **this**: `T` • **v**: `InstanceType`\<`T`\> #### Returns [`Field`](Field.mdx)[] #### Inherited from `CircuitValue.toFields` #### Source [lib/provable/types/circuit-value.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/circuit-value.ts#L42) *** ### toInput() ```ts static toInput(x: UInt64): HashInput ``` #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns `HashInput` #### Overrides `CircuitValue.toInput` #### Source [lib/provable/int.ts:116](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L116) *** ### toJSON() ```ts static toJSON(x: UInt64): string ``` Encodes this structure into a JSON-like object. #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns `string` #### Overrides `CircuitValue.toJSON` #### Source [lib/provable/int.ts:123](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L123) *** ### toValue() ```ts static toValue(x: UInt64): bigint ``` #### Parameters • **x**: [`UInt64`](UInt64.mdx) #### Returns `bigint` #### Overrides `CircuitValue.toValue` #### Source [lib/provable/int.ts:517](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L517) --- url: /zkapps/o1js-reference/classes/UInt8 --- A 8 bit unsigned integer with values ranging from 0 to 255. ## Extends - \{ `"value"`: `Field`; \} ## Constructors ### new UInt8() ```ts new UInt8(x: number | bigint | FieldVar | UInt8): UInt8 ``` Create a [UInt8](UInt8.mdx) from a bigint or number. The max value of a [UInt8](UInt8.mdx) is `2^8 - 1 = 255`. **Warning**: Cannot overflow past 255, an error is thrown if the result is greater than 255. #### Parameters • **x**: `number` \| `bigint` \| `FieldVar` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Overrides `Struct({ value: Field, }).constructor` #### Source [lib/provable/int.ts:1456](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1456) ## Properties ### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field, }).value` #### Source [lib/provable/int.ts:1446](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1446) *** ### NUM\_BITS ```ts static NUM_BITS: number = 8; ``` #### Source [lib/provable/int.ts:1448](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1448) *** ### Unsafe ```ts static Unsafe: { "fromField": UInt8; }; ``` #### fromField() Create a [UInt8](UInt8.mdx) from a [Field](../variables/Field.mdx) without constraining its range. **Warning**: This is unsafe, because it does not prove that the input [Field](../variables/Field.mdx) actually fits in 8 bits.\ Only use this if you know what you are doing, otherwise use the safe [UInt8.from](UInt8.mdx#from). ##### Parameters • **x**: [`Field`](Field.mdx) ##### Returns [`UInt8`](UInt8.mdx) #### Source [lib/provable/int.ts:1462](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1462) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct({ value: Field, })._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### empty() ```ts static empty: () => { "value": Field; }; ``` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field, }).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[]) => { "value": Field; }; ``` #### Parameters • **fields**: [`Field`](Field.mdx)[] #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field, }).fromFields` #### Source [lib/provable/types/provable-intf.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L115) *** ### fromJSON() ```ts static fromJSON: (x: { "value": Field; }) => { "value": Field; }; ``` #### Parameters • **x** • **x.value**: `string`= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field, }).fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: { "value": Field; } | { "value": Field; }) => { "value": Field; } & (value: { "value": Field; }) => { "value": Field; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct({ value: Field, }).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "value": Field; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.value?**: [`Field`](Field.mdx)= `Field` #### Returns `any`[] #### Inherited from `Struct({ value: Field, }).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "value": Field; }) => { "value": Field; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: Field = Field; ``` #### Inherited from `Struct({ value: Field, }).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "value": Field; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.value**: [`Field`](Field.mdx)= `Field` #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct({ value: Field, }).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toJSON() ```ts static toJSON: (x: { "value": Field; }) => { "value": Field; }; ``` #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: string = Field; ``` #### Inherited from `Struct({ value: Field, }).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "value": Field; }) => { "value": Field; }; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.value**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "value": Field; } ``` ##### value ```ts value: bigint = Field; ``` #### Inherited from `Struct({ value: Field, }).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Accessors ### one ```ts get static one(): UInt8 ``` Static method to create a [UInt8](UInt8.mdx) with value `1`. #### Returns [`UInt8`](UInt8.mdx) #### Source [lib/provable/int.ts:1483](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1483) *** ### zero ```ts get static zero(): UInt8 ``` Static method to create a [UInt8](UInt8.mdx) with value `0`. #### Returns [`UInt8`](UInt8.mdx) #### Source [lib/provable/int.ts:1477](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1477) ## Methods ### add() ```ts add(y: number | bigint | UInt8): UInt8 ``` Add a [UInt8](UInt8.mdx) to another [UInt8](UInt8.mdx) without allowing overflow. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Example ```ts const x = UInt8.from(3); const sum = x.add(5); sum.assertEquals(8); ``` #### Throws if the result is greater than 255. #### Source [lib/provable/int.ts:1499](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1499) *** ### assertEquals() ```ts assertEquals(y: number | bigint | UInt8, message?: string): void ``` Assert that this [UInt8](UInt8.mdx) is equal another [UInt8](UInt8.mdx) value. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) the [UInt8](UInt8.mdx) value to compare & assert with this [UInt8](UInt8.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:1765](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1765) *** ### assertGreaterThan() ```ts assertGreaterThan(y: number | bigint | UInt8, message?: string): void ``` Assert that this [UInt8](UInt8.mdx) is greater than another [UInt8](UInt8.mdx) value. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) the [UInt8](UInt8.mdx) value to compare & assert with this [UInt8](UInt8.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:1741](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1741) *** ### assertGreaterThanOrEqual() ```ts assertGreaterThanOrEqual(y: UInt8, message?: string): void ``` Assert that this [UInt8](UInt8.mdx) is greater than or equal to another [UInt8](UInt8.mdx) value. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: [`UInt8`](UInt8.mdx) the [UInt8](UInt8.mdx) value to compare & assert with this [UInt8](UInt8.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:1753](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1753) *** ### assertLessThan() ```ts assertLessThan(y: number | bigint | UInt8, message?: string): void ``` Assert that this [UInt8](UInt8.mdx) is less than another [UInt8](UInt8.mdx) value. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) the [UInt8](UInt8.mdx) value to compare & assert with this [UInt8](UInt8.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:1659](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1659) *** ### assertLessThanOrEqual() ```ts assertLessThanOrEqual(y: number | bigint | UInt8, message?: string): void ``` Assert that this [UInt8](UInt8.mdx) is less than or equal to another [UInt8](UInt8.mdx) value. **Important**: If an assertion fails, the code throws an error. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) the [UInt8](UInt8.mdx) value to compare & assert with this [UInt8](UInt8.mdx). • **message?**: `string` #### Returns `void` #### Source [lib/provable/int.ts:1684](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1684) *** ### div() ```ts div(y: number | bigint | UInt8): UInt8 ``` Divide a [UInt8](UInt8.mdx) by another [UInt8](UInt8.mdx). This is integer division that rounds down. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Example ```ts const x = UInt8.from(7); const quotient = x.div(2); quotient.assertEquals(3); ``` #### Source [lib/provable/int.ts:1552](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1552) *** ### divMod() ```ts divMod(y: number | bigint | UInt8): { "quotient": UInt8; "remainder": UInt8; } ``` Get the quotient and remainder of a [UInt8](UInt8.mdx) divided by another [UInt8](UInt8.mdx): `x == y * q + r`, where `0 <= r < y`. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) a [UInt8](UInt8.mdx) to get the quotient and remainder of another [UInt8](UInt8.mdx). #### Returns ```ts { "quotient": UInt8; "remainder": UInt8; } ``` The quotient `q` and remainder `r`. ##### quotient ```ts quotient: UInt8; ``` ##### remainder ```ts remainder: UInt8; ``` #### Source [lib/provable/int.ts:1579](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1579) *** ### greaterThan() ```ts greaterThan(y: number | bigint | UInt8): Bool ``` Check if this [UInt8](UInt8.mdx) is greater than another [UInt8](UInt8.mdx). Returns a [Bool](../variables/Bool.mdx). #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts // 5 > 3 UInt8.from(5).greaterThan(3); ``` #### Source [lib/provable/int.ts:1715](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1715) *** ### greaterThanOrEqual() ```ts greaterThanOrEqual(y: number | bigint | UInt8): Bool ``` Check if this [UInt8](UInt8.mdx) is greater than or equal another [UInt8](UInt8.mdx) value. Returns a [Bool](../variables/Bool.mdx). #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts // 3 >= 3 UInt8.from(3).greaterThanOrEqual(3); ``` #### Source [lib/provable/int.ts:1729](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1729) *** ### lessThan() ```ts lessThan(y: number | bigint | UInt8): Bool ``` Check if this [UInt8](UInt8.mdx) is less than another [UInt8](UInt8.mdx) value. Returns a [Bool](../variables/Bool.mdx). #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts UInt8.from(2).lessThan(UInt8.from(3)); ``` #### Source [lib/provable/int.ts:1638](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1638) *** ### lessThanOrEqual() ```ts lessThanOrEqual(y: number | bigint | UInt8): Bool ``` Check if this [UInt8](UInt8.mdx) is less than or equal to another [UInt8](UInt8.mdx) value. Returns a [Bool](../variables/Bool.mdx). #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`Bool`](Bool.mdx) #### Example ```ts UInt8.from(3).lessThanOrEqual(UInt8.from(5)); ``` #### Source [lib/provable/int.ts:1616](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1616) *** ### mod() ```ts mod(y: number | bigint | UInt8): UInt8 ``` Get the remainder a [UInt8](UInt8.mdx) of division of another [UInt8](UInt8.mdx). #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Example ```ts const x = UInt8.from(50); const mod = x.mod(30); mod.assertEquals(20); ``` #### Source [lib/provable/int.ts:1566](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1566) *** ### mul() ```ts mul(y: number | bigint | UInt8): UInt8 ``` Multiply a [UInt8](UInt8.mdx) by another [UInt8](UInt8.mdx) without allowing overflow. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Example ```ts const x = UInt8.from(3); const product = x.mul(5); product.assertEquals(15); ``` #### Throws if the result is greater than 255. #### Source [lib/provable/int.ts:1535](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1535) *** ### sub() ```ts sub(y: number | bigint | UInt8): UInt8 ``` Subtract a [UInt8](UInt8.mdx) from another [UInt8](UInt8.mdx) without allowing underflow. #### Parameters • **y**: `number` \| `bigint` \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Example ```ts const x = UInt8.from(8); const difference = x.sub(5); difference.assertEquals(3); ``` #### Throws if the result is less than 0. #### Source [lib/provable/int.ts:1517](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1517) *** ### toBigInt() ```ts toBigInt(): bigint ``` Serialize the [UInt8](UInt8.mdx) to a bigint. **Warning**: This operation is not provable. #### Returns `bigint` #### Source [lib/provable/int.ts:1793](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1793) *** ### toNumber() ```ts toNumber(): number ``` Serialize the [UInt8](UInt8.mdx) to a number. **Warning**: This operation is not provable. #### Returns `number` #### Source [lib/provable/int.ts:1784](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1784) *** ### toString() ```ts toString(): string ``` Serialize the [UInt8](UInt8.mdx) to a string, e.g. for printing. **Warning**: This operation is not provable. #### Returns `string` #### Source [lib/provable/int.ts:1775](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1775) *** ### toUInt32() ```ts toUInt32(): UInt32 ``` Turns a [UInt8](UInt8.mdx) into a [UInt32](UInt32.mdx). #### Returns [`UInt32`](UInt32.mdx) #### Source [lib/provable/int.ts:1813](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1813) *** ### toUInt64() ```ts toUInt64(): UInt64 ``` Turns a [UInt8](UInt8.mdx) into a [UInt64](UInt64.mdx). #### Returns [`UInt64`](UInt64.mdx) #### Source [lib/provable/int.ts:1820](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1820) *** ### MAXINT() ```ts static MAXINT(): UInt8 ``` Creates a [UInt8](UInt8.mdx) with a value of 255. #### Returns [`UInt8`](UInt8.mdx) #### Source [lib/provable/int.ts:1827](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1827) *** ### check() ```ts static check(x: Field | { "value": Field; }): void ``` Provable.check for [UInt8](UInt8.mdx). Proves that the input is in the [0, 255] range. #### Parameters • **x**: [`Field`](Field.mdx) \| \{ `"value"`: [`Field`](Field.mdx); \} #### Returns `void` #### Overrides `Struct({ value: Field, }).check` #### Source [lib/provable/int.ts:1801](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1801) *** ### from() ```ts static from(x: | number | bigint | Field | UInt64 | UInt32 | UInt8): UInt8 ``` Creates a new [UInt8](UInt8.mdx). #### Parameters • **x**: \| `number` \| `bigint` \| [`Field`](Field.mdx) \| [`UInt64`](UInt64.mdx) \| [`UInt32`](UInt32.mdx) \| [`UInt8`](UInt8.mdx) #### Returns [`UInt8`](UInt8.mdx) #### Source [lib/provable/int.ts:1834](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1834) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct({ value: Field, }).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) *** ### toInput() ```ts static toInput(x: { "value": Field; }): HashInput ``` #### Parameters • **x** • **x.value**: [`Field`](Field.mdx) #### Returns `HashInput` #### Overrides `Struct({ value: Field, }).toInput` #### Source [lib/provable/int.ts:1806](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/int.ts#L1806) --- url: /zkapps/o1js-reference/classes/Unconstrained --- Container which holds an unconstrained value. This can be used to pass values between the out-of-circuit blocks in provable code. Invariants: - An `Unconstrained`'s value can only be accessed in auxiliary contexts. - An `Unconstrained` can be empty when compiling, but never empty when running as the prover. (there is no way to create an empty `Unconstrained` in the prover) ## Example ```ts let x = Unconstrained.from(0n); class MyContract extends SmartContract { `@method` myMethod(x: Unconstrained) { Provable.witness(Field, () => { // we can access and modify `x` here let newValue = x.get() + otherField.toBigInt(); x.set(newValue); // ... }); // throws an error! x.get(); } ``` ## Type parameters • **T** ## Properties ### provable ```ts static provable: UnconstrainedProvable & { "empty": () => Unconstrained; "toInput": (x: Unconstrained) => { "fields": Field[]; "packed": [Field, number][]; }; }; ``` #### Type declaration ##### empty() ```ts empty: () => Unconstrained; ``` ###### Returns [`Unconstrained`](Unconstrained.mdx)\<`any`\> ##### toInput() ```ts toInput: (x: Unconstrained) => { "fields": Field[]; "packed": [Field, number][]; }; ``` ###### Parameters • **x**: [`Unconstrained`](Unconstrained.mdx)\<`any`\> ###### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ###### fields? ```ts optional fields: Field[]; ``` ###### packed? ```ts optional packed: [Field, number][]; ``` #### Source [lib/provable/types/unconstrained.ts:111](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L111) ## Methods ### get() ```ts get(): T ``` Read an unconstrained value. Note: Can only be called outside provable code. #### Returns `T` #### Source [lib/provable/types/unconstrained.ts:53](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L53) *** ### set() ```ts set(value: T): void ``` Modify the unconstrained value. #### Parameters • **value**: `T` #### Returns `void` #### Source [lib/provable/types/unconstrained.ts:67](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L67) *** ### setTo() ```ts setTo(value: Unconstrained): void ``` Set the unconstrained value to the same as another `Unconstrained`. #### Parameters • **value**: [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Returns `void` #### Source [lib/provable/types/unconstrained.ts:74](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L74) *** ### updateAsProver() ```ts updateAsProver(compute: (value: T) => T): void ``` Update an `Unconstrained` by a witness computation. #### Parameters • **compute** #### Returns `void` #### Source [lib/provable/types/unconstrained.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L104) *** ### from() ```ts static from(value: T | Unconstrained): Unconstrained ``` Create an `Unconstrained` with the given `value`. Note: If `T` contains provable types, `Unconstrained.from` is an anti-pattern, because it stores witnesses in a space that's intended to be used outside the proof. Something like the following should be used instead: ```ts let xWrapped = Unconstrained.witness(() => Provable.toConstant(type, x)); ``` #### Type parameters • **T** #### Parameters • **value**: `T` \| [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Returns [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Source [lib/provable/types/unconstrained.ts:89](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L89) *** ### withEmpty() ```ts static withEmpty(empty: T): Provable, T> & { "empty": () => Unconstrained; "toInput": (x: Unconstrained) => { "fields": Field[]; "packed": [Field, number][]; }; } ``` #### Type parameters • **T** #### Parameters • **empty**: `T` #### Returns `Provable`\<[`Unconstrained`](Unconstrained.mdx)\<`T`\>, `T`\> & \{ `"empty"`: () => [`Unconstrained`](Unconstrained.mdx)\<`T`\>; `"toInput"`: (`x`: [`Unconstrained`](Unconstrained.mdx)\<`T`\>) => \{ `"fields"`: [`Field`](Field.mdx)[]; `"packed"`: [[`Field`](Field.mdx), `number`][]; \}; \} #### Source [lib/provable/types/unconstrained.ts:131](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L131) *** ### witness() ```ts static witness(compute: () => T): Unconstrained ``` Create an `Unconstrained` from a witness computation. #### Type parameters • **T** #### Parameters • **compute** #### Returns [`Unconstrained`](Unconstrained.mdx)\<`T`\> #### Source [lib/provable/types/unconstrained.ts:97](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/unconstrained.ts#L97) --- url: /zkapps/o1js-reference/classes/VerificationKey --- ## Extends - \{ `"data"`: `String`; `"hash"`: `Field`; \} ## Constructors ### new VerificationKey() ```ts new VerificationKey(value: { "data": String; "hash": Field; }): VerificationKey ``` #### Parameters • **value** • **value.data**: `string`= `String` • **value.hash**: [`Field`](Field.mdx)= `Field` #### Returns [`VerificationKey`](VerificationKey.mdx) #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).constructor` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) ## Properties ### data ```ts data: string = String; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).data` #### Source [lib/proof-system/zkprogram.ts:545](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L545) *** ### hash ```ts hash: Field = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).hash` #### Source [lib/proof-system/zkprogram.ts:545](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L545) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, })._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### check() ```ts static check: (value: { "data": String; "hash": Field; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.data**: `string`= `String` • **value.hash**: [`Field`](Field.mdx)= `Field` #### Returns `void` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### empty() ```ts static empty: () => { "data": String; "hash": Field; }; ``` #### Returns ```ts { "data": String; "hash": Field; } ``` ##### data ```ts data: string = String; ``` ##### hash ```ts hash: Field = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[], aux: any[]) => { "data": String; "hash": Field; }; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling [toFields](VerificationKey.mdx#tofields) and toAuxilary methods on an element of type `T`. #### Parameters • **fields**: [`Field`](Field.mdx)[] an array of [Field](Field.mdx) elements describing the provable data of the new `T` element. • **aux**: `any`[] an array of any type describing the "auxiliary" data of the new `T` element, optional. #### Returns ```ts { "data": String; "hash": Field; } ``` ##### data ```ts data: string = String; ``` ##### hash ```ts hash: Field = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).fromFields` #### Source [lib/provable/types/provable-intf.ts:59](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L59) *** ### fromJSON() ```ts static fromJSON: (x: string) => { "data": String; "hash": Field; }; ``` #### Parameters • **x**: `string` #### Returns ```ts { "data": String; "hash": Field; } ``` ##### data ```ts data: string = String; ``` ##### hash ```ts hash: Field = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: { "data": String; "hash": Field; } | { "data": String; "hash": Field; }) => { "data": String; "hash": Field; } & (value: { "data": String; "hash": Field; } | { "data": String; "hash": Field; }) => { "data": String; "hash": Field; }; ``` Convert provable type from a normal JS type. #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "data": String; "hash": Field; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.data?**: `string`= `String` • **value.hash?**: [`Field`](Field.mdx)= `Field` #### Returns `any`[] #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "data": String; "hash": Field; }) => { "data": String; "hash": Field; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.data**: `string`= `String` • **x.hash**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "data": String; "hash": Field; } ``` ##### data ```ts data: string = String; ``` ##### hash ```ts hash: Field = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "data": String; "hash": Field; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](Field.mdx) array from. • **value.data**: `string`= `String` • **value.hash**: [`Field`](Field.mdx)= `Field` #### Returns [`Field`](Field.mdx)[] #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "data": String; "hash": Field; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.data**: `string`= `String` • **x.hash**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toInput` #### Source [lib/provable/types/struct.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L152) *** ### toJSON() ```ts static toJSON: (x: { "data": String; "hash": Field; }) => string; ``` #### Parameters • **x** • **x.data**: `string`= `String` • **x.hash**: [`Field`](Field.mdx)= `Field` #### Returns `string` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "data": String; "hash": Field; }) => { "data": String; "hash": Field; }; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.data**: `string`= `String` • **x.hash**: [`Field`](Field.mdx)= `Field` #### Returns ```ts { "data": String; "hash": Field; } ``` ##### data ```ts data: string = String; ``` ##### hash ```ts hash: bigint = Field; ``` #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### dummy() ```ts static dummy(): Promise ``` #### Returns `Promise`\<[`VerificationKey`](VerificationKey.mdx)\> #### Source [lib/proof-system/zkprogram.ts:550](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L550) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](Field.mdx) type, as [Field](Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](Field.mdx) type. #### Inherited from `Struct({ ...provable({ data: String, hash: Field }), toJSON({ data }: { data: string }) { return data; }, }).sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/functions/Bytes --- ```ts function Bytes(size: number): typeof Bytes ``` A provable type representing an array of bytes. ```ts class Bytes32 extends Bytes(32) {} let bytes = Bytes32.fromHex('deadbeef'); ``` ## Parameters • **size**: `number` ## Returns *typeof* `Bytes` ## Source [lib/provable/wrapped-classes.ts:16](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped-classes.ts#L16) --- url: /zkapps/o1js-reference/functions/ConstantField --- ```ts function ConstantField(x: bigint | ConstantFieldVar): ConstantField ``` ## Parameters • **x**: `bigint` \| `ConstantFieldVar` ## Returns [`ConstantField`](../type-aliases/ConstantField.mdx) ## Source [lib/provable/field.ts:1246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1246) --- url: /zkapps/o1js-reference/functions/MerkleListBase --- ```ts function MerkleListBase(): ProvableHashable> ``` ## Type parameters • **T** ## Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`MerkleListBase`](../type-aliases/MerkleListBase.mdx)\<`T`\>\> ## Source [lib/provable/merkle-list.ts:46](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L46) --- url: /zkapps/o1js-reference/functions/MerkleWitness --- ```ts function MerkleWitness(height: number): typeof BaseMerkleWitness ``` Returns a circuit-compatible Witness for a specific Tree height. ## Parameters • **height**: `number` Height of the Merkle Tree that this Witness belongs to. ## Returns *typeof* [`BaseMerkleWitness`](../classes/BaseMerkleWitness.mdx) A circuit-compatible Merkle Witness. ## Source [lib/provable/merkle-tree.ts:240](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L240) --- url: /zkapps/o1js-reference/functions/Option --- ```ts function Option(type: A): ProvableInferPureFrom, InferValue>, InferValue | undefined> & (option: { "isSome": Bool; "value": InferProvable; }) => Option, InferValue> & { "from": Option, InferValue>; "fromValue": Option, InferValue>; "none": Option, InferValue>; } ``` Define an optional version of a provable type. ## Type parameters • **A** *extends* [`ProvableType`](../type-aliases/ProvableType.mdx) ## Parameters • **type**: `A` ## Returns `ProvableInferPureFrom`\<`A`, [`Option`](../type-aliases/Option.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>\>, `InferValue`\<`A`\> \| `undefined`\> & (`option`: \{ `"isSome"`: [`Bool`](../type-aliases/Bool.mdx); `"value"`: [`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>; \}) => [`Option`](../type-aliases/Option.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>\> & \{ `"from"`: [`Option`](../type-aliases/Option.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>\>; `"fromValue"`: [`Option`](../type-aliases/Option.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>\>; `"none"`: [`Option`](../type-aliases/Option.mdx)\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>\>; \} ## Example ```ts class OptionUInt64 extends Option(UInt64) {} // create an optional UInt64 let some = OptionUInt64.from(5n); let none = OptionUInt64.none(); // get back a UInt64 let five: UInt64 = some.assertSome('must have a value'); let zero: UInt64 = none.orElse(0n); // specify a default value ``` ## Source [lib/provable/option.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/option.ts#L37) --- url: /zkapps/o1js-reference/functions/Reducer --- ```ts function Reducer(reducer: { "actionType": T; }): ReducerReturn ``` ## Type parameters • **T** *extends* [`FlexibleProvablePure`](../type-aliases/FlexibleProvablePure.mdx)\<`any`\> • **A** *extends* `any` = [`InferProvable`](../type-aliases/InferProvable.mdx)\<`T`\> ## Parameters • **reducer** • **reducer.actionType**: `T` ## Returns `ReducerReturn`\<`A`\> ## Source [lib/mina/actions/reducer.ts:17](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/reducer.ts#L17) --- url: /zkapps/o1js-reference/functions/State --- ```ts function State(defaultValue?: A): State ``` ## Type parameters • **A** ## Parameters • **defaultValue?**: `A` ## Returns [`State`](../type-aliases/State.mdx)\<`A`\> ## Source [lib/mina/state.ts:91](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/state.ts#L91) --- url: /zkapps/o1js-reference/functions/Struct --- ```ts function Struct(type: A): (value: T) => T & { "_isStruct": true; } & Pure extends true ? ProvablePure : Provable & { "empty": () => T; "fromJSON": (x: J) => T; "fromValue": (value: From) => T; "toInput": (x: T) => { "fields": Field[]; "packed": [Field, number][]; }; "toJSON": (x: T) => J; } ``` `Struct` lets you declare composite types for use in o1js circuits. These composite types can be passed in as arguments to smart contract methods, used for on-chain state variables or as event / action types. Here's an example of creating a "Voter" struct, which holds a public key and a collection of votes on 3 different proposals: ```ts let Vote = { hasVoted: Bool, inFavor: Bool }; class Voter extends Struct({ publicKey: PublicKey, votes: [Vote, Vote, Vote] }) {} // use Voter as SmartContract input: class VoterContract extends SmartContract { \@method register(voter: Voter) { // ... } } ``` In this example, there are no instance methods on the class. This makes `Voter` type-compatible with an anonymous object of the form `{ publicKey: PublicKey, votes: Vote[] }`. This mean you don't have to create instances by using `new Voter(...)`, you can operate with plain objects: ```ts voterContract.register({ publicKey, votes }); ``` On the other hand, you can also add your own methods: ```ts class Voter extends Struct({ publicKey: PublicKey, votes: [Vote, Vote, Vote] }) { vote(index: number, inFavor: Bool) { let vote = this.votes[i]; vote.hasVoted = Bool(true); vote.inFavor = inFavor; } } ``` In this case, you'll need the constructor to create instances of `Voter`. It always takes as input the plain object: ```ts let emptyVote = { hasVoted: Bool(false), inFavor: Bool(false) }; let voter = new Voter({ publicKey, votes: Array(3).fill(emptyVote) }); voter.vote(1, Bool(true)); ``` In addition to creating types composed of Field elements, you can also include auxiliary data which does not become part of the proof. This, for example, allows you to re-use the same type outside o1js methods, where you might want to store additional metadata. To declare non-proof values of type `string`, `number`, etc, you can use the built-in objects `String`, `Number`, etc. Here's how we could add the voter's name (a string) as auxiliary data: ```ts class Voter extends Struct({ publicKey: PublicKey, votes: [Vote, Vote, Vote], fullName: String }) {} ``` Again, it's important to note that this doesn't enable you to prove anything about the `fullName` string. From the circuit point of view, it simply doesn't exist! ## Type parameters • **A** • **T** *extends* `unknown` = [`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\> • **V** *extends* `unknown` = `InferValue`\<`A`\> • **J** *extends* `unknown` = `InferJson`\<`A`\> • **Pure** *extends* `boolean` = `IsPure`\<`A`\> ## Parameters • **type**: `A` Object specifying the layout of the `Struct` ## Returns (`value`: `T`) => `T` & \{ `"_isStruct"`: `true`; \} & `Pure` *extends* `true` ? [`ProvablePure`](../type-aliases/ProvablePure.mdx)\<`T`, `V`\> : `Provable`\<`T`, `V`\> & \{ `"empty"`: () => `T`; `"fromJSON"`: (`x`: `J`) => `T`; `"fromValue"`: (`value`: `From`\<`A`\>) => `T`; `"toInput"`: (`x`: `T`) => \{ `"fields"`: [`Field`](../type-aliases/Field.mdx)[]; `"packed"`: [[`Field`](../type-aliases/Field.mdx), `number`][]; \}; `"toJSON"`: (`x`: `T`) => `J`; \} Class which you can extend ## Note Ensure you do not use or extend `Struct` as a type directly. Instead, always call it as a function to construct a type. `Struct` is not a valid provable type itself, types created with `Struct(...)` are. ## Source [lib/provable/types/struct.ts:140](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L140) --- url: /zkapps/o1js-reference/functions/VarField --- ```ts function VarField(x: VarFieldVar): VarField ``` ## Parameters • **x**: `VarFieldVar` ## Returns [`VarField`](../type-aliases/VarField.mdx) ## Source [lib/provable/field.ts:1242](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1242) --- url: /zkapps/o1js-reference/functions/WithHash --- ```ts function WithHash(type: ProvableHashable): ProvableHashable> ``` ## Type parameters • **T** ## Parameters • **type**: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> ## Returns [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<[`WithHash`](../type-aliases/WithHash.mdx)\<`T`\>\> ## Source [lib/provable/merkle-list.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L28) --- url: /zkapps/o1js-reference/functions/ZkProgram --- ```ts function ZkProgram(config: Config & { "methods": { [I in string | number | symbol]: Methods[I] }; "name": string; "overrideWrapDomain": 0 | 2 | 1; }): { "analyzeMethods": () => Promise<{ [I in keyof Config["methods"]]: UnwrapPromise> }>; "auxiliaryOutputTypes": AuxiliaryOutputs; "compile": (options?: { "cache": Cache; "forceRecompile": boolean; "proofsEnabled": boolean; }) => Promise<{ "verificationKey": { "data": string; "hash": Field; }; }>; "digest": () => Promise; "name": string; "privateInputTypes": PrivateInputs; "proofsEnabled": boolean; "publicInputType": ProvableOrUndefined>; "publicOutputType": ProvableOrVoid>; "rawMethods": { [I in keyof Config["methods"]]: Methods[I]["method"] }; "verify": (proof: Proof>, InferProvableOrVoid>>) => Promise; "setProofsEnabled": void; } & { [I in keyof Config["methods"]]: Prover>, InferProvableOrVoid>, PrivateInputs[I], InferProvableOrUndefined> } ``` ## Type parameters • **Config** *extends* \{ `"methods"`: \{\}; `"publicInput"`: [`ProvableTypePure`](../type-aliases/ProvableTypePure.mdx); `"publicOutput"`: [`ProvableTypePure`](../type-aliases/ProvableTypePure.mdx); \} • **Methods** *extends* \{ [I in string \| number \| symbol]: Method\\>, InferProvableOrVoid\\>, Config["methods"][I]\> \} • **MethodSignatures** *extends* \{\} = `Config`\[`"methods"`\] • **PrivateInputs** *extends* \{ [I in string \| number \| symbol]: MethodSignatures[I]["privateInputs"] \} = \{ [I in string \| number \| symbol]: MethodSignatures[I]["privateInputs"] \} • **AuxiliaryOutputs** *extends* \{ [I in string \| number \| symbol]: Get\ \} = \{ [I in string \| number \| symbol]: Get\ \} ## Parameters • **config**: `Config` & \{ `"methods"`: \{ [I in string \| number \| symbol]: Methods[I] \}; `"name"`: `string`; `"overrideWrapDomain"`: `0` \| `2` \| `1`; \} ## Returns \{ `"analyzeMethods"`: () => `Promise`\<`{ [I in keyof Config["methods"]]: UnwrapPromise> }`\>; `"auxiliaryOutputTypes"`: `AuxiliaryOutputs`; `"compile"`: (`options`?: \{ `"cache"`: [`Cache`](../type-aliases/Cache.mdx); `"forceRecompile"`: `boolean`; `"proofsEnabled"`: `boolean`; \}) => `Promise`\<\{ `"verificationKey"`: \{ `"data"`: `string`; `"hash"`: [`Field`](../type-aliases/Field.mdx); \}; \}\>; `"digest"`: () => `Promise`\<`string`\>; `"name"`: `string`; `"privateInputTypes"`: `PrivateInputs`; `"proofsEnabled"`: `boolean`; `"publicInputType"`: `ProvableOrUndefined`\<`Get`\<`Config`, `"publicInput"`\>\>; `"publicOutputType"`: `ProvableOrVoid`\<`Get`\<`Config`, `"publicOutput"`\>\>; `"rawMethods"`: `{ [I in keyof Config["methods"]]: Methods[I]["method"] }`; `"verify"`: (`proof`: [`Proof`](../classes/Proof.mdx)\<`InferProvableOrUndefined`\<`Get`\<`Config`, `"publicInput"`\>\>, `InferProvableOrVoid`\<`Get`\<`Config`, `"publicOutput"`\>\>\>) => `Promise`\<`boolean`\>; `"setProofsEnabled"`: `void`; \} & `{ [I in keyof Config["methods"]]: Prover>, InferProvableOrVoid>, PrivateInputs[I], InferProvableOrUndefined> }` ## Source [lib/proof-system/zkprogram.ts:174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L174) --- url: /zkapps/o1js-reference/functions/addCachedAccount --- ```ts function addCachedAccount(partialAccount: PartialAccount, graphqlEndpoint: string): void ``` Adds an account to the local cache, indexed by a GraphQL endpoint. ## Parameters • **partialAccount**: `PartialAccount` • **graphqlEndpoint**: `string`= `networkConfig.minaEndpoint` ## Returns `void` ## Source [lib/mina/fetch.ts:418](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L418) --- url: /zkapps/o1js-reference/functions/assert --- ```ts function assert(stmt: boolean | Bool, message?: string): asserts stmt ``` Assert that a statement is true. If the statement is false, throws an error with the given message. Can be used in provable code. ## Parameters • **stmt**: `boolean` \| [`Bool`](../classes/Bool.mdx) • **message?**: `string` ## Returns `asserts stmt` ## Source [lib/provable/gadgets/common.ts:57](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/gadgets/common.ts#L57) --- url: /zkapps/o1js-reference/functions/checkBitLength --- ```ts function checkBitLength( name: string, length: number, maxLength: number): void ``` ## Parameters • **name**: `string` • **length**: `number` • **maxLength**: `number`= `Fp.sizeInBits` ## Returns `void` ## Source [lib/provable/field.ts:1180](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1180) --- url: /zkapps/o1js-reference/functions/checkZkappTransaction --- ```ts function checkZkappTransaction(transactionHash: string, blockLength: number): Promise<{ "failureReason": string[][][]; "success": false; } | { "failureReason": null; "success": true; }> ``` ## Parameters • **transactionHash**: `string` • **blockLength**: `number`= `20` ## Returns `Promise`\<\{ `"failureReason"`: `string`[][][]; `"success"`: `false`; \} \| \{ `"failureReason"`: `null`; `"success"`: `true`; \}\> ## Source [lib/mina/fetch.ts:517](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L517) --- url: /zkapps/o1js-reference/functions/circuitMain --- ```ts function circuitMain( target: typeof Circuit, propertyName: string, _descriptor?: PropertyDescriptor): any ``` ## Parameters • **target**: *typeof* [`Circuit`](../classes/Circuit.mdx) • **propertyName**: `string` • **\_descriptor?**: `PropertyDescriptor` ## Returns `any` ## Source [lib/proof-system/circuit.ts:192](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L192) --- url: /zkapps/o1js-reference/functions/conditionalSwap --- ```ts function conditionalSwap( b: Bool, x: Field, y: Field): [Field, Field] ``` ## Parameters • **b**: [`Bool`](../classes/Bool.mdx) • **x**: [`Field`](../classes/Field.mdx) • **y**: [`Field`](../classes/Field.mdx) ## Returns [[`Field`](../type-aliases/Field.mdx), [`Field`](../type-aliases/Field.mdx)] ## Source [lib/provable/merkle-tree.ts:251](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L251) --- url: /zkapps/o1js-reference/functions/createEcdsa --- ```ts function createEcdsa(curve: CurveParams | typeof ForeignCurve): typeof EcdsaSignature ``` Create a class [EcdsaSignature](../classes/EcdsaSignature.mdx) for verifying ECDSA signatures on the given curve. ## Parameters • **curve**: `CurveParams` \| *typeof* [`ForeignCurve`](../classes/ForeignCurve.mdx) ## Returns *typeof* [`EcdsaSignature`](../classes/EcdsaSignature.mdx) ## Source [lib/provable/crypto/foreign-ecdsa.ts:246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-ecdsa.ts#L246) --- url: /zkapps/o1js-reference/functions/createForeignCurve --- ```ts function createForeignCurve(params: CurveParams): typeof ForeignCurve ``` Create a class representing an elliptic curve group, which is different from the native [Group](../classes/Group.mdx). ```ts const Curve = createForeignCurve(Crypto.CurveParams.Secp256k1); ``` `createForeignCurve(params)` takes curve parameters CurveParams as input. We support `modulus` and `order` to be prime numbers up to 259 bits. The returned ForeignCurveNotNeeded class represents a _non-zero curve point_ and supports standard elliptic curve operations like point addition and scalar multiplication. ForeignCurveNotNeeded also includes to associated foreign fields: `ForeignCurve.Field` and `ForeignCurve.Scalar`, see [createForeignField](createForeignField.mdx). ## Parameters • **params**: `CurveParams` ## Returns *typeof* [`ForeignCurve`](../classes/ForeignCurve.mdx) ## Source [lib/provable/crypto/foreign-curve.ts:432](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/foreign-curve.ts#L432) --- url: /zkapps/o1js-reference/functions/createForeignField --- ```ts function createForeignField(modulus: bigint): typeof UnreducedForeignField ``` Create a class representing a prime order finite field, which is different from the native [Field](../classes/Field.mdx). ```ts const SmallField = createForeignField(17n); // the finite field F_17 ``` `createForeignField(p)` takes the prime modulus `p` of the finite field as input, as a bigint. We support prime moduli up to a size of 259 bits. The returned [ForeignField](../classes/ForeignField.mdx) class supports arithmetic modulo `p` (addition and multiplication), as well as helper methods like `assertEquals()` and `equals()`. _Advanced details:_ Internally, a foreign field element is represented as three native field elements, each of which represents a limb of 88 bits. Therefore, being a valid foreign field element means that all 3 limbs fit in 88 bits, and the foreign field element altogether is smaller than the modulus p. Since the full `x < p` check is expensive, by default we only prove a weaker assertion, `x < 2^ceil(log2(p))`, see [ForeignField.assertAlmostReduced](../classes/ForeignField.mdx#assertalmostreduced-1) for more details. This weaker assumption is what we call "almost reduced", and it is represented by the [AlmostForeignField](../classes/AlmostForeignField.mdx) class. Note that only [AlmostForeignField](../classes/AlmostForeignField.mdx) supports multiplication and inversion, while UnreducedForeignField only supports addition and subtraction. This function returns the `Unreduced` class, which will cause the minimum amount of range checks to be created by default. If you want to do multiplication, you have two options: - create your field elements using the [ForeignField.AlmostReduced](../classes/ForeignField.mdx#almostreduced) constructor. ```ts let x = Provable.witness(ForeignField.AlmostReduced, () => 5n); ``` - create your field elements normally and convert them using `x.assertAlmostReduced()`. ```ts let xChecked = x.assertAlmostReduced(); // asserts x < 2^ceil(log2(p)); returns `AlmostForeignField` ``` Similarly, there is a separate class [CanonicalForeignField](../classes/CanonicalForeignField.mdx) which represents fully reduced, "canonical" field elements. To convert to a canonical field element, use `ForeignField.assertCanonical()`: ```ts x.assertCanonical(); // asserts x < p; returns `CanonicalForeignField` ``` You will likely not need canonical fields most of the time. Base types for all of these classes are separately exported as UnreducedForeignField, [AlmostForeignField](../classes/AlmostForeignField.mdx) and [CanonicalForeignField](../classes/CanonicalForeignField.mdx)., ## Parameters • **modulus**: `bigint` the modulus of the finite field you are instantiating ## Returns *typeof* `UnreducedForeignField` ## Source [lib/provable/foreign-field.ts:642](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/foreign-field.ts#L642) --- url: /zkapps/o1js-reference/functions/declareMethods --- ```ts function declareMethods(SmartContract: T, methodArguments: Record[]>): void ``` `declareMethods` can be used in place of the `@method` decorator to declare SmartContract methods along with their list of arguments. It should be placed _after_ the class declaration. Here is an example of declaring a method `update`, which takes a single argument of type `Field`: ```ts class MyContract extends SmartContract { // ... update(x: Field) { // ... } } declareMethods(MyContract, { update: [Field] }); // `[Field]` is the list of arguments! ``` Note that a method of the same name must still be defined on the class, just without the decorator. ## Type parameters • **T** *extends* *typeof* [`SmartContract`](../classes/SmartContract.mdx) ## Parameters • **SmartContract**: `T` • **methodArguments**: `Record`\<`string`, `Provable`\<`unknown`\>[]\> ## Returns `void` ## Source [lib/mina/zkapp.ts:1270](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1270) --- url: /zkapps/o1js-reference/functions/declareState --- ```ts function declareState(SmartContract: T, states: Record>): 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(); // ... } 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 }); ``` ## Type parameters • **T** *extends* *typeof* [`SmartContract`](../classes/SmartContract.mdx) ## Parameters • **SmartContract**: `T` • **states**: `Record`\<`string`, [`FlexibleProvablePure`](../type-aliases/FlexibleProvablePure.mdx)\<`any`\>\> ## Returns `void` ## Source [lib/mina/state.ts:183](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/state.ts#L183) --- url: /zkapps/o1js-reference/functions/fetchAccount --- ```ts function fetchAccount( accountInfo: { "publicKey": string | PublicKey; "tokenId": string | Field; }, graphqlEndpoint: string, __namedParameters: { "timeout": defaultTimeout; }): Promise<{ "account": Types.Account; "error": undefined; } | { "account": undefined; "error": FetchError; }> ``` Gets account information on the specified publicKey by performing a GraphQL query to the specified endpoint. This will call the 'GetAccountInfo' query which fetches zkapp related account information. If an error is returned by the specified endpoint, an error is thrown. Otherwise, the data is returned. ## Parameters • **accountInfo** • **accountInfo.publicKey**: `string` \| [`PublicKey`](../classes/PublicKey.mdx) • **accountInfo.tokenId?**: `string` \| [`Field`](../classes/Field.mdx) • **graphqlEndpoint**: `string`= `networkConfig.minaEndpoint` The graphql endpoint to fetch from • **\_\_namedParameters**= `{}` • **\_\_namedParameters.timeout**: `undefined` \| `number`= `defaultTimeout` ## Returns `Promise`\<\{ `"account"`: `Types.Account`; `"error"`: `undefined`; \} \| \{ `"account"`: `undefined`; `"error"`: `FetchError`; \}\> zkapp information on the specified account or an error is thrown ## Source [lib/mina/fetch.ts:179](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L179) --- url: /zkapps/o1js-reference/functions/fetchEvents --- ```ts function fetchEvents( accountInfo: { "publicKey": string; "tokenId": string; }, graphqlEndpoint?: string, filterOptions?: EventActionFilterOptions): Promise<{ "blockHash": event.blockInfo.stateHash; "blockHeight": UInt32; "chainStatus": event.blockInfo.chainStatus; "events": { "data": string[]; "transactionInfo": { "hash": string; "memo": string; "status": string; }; }[]; "globalSlot": UInt32; "parentBlockHash": event.blockInfo.parentHash; }[]> ``` Asynchronously fetches event data for an account from the Mina Archive Node GraphQL API. ## Parameters • **accountInfo** The account information object. • **accountInfo.publicKey**: `string` The account public key. • **accountInfo.tokenId?**: `string` The optional token ID for the account. • **graphqlEndpoint?**: `string`= `networkConfig.archiveEndpoint` The GraphQL endpoint to query. Defaults to the Archive Node GraphQL API. • **filterOptions?**: `EventActionFilterOptions`= `{}` The optional filter options object. ## Returns `Promise`\<\{ `"blockHash"`: `event.blockInfo.stateHash`; `"blockHeight"`: [`UInt32`](../classes/UInt32.mdx); `"chainStatus"`: `event.blockInfo.chainStatus`; `"events"`: \{ `"data"`: `string`[]; `"transactionInfo"`: \{ `"hash"`: `string`; `"memo"`: `string`; `"status"`: `string`; \}; \}[]; `"globalSlot"`: [`UInt32`](../classes/UInt32.mdx); `"parentBlockHash"`: `event.blockInfo.parentHash`; \}[]\> A promise that resolves to an array of objects containing event data, block information and transaction information for the account. ## Async ## Throws If the GraphQL request fails or the response is invalid. ## Example ```ts const accountInfo = { publicKey: 'B62qiwmXrWn7Cok5VhhB3KvCwyZ7NHHstFGbiU5n7m8s2RqqNW1p1wF' }; const events = await fetchEvents(accountInfo); console.log(events); ``` ## Source [lib/mina/fetch.ts:648](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L648) --- url: /zkapps/o1js-reference/functions/fetchLastBlock --- ```ts function fetchLastBlock(graphqlEndpoint: string): Promise> ``` Fetches the last block on the Mina network. ## Parameters • **graphqlEndpoint**: `string`= `networkConfig.minaEndpoint` ## Returns `Promise`\<`PreconditionBaseTypes`\<\{\}\>\> ## Source [lib/mina/fetch.ts:461](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L461) --- url: /zkapps/o1js-reference/functions/fetchTransactionStatus --- ```ts function fetchTransactionStatus(txId: string, graphqlEndpoint: string): Promise ``` Fetches the status of a transaction. ## Parameters • **txId**: `string` • **graphqlEndpoint**: `string`= `networkConfig.minaEndpoint` ## Returns `Promise`\<[`TransactionStatus`](../type-aliases/TransactionStatus.mdx)\> ## Source [lib/mina/fetch.ts:598](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L598) --- url: /zkapps/o1js-reference/functions/genericHash --- ```ts function genericHash( provable: ProvableHashable, prefix: string, value: T): Field ``` ## Type parameters • **T** ## Parameters • **provable**: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> • **prefix**: `string` • **value**: `T` ## Returns [`Field`](../classes/Field.mdx) ## Source [lib/provable/merkle-list.ts:755](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L755) --- url: /zkapps/o1js-reference/functions/initializeBindings --- ```ts function initializeBindings(): Promise ``` A function that has to finish before any bindings exports can be used. ## Returns `Promise`\<`void`\> ## Source [snarky.d.ts:763](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/snarky.d.ts#L763) --- url: /zkapps/o1js-reference/functions/merkleListHash --- ```ts function merkleListHash(provable: ProvableHashable, prefix: string): (hash: Field, value: T) => Field ``` ## Type parameters • **T** ## Parameters • **provable**: [`ProvableHashable`](../type-aliases/ProvableHashable.mdx)\<`T`\> • **prefix**: `string`= `''` ## Returns `Function` > ### Parameters > > • **hash**: [`Field`](../classes/Field.mdx) > > • **value**: `T` > > ### Returns > > [`Field`](../classes/Field.mdx) > ## Source [lib/provable/merkle-list.ts:765](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L765) --- url: /zkapps/o1js-reference/functions/method --- ```ts function method( target: T & { [k in string]: Function }, methodName: K & string & keyof T, descriptor: PropertyDescriptor, returnType?: Provable): void ``` A decorator to use in a zkApp to mark a method as provable. You can use inside your zkApp class as: ``` \@method async myMethod(someArg: Field) { // your code here } ``` To return a value from the method, you have to explicitly declare the return type using the [method.returns](method.mdx#returns) decorator: ``` \@method.returns(Field) async myMethod(someArg: Field): Promise { // your code here } ``` ## Type parameters • **K** *extends* `string` • **T** *extends* [`SmartContract`](../classes/SmartContract.mdx) ## Parameters • **target**: `T` & `{ [k in string]: Function }` • **methodName**: `K` & `string` & keyof `T` • **descriptor**: `PropertyDescriptor` • **returnType?**: `Provable`\<`any`\> ## Returns `void` ## Source [lib/mina/zkapp.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L105) --- url: /zkapps/o1js-reference/functions/provable --- ```ts function provable(typeObj: A, options?: {}): InferredProvable ``` ## Type parameters • **A** ## Parameters • **typeObj**: `A` • **options?** **Deprecated** ## Returns `InferredProvable`\<`A`, [`Field`](../classes/Field.mdx)\> ## Source [lib/provable/types/provable-derivers.ts:78](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-derivers.ts#L78) --- url: /zkapps/o1js-reference/functions/provablePure --- ```ts function provablePure(typeObj: A): ProvablePureExtended, InferValue, InferJson> ``` ## Type parameters • **A** ## Parameters • **typeObj**: `A` ## Returns `ProvablePureExtended`\<[`InferProvable`](../type-aliases/InferProvable.mdx)\<`A`\>, `InferValue`\<`A`\>, `InferJson`\<`A`\>\> ## Source [lib/provable/types/provable-derivers.ts:80](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-derivers.ts#L80) --- url: /zkapps/o1js-reference/functions/public --- ```ts function public_( target: any, _key: string | symbol, index: number): void ``` ## Parameters • **target**: `any` • **\_key**: `string` \| `symbol` • **index**: `number` ## Returns `void` ## Source [lib/proof-system/circuit.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/circuit.ts#L156) --- url: /zkapps/o1js-reference/functions/readVarMessage --- ```ts function readVarMessage( methodName: string, varName: string, varDescription: string): string ``` ## Parameters • **methodName**: `string` • **varName**: `string` • **varDescription**: `string` ## Returns `string` ## Source [lib/provable/field.ts:1222](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1222) --- url: /zkapps/o1js-reference/functions/sendZkapp --- ```ts function sendZkapp( json: string, graphqlEndpoint: string, __namedParameters: { "timeout": defaultTimeout; }): Promise<[undefined, FetchError] | [FetchResponse, undefined]> ``` Sends a zkApp command (transaction) to the specified GraphQL endpoint. ## Parameters • **json**: `string` • **graphqlEndpoint**: `string`= `networkConfig.minaEndpoint` • **\_\_namedParameters**= `{}` • **\_\_namedParameters.timeout**: `undefined` \| `number`= `defaultTimeout` ## Returns `Promise`\<[`undefined`, `FetchError`] \| [`FetchResponse`\<`SendZkAppResponse`\>, `undefined`]\> ## Source [lib/mina/fetch.ts:618](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L618) --- url: /zkapps/o1js-reference/functions/setArchiveGraphqlEndpoint --- ```ts function setArchiveGraphqlEndpoint(graphqlEndpoint: string): void ``` Sets up a GraphQL endpoint to be used for fetching information from an Archive Node. ## Parameters • **graphqlEndpoint**: `string` ## Returns `void` ## Source [lib/mina/fetch.ts:134](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L134) --- url: /zkapps/o1js-reference/functions/setGraphqlEndpoint --- ```ts function setGraphqlEndpoint(graphqlEndpoint: string): void ``` ## Parameters • **graphqlEndpoint**: `string` ## Returns `void` ## Source [lib/mina/fetch.ts:112](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L112) --- url: /zkapps/o1js-reference/functions/setGraphqlEndpoints --- ```ts function setGraphqlEndpoints(__namedParameters: string[]): void ``` ## Parameters • **\_\_namedParameters**: `string`[] ## Returns `void` ## Source [lib/mina/fetch.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L105) --- url: /zkapps/o1js-reference/functions/setNumberOfWorkers --- ```ts function setNumberOfWorkers(numWorkers: number): void ``` Set the number of workers to use for parallelizing the proof generation. By default the number of workers is set to the number of physical CPU cores on your machine, but there may be some instances where you want to set the number of workers manually. Some machines may have a large number of cores, but not enough memory to support that many workers. In that case, you can set the number of workers to a lower number to avoid running out of memory. On the other hand, some machines with heterogeneous cores may benefit from setting the number of workers to a lower number to avoid contention between core types if load-link/store-conditional multithreading is used. Feel free to experiment and see what works best for your use case. Maybe you can squeeze slightly more performance out by tweaking this value :) ## Parameters • **numWorkers**: `number` ## Returns `void` ## Example ```typescript setNumberOfWorkers(2); // set the number of workers to 2 ``` ## Source [lib/proof-system/workers.ts:15](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/workers.ts#L15) --- url: /zkapps/o1js-reference/functions/state-1 --- ```ts function state(type: ProvableTypePure | FlexibleProvablePure): (target: SmartContract & { "constructor": any; }, key: string, _descriptor?: PropertyDescriptor) => void ``` 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(); ``` ## Type parameters • **A** ## Parameters • **type**: [`ProvableTypePure`](../type-aliases/ProvableTypePure.mdx)\<`A`\> \| [`FlexibleProvablePure`](../type-aliases/FlexibleProvablePure.mdx)\<`A`\> ## Returns `Function` > ### Parameters > > • **target**: [`SmartContract`](../classes/SmartContract.mdx) & \{ > `"constructor"`: `any`; > \} > > • **key**: `string` > > • **\_descriptor?**: `PropertyDescriptor` > > ### Returns > > `void` > ## Source [lib/mina/state.ts:105](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/state.ts#L105) --- url: /zkapps/o1js-reference/functions/toConstantField --- ```ts function toConstantField( x: Field, methodName: string, varName: string, varDescription: string): ConstantField ``` ## Parameters • **x**: [`Field`](../classes/Field.mdx) • **methodName**: `string` • **varName**: `string`= `'x'` • **varDescription**: `string`= `'field element'` ## Returns [`ConstantField`](../type-aliases/ConstantField.mdx) ## Source [lib/provable/field.ts:1197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1197) --- url: /zkapps/o1js-reference/functions/toFp --- ```ts function toFp(x: string | number | bigint | Field): bigint ``` ## Parameters • **x**: `string` \| `number` \| `bigint` \| [`Field`](../classes/Field.mdx) ## Returns `bigint` ## Source [lib/provable/field.ts:1156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1156) --- url: /zkapps/o1js-reference/functions/verify --- ```ts function verify(proof: ProofBase | JsonProof, verificationKey: string | VerificationKey): Promise ``` ## Parameters • **proof**: [`ProofBase`](../classes/ProofBase.mdx)\<`any`, `any`\> \| [`JsonProof`](../type-aliases/JsonProof.mdx) • **verificationKey**: `string` \| [`VerificationKey`](../classes/VerificationKey.mdx) ## Returns `Promise`\<`boolean`\> ## Source [lib/proof-system/zkprogram.ts:109](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L109) --- url: /zkapps/o1js-reference/functions/withHashes --- ```ts function withHashes( data: T[], nextHash: (hash: Field, value: T) => Field, emptyHash: Field): { "data": WithHash[]; "hash": Field; } ``` ## Type parameters • **T** ## Parameters • **data**: `T`[] • **nextHash** • **emptyHash**: [`Field`](../classes/Field.mdx) ## Returns ```ts { "data": WithHash[]; "hash": Field; } ``` ### data ```ts data: WithHash[]; ``` ### hash ```ts hash: Field; ``` ## Source [lib/provable/merkle-list.ts:773](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L773) --- url: /zkapps/o1js-reference/functions/withMessage --- ```ts function withMessage(error: unknown, message?: string): unknown ``` ## Parameters • **error**: `unknown` • **message?**: `string` ## Returns `unknown` ## Source [lib/provable/field.ts:1174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1174) --- url: /zkapps/o1js-reference/interfaces/Permissions --- Permissions specify how specific aspects of the zkapp account are allowed to be modified. All fields are denominated by a Permission. ## Extends - `Permissions_` ## Properties ### access ```ts access: AuthRequired; ``` Permission to control the ability to include _any_ account update for this account in a transaction. Note that this is more restrictive than all other permissions combined. For normal accounts it can safely be set to `none`, but for token contracts this has to be more restrictive, to prevent unauthorized token interactions -- for example, it could be `proofOrSignature`. #### Overrides `Permissions_.access` #### Source [lib/mina/account-update.ts:397](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L397) *** ### editActionState ```ts editActionState: AuthRequired; ``` The Permission corresponding to the ability to emit actions to the account. #### Overrides `Permissions_.editActionState` #### Source [lib/mina/account-update.ts:376](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L376) *** ### editState ```ts editState: AuthRequired; ``` The Permission corresponding to the 8 state fields associated with an account. #### Overrides `Permissions_.editState` #### Source [lib/mina/account-update.ts:332](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L332) *** ### incrementNonce ```ts incrementNonce: AuthRequired; ``` #### Overrides `Permissions_.incrementNonce` #### Source [lib/mina/account-update.ts:385](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L385) *** ### receive ```ts receive: AuthRequired; ``` The Permission corresponding to the ability to receive transactions to this account. #### Overrides `Permissions_.receive` #### Source [lib/mina/account-update.ts:344](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L344) *** ### send ```ts send: AuthRequired; ``` The Permission corresponding to the ability to send transactions from this account. #### Overrides `Permissions_.send` #### Source [lib/mina/account-update.ts:338](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L338) *** ### setDelegate ```ts setDelegate: AuthRequired; ``` The Permission corresponding to the ability to set the delegate field of the account. #### Overrides `Permissions_.setDelegate` #### Source [lib/mina/account-update.ts:350](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L350) *** ### setPermissions ```ts setPermissions: AuthRequired; ``` The Permission corresponding to the ability to set the permissions field of the account. #### Overrides `Permissions_.setPermissions` #### Source [lib/mina/account-update.ts:356](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L356) *** ### setTiming ```ts setTiming: AuthRequired; ``` #### Overrides `Permissions_.setTiming` #### Source [lib/mina/account-update.ts:387](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L387) *** ### setTokenSymbol ```ts setTokenSymbol: AuthRequired; ``` The Permission corresponding to the ability to set the token symbol for this account. #### Overrides `Permissions_.setTokenSymbol` #### Source [lib/mina/account-update.ts:382](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L382) *** ### setVerificationKey ```ts setVerificationKey: VerificationKeyPermission; ``` The Permission corresponding to the ability to set the verification key associated with the circuit tied to this account. Effectively "upgradeability" of the smart contract. #### Overrides `Permissions_.setVerificationKey` #### Source [lib/mina/account-update.ts:363](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L363) *** ### setVotingFor ```ts setVotingFor: AuthRequired; ``` #### Overrides `Permissions_.setVotingFor` #### Source [lib/mina/account-update.ts:386](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L386) *** ### setZkappUri ```ts setZkappUri: AuthRequired; ``` The Permission corresponding to the ability to set the zkapp uri typically pointing to the source code of the smart contract. Usually this should be changed whenever the [Permissions.setVerificationKey](Permissions.mdx#setverificationkey) is changed. Effectively "upgradeability" of the smart contract. #### Overrides `Permissions_.setZkappUri` #### Source [lib/mina/account-update.ts:371](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L371) --- url: /zkapps/o1js-reference/namespaces/Crypto/README --- ## Index | Member | Description | | :------ | :------ | | [Curve](type-aliases/Curve.mdx) | - | | [CurveParams](type-aliases/CurveParams.mdx) | Parameters defining an elliptic curve in short Weierstraß form | --- url: /zkapps/o1js-reference/namespaces/Crypto/type-aliases/Curve --- ```ts type Curve: CurveAffine; ``` ## Source [lib/provable/crypto/crypto.ts:29](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/crypto.ts#L29) --- url: /zkapps/o1js-reference/namespaces/Crypto/type-aliases/CurveParams --- ```ts type CurveParams: CurveParams_; ``` Parameters defining an elliptic curve in short Weierstraß form y^2 = x^3 + ax + b ## Source [lib/provable/crypto/crypto.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/crypto.ts#L27) --- url: /zkapps/o1js-reference/namespaces/Encryption/README --- ## Index | Member | Description | | :------ | :------ | | [CipherText](type-aliases/CipherText.mdx) | - | | [CipherTextBytes](type-aliases/CipherTextBytes.mdx) | - | | [decrypt](functions/decrypt.mdx) | Decrypts a [CipherText](type-aliases/CipherText.mdx) using a [PrivateKey](../../classes/PrivateKey.mdx). | | [decryptBytes](functions/decryptBytes.mdx) | Decrypts a [CipherText](type-aliases/CipherText.mdx) using a [PrivateKey](../../classes/PrivateKey.mdx). | | [encrypt](functions/encrypt.mdx) | Public Key Encryption, encrypts Field elements using a [PublicKey](../../classes/PublicKey.mdx). | | [encryptBytes](functions/encryptBytes.mdx) | Public Key Encryption, encrypts Bytes using a [PublicKey](../../classes/PublicKey.mdx). | --- url: /zkapps/o1js-reference/namespaces/Encryption/functions/decrypt --- ```ts function decrypt(__namedParameters: CipherText, privateKey: PrivateKey): Field[] ``` Decrypts a [CipherText](../type-aliases/CipherText.mdx) using a [PrivateKey](../../../classes/PrivateKey.mdx). ## Parameters • **\_\_namedParameters**: [`CipherText`](../type-aliases/CipherText.mdx) • **privateKey**: [`PrivateKey`](../../../classes/PrivateKey.mdx) ## Returns [`Field`](../../../classes/Field.mdx)[] ## Source [lib/provable/crypto/encryption.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L28) --- url: /zkapps/o1js-reference/namespaces/Encryption/functions/decryptBytes --- ```ts function decryptBytes(cipherText: CipherTextBytes, privateKey: PrivateKey): Bytes ``` Decrypts a [CipherText](../type-aliases/CipherText.mdx) using a [PrivateKey](../../../classes/PrivateKey.mdx). ## Parameters • **cipherText**: [`CipherTextBytes`](../type-aliases/CipherTextBytes.mdx) • **privateKey**: [`PrivateKey`](../../../classes/PrivateKey.mdx) ## Returns `Bytes` ## Source [lib/provable/crypto/encryption.ts:129](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L129) --- url: /zkapps/o1js-reference/namespaces/Encryption/functions/encrypt --- ```ts function encrypt(message: Field[], otherPublicKey: PublicKey): CipherText ``` Public Key Encryption, encrypts Field elements using a [PublicKey](../../../classes/PublicKey.mdx). ## Parameters • **message**: [`Field`](../../../classes/Field.mdx)[] • **otherPublicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) ## Returns [`CipherText`](../type-aliases/CipherText.mdx) ## Source [lib/provable/crypto/encryption.ts:64](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L64) --- url: /zkapps/o1js-reference/namespaces/Encryption/functions/encryptBytes --- ```ts function encryptBytes(message: Bytes, otherPublicKey: PublicKey): CipherTextBytes ``` Public Key Encryption, encrypts Bytes using a [PublicKey](../../../classes/PublicKey.mdx). ## Parameters • **message**: `Bytes` • **otherPublicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) ## Returns [`CipherTextBytes`](../type-aliases/CipherTextBytes.mdx) ## Source [lib/provable/crypto/encryption.ts:97](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L97) --- url: /zkapps/o1js-reference/namespaces/Encryption/type-aliases/CipherText --- ```ts type CipherText: { "cipherText": Field[]; "publicKey": Group; }; ``` ## Type declaration ### cipherText ```ts cipherText: Field[]; ``` ### publicKey ```ts publicKey: Group; ``` ## Source [lib/provable/crypto/encryption.ts:19](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L19) --- url: /zkapps/o1js-reference/namespaces/Encryption/type-aliases/CipherTextBytes --- ```ts type CipherTextBytes: CipherText & { "messageLength": number; }; ``` ## Type declaration ### messageLength ```ts messageLength: number; ``` ## Source [lib/provable/crypto/encryption.ts:23](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/encryption.ts#L23) --- url: /zkapps/o1js-reference/namespaces/Experimental/README --- This module exposes APIs that are unstable, in the sense that the API surface is expected to change. (Not unstable in the sense that they are less functional or tested than other parts.) ## Index | Member | Description | | :------ | :------ | | [BatchReducer](classes/BatchReducer.mdx) | A reducer to process actions in fixed-size batches. | | [OffchainStateCommitments](classes/OffchainStateCommitments.mdx) | Commitments that keep track of the current state of an offchain Merkle tree constructed from actions. | | [ActionBatch](type-aliases/ActionBatch.mdx) | - | | [IndexedMerkleMap](type-aliases/IndexedMerkleMap.mdx) | - | | [ActionBatch](functions/ActionBatch.mdx) | Provable type that represents a batch of actions. | | [IndexedMerkleMap](functions/IndexedMerkleMap.mdx) | Class factory for an Indexed Merkle Map with a given height. | | [OffchainState](functions/OffchainState.mdx) | Offchain state for a `SmartContract`. | | [memoizeWitness](functions/memoizeWitness.mdx) | Like Provable.witness, but memoizes the witness during transaction construction | --- url: /zkapps/o1js-reference/namespaces/Experimental/classes/BatchReducer --- A reducer to process actions in fixed-size batches. ```ts let batchReducer = new BatchReducer({ actionType: Action, batchSize: 5 }); // in contract: concurrent dispatching of actions batchReducer.dispatch(action); // reducer logic // outside contract: prepare a list of { batch, proof } objects which cover all pending actions let batches = await batchReducer.prepareBatches(); // in contract: process a single batch // create one transaction that does this for each batch! batchReducer.processBatch({ batch, proof }, (action, isDummy) => { // ... }); ``` ## Extends - `BatchReducer`\<`ActionType`, `BatchSize`, `Action`\> ## Type parameters • **ActionType** *extends* `Actionable`\<`any`\> • **BatchSize** *extends* `number` = `number` • **Action** = [`InferProvable`](../../../type-aliases/InferProvable.mdx)\<`ActionType`\> ## Constructors ### new BatchReducer() ```ts new BatchReducer(__namedParameters: { "actionType": ActionType; "batchSize": BatchSize; "maxActionsPerUpdate": number; "maxUpdatesFinalProof": 100; "maxUpdatesPerProof": 300; }): BatchReducer ``` #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.actionType**: `ActionType` The provable type of actions submitted by this reducer. • **\_\_namedParameters.batchSize**: `BatchSize` The number of actions in a batch. The idea is to process one batch per transaction, by calling `processBatch()`. The motivation for processing actions in small batches is to work around the protocol limit on the number of account updates. If every action should result in an account update, then you have to set the batch size low enough to not exceed the limit. If transaction limits are no concern, the `batchSize` could be set based on amount of logic you do per action. A smaller batch size will make proofs faster, but you might need more individual transactions as more batches are needed to process all pending actions. • **\_\_namedParameters.maxActionsPerUpdate?**: `number`= `undefined` The maximum number of actions dispatched in any of the zkApp methods on the contract. Note: This number just has to be an upper bound of the actual maximum, but if it's the precise number, fewer constraints will be used. (The overhead of a higher number is fairly small though.) A restriction is that the number has to be less or equal than the `batchSize`. The reason is that actions in one account update are always processed together, so if you'd have more actions in one than the batch size, we couldn't process them at all. By default, this is set to `Math.min(batchSize, 5)` which should be sensible for most applications. • **\_\_namedParameters.maxUpdatesFinalProof?**: `number`= `100` The maximum number of action lists (= all actions on an account update) to process inside `processBatch()`, i.e. in your zkApp method. Default: 100, which will take up about 3000 constraints. The current default should be sensible for most applications, but here are some trade-offs to consider when changing it: - Using a smaller number means a smaller circuit, so proofs of your method will be faster. - Using a bigger number means it's more likely that you can prove _all_ actions in the method call and won't need a recursive proof. So, go lower if you expect very few actions, and higher if you expect a lot of actions. • **\_\_namedParameters.maxUpdatesPerProof?**: `number`= `300` The maximum number of action lists (= all actions on an account update) to process in a single recursive proof, in `prepareBatches()`. Default: 300, which will take up about 9000 constraints. The current default should be sensible for most applications, but here are some trade-offs to consider when changing it: - Using a smaller number means a smaller circuit, so recursive proofs will be faster. - Using a bigger number means you'll need fewer recursive proofs in the case a lot of actions are pending. So, go lower if you expect very few actions, and higher if you expect a lot of actions. (Note: A larger circuit causes longer compilation and proof times for your zkApp even if you _never_ need a recursive proof) #### Returns [`BatchReducer`](BatchReducer.mdx)\<`ActionType`, `BatchSize`, `Action`\> #### Inherited from `BatchReducer_.BatchReducer.constructor` #### Source [lib/mina/actions/batch-reducer.ts:75](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L75) ## Properties ### Batch ```ts Batch: (value: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; } & { "_isStruct": true; } & Provable<{ "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }, { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": any; "useOnchainStack": Bool; "witnesses": ActionWitnesses; }> & { "empty": () => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "fromJSON": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "fromValue": (value: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": any; "useOnchainStack": Bool; "witnesses": ActionWitnesses | Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "toInput": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "fields": Field[]; "packed": [Field, number][]; }; "toJSON": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }; }; ``` #### Type declaration ##### \_isStruct ```ts _isStruct: true; ``` #### Type declaration ##### empty() ```ts empty: () => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; ``` ###### Returns ```ts { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; } ``` ###### isRecursive ```ts isRecursive: Bool = Bool; ``` ###### onchainActionState ```ts onchainActionState: Field = Field; ``` ###### onchainStack ```ts onchainStack: Field = Field; ``` ###### processedActionState ```ts processedActionState: Field = Field; ``` ###### stack ```ts stack: MerkleList>>; ``` ###### useOnchainStack ```ts useOnchainStack: Bool = Bool; ``` ###### witnesses ```ts witnesses: Unconstrained; ``` ##### fromJSON() ```ts fromJSON: (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; ``` ###### Parameters • **x** • **x.isRecursive**: `boolean`= `Bool` • **x.onchainActionState**: `string`= `Field` • **x.onchainStack**: `string`= `Field` • **x.processedActionState**: `string`= `Field` • **x.stack**= `undefined` • **x.stack.\_emptyHash**: `null` \| `string` • **x.stack.\_innerProvable**: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \} • **x.stack.\_nextHash**: `null` \| \{\} • **x.stack.\_provable**: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \} • **x.stack.empty** • **x.stack.emptyHash**: `string` • **x.stack.from** • **x.stack.fromReverse** • **x.stack.prototype** • **x.stack.prototype.Constructor** • **x.stack.prototype.Constructor.\_emptyHash**: `null` \| `string` • **x.stack.prototype.Constructor.\_innerProvable**: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \} • **x.stack.prototype.Constructor.\_nextHash**: `null` \| \{\} • **x.stack.prototype.Constructor.\_provable**: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \} • **x.stack.prototype.Constructor.emptyHash**: `string` • **x.stack.prototype.Constructor.prototype**: \{ hash: string; data: \{ get: \{\}; set: \{\}; setTo: \{\}; updateAsProver: \{\}; \}; isEmpty: \{\}; push: \{\}; pushIf: \{\}; popExn: \{\}; pop: \{\}; popIf: \{\}; popIfUnsafe: \{\}; clone: \{\}; forEach: \{\}; startIterating: \{\}; startIteratingFromLast: \{\}; ... 4 more ...; readonly innerProvable: \{ ...; \}; \} • **x.stack.prototype.Constructor.create** Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. **Example** ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` • **x.stack.prototype.data** • **x.stack.prototype.data.get** Read an unconstrained value. Note: Can only be called outside provable code. • **x.stack.prototype.data.set** Modify the unconstrained value. • **x.stack.prototype.data.setTo** Set the unconstrained value to the same as another `Unconstrained`. • **x.stack.prototype.data.updateAsProver** Update an `Unconstrained` by a witness computation. • **x.stack.prototype.hash**: `string` • **x.stack.prototype.innerProvable** • **x.stack.prototype.innerProvable.check** Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. **Param** the element of type `T` to put assertions on. • **x.stack.prototype.innerProvable.empty** • **x.stack.prototype.innerProvable.fromFields** A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. **Param** an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. **Param** an array of any type describing the "auxiliary" data of the new `T` element, optional. • **x.stack.prototype.innerProvable.fromValue** Convert provable type from a normal JS type. • **x.stack.prototype.innerProvable.toAuxiliary** A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. **Param** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **x.stack.prototype.innerProvable.toCanonical?**: `null` \| \{\} Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. • **x.stack.prototype.innerProvable.toFields** A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. **Param** the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. • **x.stack.prototype.innerProvable.toInput** • **x.stack.prototype.innerProvable.toValue** Convert provable type to a normal JS type. • **x.stack.prototype.innerProvable.sizeInFields** • **x.stack.prototype.clone** • **x.stack.prototype.forEach** Iterate through the list in a fixed number of steps any apply a given callback on each element. Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback. Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the `isDummy` flag separately. • **x.stack.prototype.isEmpty** • **x.stack.prototype.lengthUnconstrained** • **x.stack.prototype.nextHash** • **x.stack.prototype.pop** Remove the last element from the list and return it. If the list is empty, returns a dummy element. • **x.stack.prototype.popExn** Remove the last element from the list and return it. This proves that the list is non-empty, and fails otherwise. • **x.stack.prototype.popIf** Return the last element, but only remove it if `condition` is true. If the list is empty, returns a dummy element. • **x.stack.prototype.popIfUnsafe** Low-level, minimal version of `pop()` which lets the _caller_ decide whether there is an element to pop. I.e. this proves: - If the input condition is true, this returns the last element and removes it from the list. - If the input condition is false, the list is unchanged and the return value is garbage. Note that if the caller passes `true` but the list is empty, this will fail. If the caller passes `false` but the list is non-empty, this succeeds and just doesn't pop off an element. • **x.stack.prototype.push** Push a new element to the list. • **x.stack.prototype.pushIf** Push a new element to the list, if the `condition` is true. • **x.stack.prototype.startIterating** • **x.stack.prototype.startIteratingFromLast** • **x.stack.prototype.toArrayUnconstrained** • **x.stack.provable** • **x.stack.provable.check** Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. **Param** the element of type `T` to put assertions on. • **x.stack.provable.empty** • **x.stack.provable.fromFields** A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. **Param** an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. **Param** an array of any type describing the "auxiliary" data of the new `T` element, optional. • **x.stack.provable.fromValue** Convert provable type from a normal JS type. • **x.stack.provable.toAuxiliary** A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. **Param** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **x.stack.provable.toCanonical?**: `null` \| \{\} Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. • **x.stack.provable.toFields** A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. **Param** the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. • **x.stack.provable.toInput** • **x.stack.provable.toValue** Convert provable type to a normal JS type. • **x.stack.provable.sizeInFields** • **x.stack.create** Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. **Example** ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` • **x.useOnchainStack**: `boolean`= `Bool` • **x.witnesses**= `undefined` • **x.witnesses.check** Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. **Param** the element of type `T` to put assertions on. • **x.witnesses.empty** • **x.witnesses.fromFields** A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. **Param** an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. **Param** an array of any type describing the "auxiliary" data of the new `T` element, optional. • **x.witnesses.fromValue** Convert provable type from a normal JS type. • **x.witnesses.toAuxiliary** A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. **Param** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **x.witnesses.toCanonical?**: `null` \| \{\} Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. • **x.witnesses.toFields** A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. **Param** the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. • **x.witnesses.toInput** • **x.witnesses.toValue** Convert provable type to a normal JS type. • **x.witnesses.sizeInFields** ###### Returns ```ts { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; } ``` ###### isRecursive ```ts isRecursive: Bool = Bool; ``` ###### onchainActionState ```ts onchainActionState: Field = Field; ``` ###### onchainStack ```ts onchainStack: Field = Field; ``` ###### processedActionState ```ts processedActionState: Field = Field; ``` ###### stack ```ts stack: MerkleList>>; ``` ###### useOnchainStack ```ts useOnchainStack: Bool = Bool; ``` ###### witnesses ```ts witnesses: Unconstrained; ``` ##### fromValue() ```ts fromValue: (value: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": any; "useOnchainStack": Bool; "witnesses": ActionWitnesses | Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; ``` ###### Parameters • **value** • **value.isRecursive**: `boolean` \| [`Bool`](../../../classes/Bool.mdx)= `Bool` • **value.onchainActionState**: `string` \| `number` \| `bigint` \| [`Field`](../../../classes/Field.mdx)= `Field` • **value.onchainStack**: `string` \| `number` \| `bigint` \| [`Field`](../../../classes/Field.mdx)= `Field` • **value.processedActionState**: `string` \| `number` \| `bigint` \| [`Field`](../../../classes/Field.mdx)= `Field` • **value.stack**: `any`= `undefined` • **value.useOnchainStack**: `boolean` \| [`Bool`](../../../classes/Bool.mdx)= `Bool` • **value.witnesses**: `ActionWitnesses` \| [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>= `undefined` ###### Returns ```ts { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; } ``` ###### isRecursive ```ts isRecursive: Bool = Bool; ``` ###### onchainActionState ```ts onchainActionState: Field = Field; ``` ###### onchainStack ```ts onchainStack: Field = Field; ``` ###### processedActionState ```ts processedActionState: Field = Field; ``` ###### stack ```ts stack: MerkleList>>; ``` ###### useOnchainStack ```ts useOnchainStack: Bool = Bool; ``` ###### witnesses ```ts witnesses: Unconstrained; ``` ##### toInput() ```ts toInput: (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` ###### Parameters • **x** • **x.isRecursive**: [`Bool`](../../../classes/Bool.mdx)= `Bool` • **x.onchainActionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.onchainStack**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.processedActionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.stack**: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`any`\>\>\>= `undefined` • **x.useOnchainStack**: [`Bool`](../../../classes/Bool.mdx)= `Bool` • **x.witnesses**: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>= `undefined` ###### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ###### fields? ```ts optional fields: Field[]; ``` ###### packed? ```ts optional packed: [Field, number][]; ``` ##### toJSON() ```ts toJSON: (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }; ``` ###### Parameters • **x** • **x.isRecursive**: [`Bool`](../../../classes/Bool.mdx)= `Bool` • **x.onchainActionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.onchainStack**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.processedActionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.stack**: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`any`\>\>\>= `undefined` • **x.useOnchainStack**: [`Bool`](../../../classes/Bool.mdx)= `Bool` • **x.witnesses**: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>= `undefined` ###### Returns ```ts { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; } ``` ###### isRecursive ```ts isRecursive: boolean = Bool; ``` ###### onchainActionState ```ts onchainActionState: string = Field; ``` ###### onchainStack ```ts onchainStack: string = Field; ``` ###### processedActionState ```ts processedActionState: string = Field; ``` ###### stack ```ts stack: { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; ``` ###### stack.\_emptyHash ```ts _emptyHash: null | string; ``` ###### stack.\_innerProvable ```ts _innerProvable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.\_nextHash ```ts _nextHash: null | {}; ``` ###### stack.\_provable ```ts _provable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.empty ```ts empty: {}; ``` ###### stack.emptyHash ```ts emptyHash: string; ``` ###### stack.from ```ts from: {}; ``` ###### stack.fromReverse ```ts fromReverse: {}; ``` ###### stack.prototype ```ts prototype: { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; ``` ###### stack.prototype.Constructor ```ts Constructor: { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; ``` ###### stack.prototype.Constructor.\_emptyHash ```ts _emptyHash: null | string; ``` ###### stack.prototype.Constructor.\_innerProvable ```ts _innerProvable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.prototype.Constructor.\_nextHash ```ts _nextHash: null | {}; ``` ###### stack.prototype.Constructor.\_provable ```ts _provable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.prototype.Constructor.emptyHash ```ts emptyHash: string; ``` ###### stack.prototype.Constructor.prototype ```ts prototype: { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; ``` ###### stack.prototype.Constructor.create ```ts create; ``` Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. ###### Example ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` ###### stack.prototype.data ```ts data: { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; ``` ###### stack.prototype.data.get ```ts get; ``` Read an unconstrained value. Note: Can only be called outside provable code. ###### stack.prototype.data.set ```ts set; ``` Modify the unconstrained value. ###### stack.prototype.data.setTo ```ts setTo; ``` Set the unconstrained value to the same as another `Unconstrained`. ###### stack.prototype.data.updateAsProver ```ts updateAsProver; ``` Update an `Unconstrained` by a witness computation. ###### stack.prototype.hash ```ts hash: string; ``` ###### stack.prototype.innerProvable ```ts innerProvable: { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.prototype.innerProvable.check ```ts check: {}; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. ###### Param the element of type `T` to put assertions on. ###### stack.prototype.innerProvable.empty ```ts empty: {}; ``` ###### stack.prototype.innerProvable.fromFields ```ts fromFields: {}; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. ###### Param an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. ###### Param an array of any type describing the "auxiliary" data of the new `T` element, optional. ###### stack.prototype.innerProvable.fromValue ```ts fromValue: {}; ``` Convert provable type from a normal JS type. ###### stack.prototype.innerProvable.toAuxiliary ```ts toAuxiliary: {}; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. ###### Param the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. ###### stack.prototype.innerProvable.toCanonical? ```ts optional toCanonical: null | {}; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. ###### stack.prototype.innerProvable.toFields ```ts toFields: {}; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. ###### Param the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. ###### stack.prototype.innerProvable.toInput ```ts toInput: {}; ``` ###### stack.prototype.innerProvable.toValue ```ts toValue: {}; ``` Convert provable type to a normal JS type. ###### stack.prototype.innerProvable.sizeInFields ```ts sizeInFields; ``` ###### stack.prototype.clone ```ts clone; ``` ###### stack.prototype.forEach ```ts forEach; ``` Iterate through the list in a fixed number of steps any apply a given callback on each element. Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback. Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the `isDummy` flag separately. ###### stack.prototype.isEmpty ```ts isEmpty; ``` ###### stack.prototype.lengthUnconstrained ```ts lengthUnconstrained; ``` ###### stack.prototype.nextHash ```ts nextHash; ``` ###### stack.prototype.pop ```ts pop; ``` Remove the last element from the list and return it. If the list is empty, returns a dummy element. ###### stack.prototype.popExn ```ts popExn; ``` Remove the last element from the list and return it. This proves that the list is non-empty, and fails otherwise. ###### stack.prototype.popIf ```ts popIf; ``` Return the last element, but only remove it if `condition` is true. If the list is empty, returns a dummy element. ###### stack.prototype.popIfUnsafe ```ts popIfUnsafe; ``` Low-level, minimal version of `pop()` which lets the _caller_ decide whether there is an element to pop. I.e. this proves: - If the input condition is true, this returns the last element and removes it from the list. - If the input condition is false, the list is unchanged and the return value is garbage. Note that if the caller passes `true` but the list is empty, this will fail. If the caller passes `false` but the list is non-empty, this succeeds and just doesn't pop off an element. ###### stack.prototype.push ```ts push; ``` Push a new element to the list. ###### stack.prototype.pushIf ```ts pushIf; ``` Push a new element to the list, if the `condition` is true. ###### stack.prototype.startIterating ```ts startIterating; ``` ###### stack.prototype.startIteratingFromLast ```ts startIteratingFromLast; ``` ###### stack.prototype.toArrayUnconstrained ```ts toArrayUnconstrained; ``` ###### stack.provable ```ts provable: { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### stack.provable.check ```ts check: {}; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. ###### Param the element of type `T` to put assertions on. ###### stack.provable.empty ```ts empty: {}; ``` ###### stack.provable.fromFields ```ts fromFields: {}; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. ###### Param an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. ###### Param an array of any type describing the "auxiliary" data of the new `T` element, optional. ###### stack.provable.fromValue ```ts fromValue: {}; ``` Convert provable type from a normal JS type. ###### stack.provable.toAuxiliary ```ts toAuxiliary: {}; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. ###### Param the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. ###### stack.provable.toCanonical? ```ts optional toCanonical: null | {}; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. ###### stack.provable.toFields ```ts toFields: {}; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. ###### Param the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. ###### stack.provable.toInput ```ts toInput: {}; ``` ###### stack.provable.toValue ```ts toValue: {}; ``` Convert provable type to a normal JS type. ###### stack.provable.sizeInFields ```ts sizeInFields; ``` ###### stack.create ```ts create; ``` Create a Merkle list type Optionally, you can tell `create()` how to do the hash that pushes a new list element, by passing a `nextHash` function. ###### Example ```ts class MyList extends MerkleList.create(Field, (hash, x) => Poseidon.hashWithPrefix('custom', [hash, x]) ) {} ``` ###### useOnchainStack ```ts useOnchainStack: boolean = Bool; ``` ###### witnesses ```ts witnesses: { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; ``` ###### witnesses.check ```ts check: {}; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. ###### Param the element of type `T` to put assertions on. ###### witnesses.empty ```ts empty: {}; ``` ###### witnesses.fromFields ```ts fromFields: {}; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. ###### Param an array of [Field](../../../classes/Field.mdx) elements describing the provable data of the new `T` element. ###### Param an array of any type describing the "auxiliary" data of the new `T` element, optional. ###### witnesses.fromValue ```ts fromValue: {}; ``` Convert provable type from a normal JS type. ###### witnesses.toAuxiliary ```ts toAuxiliary: {}; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. ###### Param the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. ###### witnesses.toCanonical? ```ts optional toCanonical: null | {}; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. ###### witnesses.toFields ```ts toFields: {}; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. ###### Param the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. ###### witnesses.toInput ```ts toInput: {}; ``` ###### witnesses.toValue ```ts toValue: {}; ``` Convert provable type to a normal JS type. ###### witnesses.sizeInFields ```ts sizeInFields; ``` #### Inherited from `BatchReducer_.BatchReducer.Batch` #### Source [lib/mina/actions/batch-reducer.ts:67](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L67) *** ### BatchProof ```ts BatchProof: typeof Proof; ``` #### Inherited from `BatchReducer_.BatchReducer.BatchProof` #### Source [lib/mina/actions/batch-reducer.ts:70](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L70) *** ### \_contract? ```ts optional _contract: BatchReducerContract; ``` #### Inherited from `BatchReducer_.BatchReducer._contract` #### Source [lib/mina/actions/batch-reducer.ts:164](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L164) *** ### \_contractClass? ```ts optional _contractClass: BatchReducerContractClass; ``` #### Inherited from `BatchReducer_.BatchReducer._contractClass` #### Source [lib/mina/actions/batch-reducer.ts:165](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L165) *** ### actionType ```ts actionType: Provable & { "empty": () => Action; } & { "toInput": (x: Action) => HashInput; } & Omit, "fromFields"> & { "fromFields": (fields: Field[]) => Action; }; ``` #### Type declaration ##### empty() ```ts empty: () => Action; ``` ###### Returns `Action` #### Type declaration ##### toInput() ```ts toInput: (x: Action) => HashInput; ``` ###### Parameters • **x**: `Action` ###### Returns `HashInput` #### Type declaration ##### fromFields() ```ts fromFields: (fields: Field[]) => Action; ``` ###### Parameters • **fields**: [`Field`](../../../classes/Field.mdx)[] ###### Returns `Action` #### Inherited from `BatchReducer_.BatchReducer.actionType` #### Source [lib/mina/actions/batch-reducer.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L66) *** ### batchSize ```ts batchSize: BatchSize; ``` #### Inherited from `BatchReducer_.BatchReducer.batchSize` #### Source [lib/mina/actions/batch-reducer.ts:65](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L65) *** ### maxActionsPerUpdate ```ts maxActionsPerUpdate: number; ``` #### Inherited from `BatchReducer_.BatchReducer.maxActionsPerUpdate` #### Source [lib/mina/actions/batch-reducer.ts:73](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L73) *** ### maxUpdatesFinalProof ```ts maxUpdatesFinalProof: number; ``` #### Inherited from `BatchReducer_.BatchReducer.maxUpdatesFinalProof` #### Source [lib/mina/actions/batch-reducer.ts:72](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L72) *** ### program ```ts program: ActionStackProgram; ``` #### Inherited from `BatchReducer_.BatchReducer.program` #### Source [lib/mina/actions/batch-reducer.ts:69](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L69) ## Accessors ### initialActionStack ```ts get static initialActionStack(): Field ``` #### Returns [`Field`](../../../classes/Field.mdx) #### Source [lib/mina/actions/batch-reducer.ts:160](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L160) *** ### initialActionState ```ts get static initialActionState(): Field ``` #### Returns [`Field`](../../../classes/Field.mdx) #### Source [lib/mina/actions/batch-reducer.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L157) ## Methods ### compile() ```ts compile(): Promise<{ "verificationKey": { "data": string; "hash": Field; }; }> ``` Compile the recursive action stack prover. #### Returns `Promise`\<\{ `"verificationKey"`: \{ `"data"`: `string`; `"hash"`: [`Field`](../../../classes/Field.mdx); \}; \}\> > ##### verificationKey > > ```ts > verificationKey: { > "data": string; > "hash": Field; > }; > ``` > > ##### verificationKey.data > > ```ts > data: string; > ``` > > ##### verificationKey.hash > > ```ts > hash: Field; > ``` > #### Inherited from `BatchReducer_.BatchReducer.compile` #### Source [lib/mina/actions/batch-reducer.ts:421](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L421) *** ### contract() ```ts contract(): BatchReducerContract ``` #### Returns `BatchReducerContract` #### Inherited from `BatchReducer_.BatchReducer.contract` #### Source [lib/mina/actions/batch-reducer.ts:174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L174) *** ### contractClass() ```ts contractClass(): BatchReducerContractClass ``` #### Returns `BatchReducerContractClass` #### Inherited from `BatchReducer_.BatchReducer.contractClass` #### Source [lib/mina/actions/batch-reducer.ts:167](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L167) *** ### dispatch() ```ts dispatch(action: From): void ``` Submit an action. #### Parameters • **action**: `From`\<`ActionType`\> #### Returns `void` #### Inherited from `BatchReducer_.BatchReducer.dispatch` #### Source [lib/mina/actions/batch-reducer.ts:202](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L202) *** ### dispatchIf() ```ts dispatchIf(condition: Bool, action: From): void ``` Conditionally submit an action. #### Parameters • **condition**: [`Bool`](../../../classes/Bool.mdx) • **action**: `From`\<`ActionType`\> #### Returns `void` #### Inherited from `BatchReducer_.BatchReducer.dispatchIf` #### Source [lib/mina/actions/batch-reducer.ts:215](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L215) *** ### prepareBatches() ```ts prepareBatches(): Promise<{ "batch": ActionBatch; "proof": ActionStackProof; }[]> ``` Create a proof which returns the next actions batch(es) to process and helps guarantee their correctness. #### Returns `Promise`\<\{ `"batch"`: `ActionBatch`\<`Action`\>; `"proof"`: `ActionStackProof`; \}[]\> #### Inherited from `BatchReducer_.BatchReducer.prepareBatches` #### Source [lib/mina/actions/batch-reducer.ts:428](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L428) *** ### processBatch() ```ts processBatch(__namedParameters: { "batch": ActionBatch; "proof": Proof; }, callback: (action: Action, isDummy: Bool, i: number) => void): void ``` Process a batch of actions which was created by `prepareBatches()`. **Important**: The callback exposes the action's value along with an `isDummy` flag. This is necessary because we process a dynamically-sized list in a fixed number of steps. Dummies will be passed to your callback once the actual actions are exhausted. Make sure to write your code to account for dummies. For example, when sending MINA from your contract for every action, you probably want to zero out the balance decrease in the `isDummy` case: ```ts processBatch({ batch, proof }, (action, isDummy) => { // ... other logic ... let amountToSend = Provable.if(isDummy, UInt64.zero, action.amount); this.balance.subInPlace(amountToSend); }); ``` **Warning**: Don't call `processBatch()` on two _different_ batches within the same method. The second call would override the preconditions set by the first call, which would leave the method insecure. To process more actions per method call, increase the `batchSize`. #### Parameters • **\_\_namedParameters** • **\_\_namedParameters.batch**: `ActionBatch`\<`Action`\> • **\_\_namedParameters.proof**: [`Proof`](../../../classes/Proof.mdx)\<[`Field`](../../../classes/Field.mdx), `ActionStackState`\> • **callback** #### Returns `void` #### Inherited from `BatchReducer_.BatchReducer.processBatch` #### Source [lib/mina/actions/batch-reducer.ts:253](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L253) *** ### setContractClass() ```ts setContractClass(contractClass: BatchReducerContractClass): void ``` Set the smart contract class this reducer is connected with. Note: You can use either this method or `setContractInstance()` before calling `compile()`. However, `setContractInstance()` is required for `proveNextBatch()`. #### Parameters • **contractClass**: `BatchReducerContractClass` #### Returns `void` #### Inherited from `BatchReducer_.BatchReducer.setContractClass` #### Source [lib/mina/actions/batch-reducer.ts:195](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L195) *** ### setContractInstance() ```ts setContractInstance(contract: BatchReducerContract): void ``` Set the smart contract instance this reducer is connected with. Note: This is a required step before using `dispatch()`, `proveNextBatch()` or `processNextBatch()`. #### Parameters • **contract**: `BatchReducerContract` #### Returns `void` #### Inherited from `BatchReducer_.BatchReducer.setContractInstance` #### Source [lib/mina/actions/batch-reducer.ts:184](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/batch-reducer.ts#L184) --- url: /zkapps/o1js-reference/namespaces/Experimental/classes/OffchainStateCommitments --- Commitments that keep track of the current state of an offchain Merkle tree constructed from actions. Intended to be stored on-chain. Fields: - `root`: The root of the current Merkle tree - `actionState`: The hash pointing to the list of actions that have been applied to form the current Merkle tree ## Extends - `OffchainStateCommitments` ## Constructors ### new OffchainStateCommitments() ```ts new OffchainStateCommitments(value: { "actionState": Field; "length": Field; "root": Field; }): OffchainStateCommitments ``` #### Parameters • **value** • **value.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns [`OffchainStateCommitments`](OffchainStateCommitments.mdx) #### Inherited from `OffchainState_.OffchainStateCommitments.constructor` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) ## Properties ### actionState ```ts actionState: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.actionState` #### Source [lib/mina/actions/offchain-state-rollup.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/offchain-state-rollup.ts#L49) *** ### length ```ts length: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.length` #### Source [lib/mina/actions/offchain-state-rollup.ts:46](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/offchain-state-rollup.ts#L46) *** ### root ```ts root: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.root` #### Source [lib/mina/actions/offchain-state-rollup.ts:45](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/offchain-state-rollup.ts#L45) *** ### \_isStruct ```ts static _isStruct: true; ``` #### Inherited from `OffchainState_.OffchainStateCommitments._isStruct` #### Source [lib/provable/types/struct.ts:148](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L148) *** ### check() ```ts static check: (value: { "actionState": Field; "length": Field; "root": Field; }) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../../../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value** the element of type `T` to put assertions on. • **value.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns `void` #### Inherited from `OffchainState_.OffchainStateCommitments.check` #### Source [lib/provable/types/provable-intf.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L76) *** ### empty() ```ts static empty: () => { "actionState": Field; "length": Field; "root": Field; }; ``` #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: Field = Field; ``` ##### length ```ts length: Field = Field; ``` ##### root ```ts root: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.empty` #### Source [lib/provable/types/struct.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L158) *** ### fromFields() ```ts static fromFields: (fields: Field[]) => { "actionState": Field; "length": Field; "root": Field; }; ``` #### Parameters • **fields**: [`Field`](../../../classes/Field.mdx)[] #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: Field = Field; ``` ##### length ```ts length: Field = Field; ``` ##### root ```ts root: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.fromFields` #### Source [lib/provable/types/provable-intf.ts:115](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L115) *** ### fromJSON() ```ts static fromJSON: (x: { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; }; ``` #### Parameters • **x** • **x.actionState**: `string`= `Field` • **x.length**: `string`= `Field` • **x.root**: `string`= `Field` #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: Field = Field; ``` ##### length ```ts length: Field = Field; ``` ##### root ```ts root: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.fromJSON` #### Source [lib/provable/types/struct.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L157) *** ### fromValue ```ts static fromValue: (x: { "actionState": Field; "length": Field; "root": Field; } | { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; } & (value: { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; }; ``` Convert provable type from a normal JS type. #### Inherited from `OffchainState_.OffchainStateCommitments.fromValue` #### Source [lib/provable/types/provable-intf.ts:86](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L86) *** ### toAuxiliary() ```ts static toAuxiliary: (value?: { "actionState": Field; "length": Field; "root": Field; }) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?** the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. • **value.actionState?**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.length?**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.root?**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns `any`[] #### Inherited from `OffchainState_.OffchainStateCommitments.toAuxiliary` #### Source [lib/provable/types/provable-intf.ts:47](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L47) *** ### toCanonical()? ```ts static optional toCanonical: (x: { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; }; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x** • **x.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: Field = Field; ``` ##### length ```ts length: Field = Field; ``` ##### root ```ts root: Field = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.toCanonical` #### Source [lib/provable/types/provable-intf.ts:104](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L104) *** ### toFields() ```ts static toFields: (value: { "actionState": Field; "length": Field; "root": Field; }) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../../../classes/Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value** the element of type `T` to generate the [Field](../../../classes/Field.mdx) array from. • **value.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **value.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns [`Field`](../../../classes/Field.mdx)[] #### Inherited from `OffchainState_.OffchainStateCommitments.toFields` #### Source [lib/provable/types/provable-intf.ts:36](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L36) *** ### toInput() ```ts static toInput: (x: { "actionState": Field; "length": Field; "root": Field; }) => { "fields": Field[]; "packed": [Field, number][]; }; ``` #### Parameters • **x** • **x.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns ```ts { "fields": Field[]; "packed": [Field, number][]; } ``` ##### fields? ```ts optional fields: Field[]; ``` ##### packed? ```ts optional packed: [Field, number][]; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.toInput` #### Source [lib/provable/types/struct.ts:152](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L152) *** ### toJSON() ```ts static toJSON: (x: { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; }; ``` #### Parameters • **x** • **x.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: string = Field; ``` ##### length ```ts length: string = Field; ``` ##### root ```ts root: string = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.toJSON` #### Source [lib/provable/types/struct.ts:156](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L156) *** ### toValue() ```ts static toValue: (x: { "actionState": Field; "length": Field; "root": Field; }) => { "actionState": Field; "length": Field; "root": Field; }; ``` Convert provable type to a normal JS type. #### Parameters • **x** • **x.actionState**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.length**: [`Field`](../../../classes/Field.mdx)= `Field` • **x.root**: [`Field`](../../../classes/Field.mdx)= `Field` #### Returns ```ts { "actionState": Field; "length": Field; "root": Field; } ``` ##### actionState ```ts actionState: bigint = Field; ``` ##### length ```ts length: bigint = Field; ``` ##### root ```ts root: bigint = Field; ``` #### Inherited from `OffchainState_.OffchainStateCommitments.toValue` #### Source [lib/provable/types/provable-intf.ts:81](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L81) ## Methods ### emptyFromHeight() ```ts static emptyFromHeight(height: number): OffchainStateCommitments ``` #### Parameters • **height**: `number` #### Returns `OffchainStateCommitments` #### Inherited from `OffchainState_.OffchainStateCommitments.emptyFromHeight` #### Source [lib/mina/actions/offchain-state-rollup.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/offchain-state-rollup.ts#L51) *** ### sizeInFields() ```ts static sizeInFields(): number ``` Return the size of the `T` type in terms of [Field](../../../classes/Field.mdx) type, as [Field](../../../classes/Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](../../../classes/Field.mdx) type. #### Inherited from `OffchainState_.OffchainStateCommitments.sizeInFields` #### Source [lib/provable/types/provable-intf.ts:66](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L66) --- url: /zkapps/o1js-reference/namespaces/Experimental/functions/ActionBatch --- ```ts function ActionBatch(actionType: A): (value: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; } & { "_isStruct": true; } & Provable<{ "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }, { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": any; "useOnchainStack": Bool; "witnesses": ActionWitnesses; }> & { "empty": () => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "fromJSON": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "fromValue": (value: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": any; "useOnchainStack": Bool; "witnesses": ActionWitnesses | Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }; "toInput": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "fields": Field[]; "packed": [Field, number][]; }; "toJSON": (x: { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": MerkleList>>>; "useOnchainStack": Bool; "witnesses": Unconstrained; }) => { "isRecursive": Bool; "onchainActionState": Field; "onchainStack": Field; "processedActionState": Field; "stack": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "empty": {}; "emptyHash": string; "from": {}; "fromReverse": {}; "prototype": { "Constructor": { "_emptyHash": null | string; "_innerProvable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "_nextHash": null | {}; "_provable": null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "emptyHash": string; "prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }; "create": ; }; "data": { "get": ; "set": ; "setTo": ; "updateAsProver": ; }; "hash": string; "innerProvable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "clone": ; "forEach": ; "isEmpty": ; "lengthUnconstrained": ; "nextHash": ; "pop": ; "popExn": ; "popIf": ; "popIfUnsafe": ; "push": ; "pushIf": ; "startIterating": ; "startIteratingFromLast": ; "toArrayUnconstrained": ; }; "provable": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; "create": ; }; "useOnchainStack": Bool; "witnesses": { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }; }; } ``` Provable type that represents a batch of actions. ## Type parameters • **A** *extends* `Actionable`\<`any`\> ## Parameters • **actionType**: `A` ## Returns (`value`: \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}) => \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \} & \{ `"_isStruct"`: `true`; \} & `Provable`\<\{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}, \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: `any`; `"useOnchainStack"`: `Bool`; `"witnesses"`: `ActionWitnesses`; \}\> & \{ `"empty"`: () => \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}; `"fromJSON"`: (`x`: \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: \{ `"_emptyHash"`: `null` \| `string`; `"_innerProvable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"_nextHash"`: `null` \| \{\}; `"_provable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"empty"`: \{\}; `"emptyHash"`: `string`; `"from"`: \{\}; `"fromReverse"`: \{\}; `"prototype"`: \{ `"Constructor"`: \{ `"_emptyHash"`: `null` \| `string`; `"_innerProvable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"_nextHash"`: `null` \| \{\}; `"_provable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"emptyHash"`: `string`; `"prototype"`: \{ hash: string; data: \{ get: \{\}; set: \{\}; setTo: \{\}; updateAsProver: \{\}; \}; isEmpty: \{\}; push: \{\}; pushIf: \{\}; popExn: \{\}; pop: \{\}; popIf: \{\}; popIfUnsafe: \{\}; clone: \{\}; forEach: \{\}; startIterating: \{\}; startIteratingFromLast: \{\}; ... 4 more ...; readonly innerProvable: \{ ...; \}; \}; `"create"`: ; \}; `"data"`: \{ `"get"`: ; `"set"`: ; `"setTo"`: ; `"updateAsProver"`: ; \}; `"hash"`: `string`; `"innerProvable"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"clone"`: ; `"forEach"`: ; `"isEmpty"`: ; `"lengthUnconstrained"`: ; `"nextHash"`: ; `"pop"`: ; `"popExn"`: ; `"popIf"`: ; `"popIfUnsafe"`: ; `"push"`: ; `"pushIf"`: ; `"startIterating"`: ; `"startIteratingFromLast"`: ; `"toArrayUnconstrained"`: ; \}; `"provable"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"create"`: ; \}; `"useOnchainStack"`: `Bool`; `"witnesses"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; \}) => \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}; `"fromValue"`: (`value`: \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: `any`; `"useOnchainStack"`: `Bool`; `"witnesses"`: `ActionWitnesses` \| [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}) => \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}; `"toInput"`: (`x`: \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}) => \{ `"fields"`: [`Field`](../../../classes/Field.mdx)[]; `"packed"`: [[`Field`](../../../classes/Field.mdx), `number`][]; \}; `"toJSON"`: (`x`: \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: [`MerkleList`](../../../classes/MerkleList.mdx)\<[`MerkleList`](../../../classes/MerkleList.mdx)\<[`Hashed`](../../../classes/Hashed.mdx)\<`InferProvable`\<`A`, [`Field`](../../../classes/Field.mdx)\>\>\>\>; `"useOnchainStack"`: `Bool`; `"witnesses"`: [`Unconstrained`](../../../classes/Unconstrained.mdx)\<`ActionWitnesses`\>; \}) => \{ `"isRecursive"`: `Bool`; `"onchainActionState"`: `Field`; `"onchainStack"`: `Field`; `"processedActionState"`: `Field`; `"stack"`: \{ `"_emptyHash"`: `null` \| `string`; `"_innerProvable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"_nextHash"`: `null` \| \{\}; `"_provable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"empty"`: \{\}; `"emptyHash"`: `string`; `"from"`: \{\}; `"fromReverse"`: \{\}; `"prototype"`: \{ `"Constructor"`: \{ `"_emptyHash"`: `null` \| `string`; `"_innerProvable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"_nextHash"`: `null` \| \{\}; `"_provable"`: `null` \| \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"emptyHash"`: `string`; `"prototype"`: \{ hash: string; data: \{ get: \{\}; set: \{\}; setTo: \{\}; updateAsProver: \{\}; \}; isEmpty: \{\}; push: \{\}; pushIf: \{\}; popExn: \{\}; pop: \{\}; popIf: \{\}; popIfUnsafe: \{\}; clone: \{\}; forEach: \{\}; startIterating: \{\}; startIteratingFromLast: \{\}; ... 4 more ...; readonly innerProvable: \{ ...; \}; \}; `"create"`: ; \}; `"data"`: \{ `"get"`: ; `"set"`: ; `"setTo"`: ; `"updateAsProver"`: ; \}; `"hash"`: `string`; `"innerProvable"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"clone"`: ; `"forEach"`: ; `"isEmpty"`: ; `"lengthUnconstrained"`: ; `"nextHash"`: ; `"pop"`: ; `"popExn"`: ; `"popIf"`: ; `"popIfUnsafe"`: ; `"push"`: ; `"pushIf"`: ; `"startIterating"`: ; `"startIteratingFromLast"`: ; `"toArrayUnconstrained"`: ; \}; `"provable"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; `"create"`: ; \}; `"useOnchainStack"`: `Bool`; `"witnesses"`: \{ `"check"`: \{\}; `"empty"`: \{\}; `"fromFields"`: \{\}; `"fromValue"`: \{\}; `"toAuxiliary"`: \{\}; `"toCanonical"`: `null` \| \{\}; `"toFields"`: \{\}; `"toInput"`: \{\}; `"toValue"`: \{\}; `"sizeInFields"`: ; \}; \}; \} ## Source [index.ts:213](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L213) --- url: /zkapps/o1js-reference/namespaces/Experimental/functions/IndexedMerkleMap --- ```ts function IndexedMerkleMap(height: number): typeof IndexedMerkleMapBase ``` Class factory for an Indexed Merkle Map with a given height. ```ts class MerkleMap extends IndexedMerkleMap(33) {} let map = new MerkleMap(); map.insert(2n, 14n); map.insert(1n, 13n); let x = map.get(2n); // 14 ``` Indexed Merkle maps can be used directly in provable code: ```ts ZkProgram({ methods: { test: { privateInputs: [MerkleMap, Field], method(map: MerkleMap, key: Field) { // get the value associated with `key` let value = map.getOption(key).orElse(0n); // increment the value by 1 map.set(key, value.add(1)); } } } }) ``` Initially, every `IndexedMerkleMap` is populated by a single key-value pair: `(0, 0)`. The value for key `0` can be updated like any other. When keys and values are hash outputs, `(0, 0)` can serve as a convenient way to represent a dummy update to the tree, since 0 is not effciently computable as a hash image, and this update doesn't affect the Merkle root. ## Parameters • **height**: `number` ## Returns *typeof* `IndexedMerkleMapBase` ## Source [index.ts:166](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L166) --- url: /zkapps/o1js-reference/namespaces/Experimental/functions/OffchainState --- ```ts function OffchainState(config: Config, options?: { "logTotalCapacity": number; "maxActionsPerProof": number; "maxActionsPerUpdate": number; }): OffchainState ``` Offchain state for a `SmartContract`. ```ts // declare your offchain state const offchainState = OffchainState({ accounts: OffchainState.Map(PublicKey, UInt64), totalSupply: OffchainState.Field(UInt64), }); // use it in a contract, by adding an onchain state field of type `OffchainStateCommitments` class MyContract extends SmartContract { \@state(OffchainStateCommitments) offchainState = State( OffchainStateCommitments.empty() ); // ... } // set the contract instance let contract = new MyContract(address); offchainState.setContractInstance(contract); ``` See the individual methods on `offchainState` for more information on usage. ## Type parameters • **Config** *extends* \{\} ## Parameters • **config**: `Config` • **options?** • **options.logTotalCapacity?**: `number` The base-2 logarithm of the total capacity of the offchain state. Example: if you want to have 1 million individual state fields and map entries available, set this to 20, because 2^20 ~= 1M. The default is 30, which allows for ~1 billion entries. Passing in lower numbers will reduce the number of constraints required to prove offchain state updates, which we will make proof creation slightly faster. Instead, you could also use a smaller total capacity to increase the `maxActionsPerProof`, so that fewer proofs are required, which will reduce the proof time even more, but only in the case of many actions. • **options.maxActionsPerProof?**: `number` • **options.maxActionsPerUpdate?**: `number` The maximum number of offchain state actions that can be included in a single account update. In other words, you must not call `.update()` or `.overwrite()` more than this number of times in any of your smart contract methods. The default is 4. Note: When increasing this, consider decreasing `maxActionsPerProof` or `logTotalCapacity` in order to not exceed the circuit size limit. ## Returns `OffchainState`\<`Config`\> ## Source [index.ts:170](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L170) --- url: /zkapps/o1js-reference/namespaces/Experimental/functions/memoizeWitness --- ```ts function memoizeWitness(type: FlexibleProvable, compute: () => T): T ``` Like Provable.witness, but memoizes the witness during transaction construction for reuse by the prover. This is needed to witness non-deterministic values. ## Type parameters • **T** ## Parameters • **type**: [`FlexibleProvable`](../../../type-aliases/FlexibleProvable.mdx)\<`T`\> • **compute** ## Returns `T` ## Source [index.ts:163](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L163) --- url: /zkapps/o1js-reference/namespaces/Experimental/type-aliases/ActionBatch --- ```ts type ActionBatch: BatchReducer_.ActionBatch; ``` ## Type parameters • **Action** ## Source [index.ts:213](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L213) --- url: /zkapps/o1js-reference/namespaces/Experimental/type-aliases/IndexedMerkleMap --- ```ts type IndexedMerkleMap: IndexedMerkleMapBase; ``` ## Source [index.ts:166](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/index.ts#L166) --- url: /zkapps/o1js-reference/namespaces/Lightnet/README --- ## Index | Member | Description | | :------ | :------ | | [acquireKeyPair](functions/acquireKeyPair.mdx) | Gets random key pair (public and private keys) from account manager | | [listAcquiredKeyPairs](functions/listAcquiredKeyPairs.mdx) | Gets previously acquired key pairs list. | | [releaseKeyPair](functions/releaseKeyPair.mdx) | Releases previously acquired key pair by public key. | --- url: /zkapps/o1js-reference/namespaces/Lightnet/functions/acquireKeyPair --- ```ts function acquireKeyPair(options: { "isRegularAccount": boolean; "lightnetAccountManagerEndpoint": string; }): Promise<{ "privateKey": PrivateKey; "publicKey": PublicKey; }> ``` Gets random key pair (public and private keys) from account manager that operates with accounts configured in target network Genesis Ledger. If an error is returned by the specified endpoint, an error is thrown. Otherwise, the data is returned. ## Parameters • **options**= `{}` • **options.isRegularAccount?**: `boolean` Whether to acquire key pair of regular or zkApp account (one with already configured verification key) • **options.lightnetAccountManagerEndpoint?**: `string` Account manager endpoint to fetch from ## Returns `Promise`\<\{ `"privateKey"`: [`PrivateKey`](../../../classes/PrivateKey.mdx); `"publicKey"`: [`PublicKey`](../../../classes/PublicKey.mdx); \}\> Key pair > ### privateKey > > ```ts > privateKey: PrivateKey; > ``` > > ### publicKey > > ```ts > publicKey: PublicKey; > ``` > ## Source [lib/mina/fetch.ts:843](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L843) --- url: /zkapps/o1js-reference/namespaces/Lightnet/functions/listAcquiredKeyPairs --- ```ts function listAcquiredKeyPairs(options: { "lightnetAccountManagerEndpoint": string; }): Promise<{ "privateKey": PrivateKey; "publicKey": PublicKey; }[] | null> ``` Gets previously acquired key pairs list. ## Parameters • **options** • **options.lightnetAccountManagerEndpoint?**: `string` Account manager endpoint to fetch from ## Returns `Promise`\<\{ `"privateKey"`: [`PrivateKey`](../../../classes/PrivateKey.mdx); `"publicKey"`: [`PublicKey`](../../../classes/PublicKey.mdx); \}[] \| `null`\> Key pairs list or null if the request failed ## Source [lib/mina/fetch.ts:923](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L923) --- url: /zkapps/o1js-reference/namespaces/Lightnet/functions/releaseKeyPair --- ```ts function releaseKeyPair(options: { "lightnetAccountManagerEndpoint": string; "publicKey": string; }): Promise ``` Releases previously acquired key pair by public key. ## Parameters • **options** • **options.lightnetAccountManagerEndpoint?**: `string` Account manager endpoint to fetch from • **options.publicKey**: `string` Public key of previously acquired key pair to release ## Returns `Promise`\<`string` \| `null`\> Response message from the account manager as string or null if the request failed ## Source [lib/mina/fetch.ts:886](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/fetch.ts#L886) --- url: /zkapps/o1js-reference/namespaces/Mina/README --- ## Index | Member | Description | | :------ | :------ | | [TestPublicKey](namespaces/TestPublicKey/README.mdx) | - | | [Transaction](namespaces/Transaction/README.mdx) | - | | [ActionStates](type-aliases/ActionStates.mdx) | - | | [FeePayerSpec](type-aliases/FeePayerSpec.mdx) | Allows you to specify information about the fee payer account and the transaction. | | [IncludedTransaction](type-aliases/IncludedTransaction.mdx) | Represents a transaction that has been successfully included in a block. | | [NetworkConstants](type-aliases/NetworkConstants.mdx) | - | | [PendingTransaction](type-aliases/PendingTransaction.mdx) | Represents a transaction that has been submitted to the blockchain but has not yet reached a final state. | | [PendingTransactionPromise](type-aliases/PendingTransactionPromise.mdx) | A `Promise` with an additional `wait` method, which calls | | [PendingTransactionStatus](type-aliases/PendingTransactionStatus.mdx) | - | | [RejectedTransaction](type-aliases/RejectedTransaction.mdx) | Represents a transaction that has been rejected and not included in a blockchain block. | | [TestPublicKey](type-aliases/TestPublicKey.mdx) | - | | [Transaction](type-aliases/Transaction.mdx) | Defines the structure and operations associated with a transaction. | | [activeInstance](variables/activeInstance.mdx) | - | | [LocalBlockchain](functions/LocalBlockchain.mdx) | A mock Mina blockchain running locally and useful for testing. | | [Network](functions/Network.mdx) | Represents the Mina blockchain running on a real network | | [TestPublicKey](functions/TestPublicKey.mdx) | - | | [currentSlot](functions/currentSlot.mdx) | - | | [currentTransaction](functions/currentTransaction.mdx) | - | | [faucet](functions/faucet.mdx) | Requests the [testnet faucet](https://faucet.minaprotocol.com/api/v1/faucet) to fund a public key. | | [fetchActions](functions/fetchActions.mdx) | - | | [fetchEvents](functions/fetchEvents.mdx) | - | | [filterGroups](functions/filterGroups.mdx) | - | | [getAccount](functions/getAccount.mdx) | - | | [getActions](functions/getActions.mdx) | - | | [getBalance](functions/getBalance.mdx) | - | | [getNetworkConstants](functions/getNetworkConstants.mdx) | - | | [getNetworkId](functions/getNetworkId.mdx) | - | | [getNetworkState](functions/getNetworkState.mdx) | - | | [getProofsEnabled](functions/getProofsEnabled.mdx) | - | | [hasAccount](functions/hasAccount.mdx) | Checks if an account exists within the ledger. | | [sender](functions/sender.mdx) | Returns the public key of the current transaction's sender account. | | [setActiveInstance](functions/setActiveInstance.mdx) | Set the currently used Mina instance. | | [transaction](functions/transaction.mdx) | Construct a smart contract transaction. Within the callback passed to this function, | | [waitForFunding](functions/waitForFunding.mdx) | - | --- url: /zkapps/o1js-reference/namespaces/Mina/functions/LocalBlockchain --- ```ts function LocalBlockchain(__namedParameters: { "enforceTransactionLimits": true; "proofsEnabled": true; }): Promise<{ "addAccount": (publicKey: PublicKey, balance: string) => void; "getNetworkId": () => NetworkId; "proofsEnabled": boolean; "testAccounts": [TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey]; "applyJsonTransaction": void; "currentSlot": UInt32; "fetchActions": Promise<{ "actions": string[][]; "hash": string; }[]>; "fetchEvents": Promise; "getAccount": Account; "getActions": { "actions": string[][]; "hash": string; }[]; "getNetworkConstants": { "accountCreationFee": UInt64; "genesisTimestamp": UInt64; "slotTime": UInt64; }; "getNetworkState": PreconditionBaseTypes<{}>; "hasAccount": boolean; "incrementGlobalSlot": void; "resetProofsEnabled": void; "sendTransaction": PendingTransactionPromise; "setBlockchainLength": void; "setGlobalSlot": void; "setProofsEnabled": void; "setTotalCurrency": void; "transaction": TransactionPromise; }> ``` A mock Mina blockchain running locally and useful for testing. ## Parameters • **\_\_namedParameters**= `{}` • **\_\_namedParameters.enforceTransactionLimits**: `undefined` \| `boolean`= `true` • **\_\_namedParameters.proofsEnabled**: `undefined` \| `boolean`= `true` ## Returns `Promise`\<\{ `"addAccount"`: (`publicKey`: [`PublicKey`](../../../classes/PublicKey.mdx), `balance`: `string`) => `void`; `"getNetworkId"`: () => `NetworkId`; `"proofsEnabled"`: `boolean`; `"testAccounts"`: [[`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx), [`TestPublicKey`](../type-aliases/TestPublicKey.mdx)]; `"applyJsonTransaction"`: `void`; `"currentSlot"`: [`UInt32`](../../../classes/UInt32.mdx); `"fetchActions"`: `Promise`\<\{ `"actions"`: `string`[][]; `"hash"`: `string`; \}[]\>; `"fetchEvents"`: `Promise`\<`any`\>; `"getAccount"`: `Account`; `"getActions"`: \{ `"actions"`: `string`[][]; `"hash"`: `string`; \}[]; `"getNetworkConstants"`: \{ `"accountCreationFee"`: [`UInt64`](../../../classes/UInt64.mdx); `"genesisTimestamp"`: [`UInt64`](../../../classes/UInt64.mdx); `"slotTime"`: [`UInt64`](../../../classes/UInt64.mdx); \}; `"getNetworkState"`: `PreconditionBaseTypes`\<\{\}\>; `"hasAccount"`: `boolean`; `"incrementGlobalSlot"`: `void`; `"resetProofsEnabled"`: `void`; `"sendTransaction"`: [`PendingTransactionPromise`](../type-aliases/PendingTransactionPromise.mdx); `"setBlockchainLength"`: `void`; `"setGlobalSlot"`: `void`; `"setProofsEnabled"`: `void`; `"setTotalCurrency"`: `void`; `"transaction"`: [`TransactionPromise`](../../../type-aliases/TransactionPromise.mdx)\<`false`, `false`\>; \}\> > ### addAccount() > > ```ts > addAccount: (publicKey: PublicKey, balance: string) => void; > ``` > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **balance**: `string` > > #### Returns > > `void` > > ### getNetworkId() > > ```ts > getNetworkId: () => NetworkId; > ``` > > #### Returns > > `NetworkId` > > ### proofsEnabled > > ```ts > proofsEnabled: boolean; > ``` > > ### testAccounts > > ```ts > testAccounts: [TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey, TestPublicKey]; > ``` > > ### applyJsonTransaction() > > #### Parameters > > • **json**: `string` > > #### Returns > > `void` > > ### currentSlot() > > #### Returns > > [`UInt32`](../../../classes/UInt32.mdx) > > ### fetchActions() > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **actionStates?**: [`ActionStates`](../type-aliases/ActionStates.mdx) > > • **tokenId?**: [`Field`](../../../classes/Field.mdx)= `TokenId.default` > > #### Returns > > `Promise`\<\{ > `"actions"`: `string`[][]; > `"hash"`: `string`; > \}[]\> > > ### fetchEvents() > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **tokenId**: [`Field`](../../../classes/Field.mdx)= `TokenId.default` > > #### Returns > > `Promise`\<`any`\> > > ### getAccount() > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **tokenId**: [`Field`](../../../classes/Field.mdx)= `TokenId.default` > > #### Returns > > `Account` > > ### getActions() > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **actionStates?**: [`ActionStates`](../type-aliases/ActionStates.mdx) > > • **tokenId?**: [`Field`](../../../classes/Field.mdx)= `TokenId.default` > > #### Returns > > \{ > `"actions"`: `string`[][]; > `"hash"`: `string`; > \}[] > > ### getNetworkConstants() > > #### Returns > > ```ts > { > "accountCreationFee": UInt64; > "genesisTimestamp": UInt64; > "slotTime": UInt64; > } > ``` > > ##### accountCreationFee > > ```ts > accountCreationFee: UInt64; > ``` > > ##### genesisTimestamp > > ```ts > genesisTimestamp: UInt64; > ``` > > ##### slotTime > > ```ts > slotTime: UInt64; > ``` > > Duration of 1 slot in millisecondw > > ### getNetworkState() > > #### Returns > > `PreconditionBaseTypes`\<\{\}\> > > ### hasAccount() > > #### Parameters > > • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) > > • **tokenId**: [`Field`](../../../classes/Field.mdx)= `TokenId.default` > > #### Returns > > `boolean` > > ### incrementGlobalSlot() > > #### Parameters > > • **increment**: `number` \| [`UInt32`](../../../classes/UInt32.mdx) > > #### Returns > > `void` > > ### resetProofsEnabled() > > #### Returns > > `void` > > ### sendTransaction() > > #### Parameters > > • **txn**: [`Transaction`](../type-aliases/Transaction.mdx)\<`boolean`, `boolean`\> > > #### Returns > > [`PendingTransactionPromise`](../type-aliases/PendingTransactionPromise.mdx) > > ### setBlockchainLength() > > #### Parameters > > • **height**: [`UInt32`](../../../classes/UInt32.mdx) > > #### Returns > > `void` > > ### setGlobalSlot() > > #### Parameters > > • **slot**: `number` \| [`UInt32`](../../../classes/UInt32.mdx) > > #### Returns > > `void` > > ### setProofsEnabled() > > #### Parameters > > • **newProofsEnabled**: `boolean` > > #### Returns > > `void` > > ### setTotalCurrency() > > #### Parameters > > • **currency**: [`UInt64`](../../../classes/UInt64.mdx) > > #### Returns > > `void` > > ### transaction() > > #### Parameters > > • **sender**: [`FeePayerSpec`](../type-aliases/FeePayerSpec.mdx) > > • **f** > > #### Returns > > [`TransactionPromise`](../../../type-aliases/TransactionPromise.mdx)\<`false`, `false`\> > ## Source [lib/mina/local-blockchain.ts:72](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/local-blockchain.ts#L72) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/Network --- ## Network(graphqlEndpoint) ```ts function Network(graphqlEndpoint: string): Mina ``` Represents the Mina blockchain running on a real network ### Parameters • **graphqlEndpoint**: `string` ### Returns `Mina` ### Source [lib/mina/mina.ts:101](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina.ts#L101) ## Network(options) ```ts function Network(options: { "archive": string | string[]; "lightnetAccountManager": string; "mina": string | string[]; "networkId": NetworkId; }): Mina ``` ### Parameters • **options** • **options.archive?**: `string` \| `string`[] • **options.lightnetAccountManager?**: `string` • **options.mina**: `string` \| `string`[] • **options.networkId?**: `NetworkId` ### Returns `Mina` ### Source [lib/mina/mina.ts:102](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina.ts#L102) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/TestPublicKey --- ```ts function TestPublicKey(key: PrivateKey): TestPublicKey ``` ## Parameters • **key**: [`PrivateKey`](../../../classes/PrivateKey.mdx) ## Returns [`TestPublicKey`](../type-aliases/TestPublicKey.mdx) ## Source [lib/mina/local-blockchain.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/local-blockchain.ts#L51) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/currentSlot --- ```ts function currentSlot(): UInt32 ``` ## Returns [`UInt32`](../../../classes/UInt32.mdx) The current slot number, according to the active Mina instance. ## Source [lib/mina/mina-instance.ts:137](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L137) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/currentTransaction --- ```ts function currentTransaction(): undefined | CurrentTransaction ``` ## Returns `undefined` \| `CurrentTransaction` ## Source [lib/mina/transaction-context.ts:16](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction-context.ts#L16) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/faucet --- ```ts function faucet(pub: PublicKey, network: string): Promise ``` Requests the [testnet faucet](https://faucet.minaprotocol.com/api/v1/faucet) to fund a public key. ## Parameters • **pub**: [`PublicKey`](../../../classes/PublicKey.mdx) • **network**: `string`= `'berkeley-qanet'` ## Returns `Promise`\<`void`\> ## Source [lib/mina/mina.ts:514](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina.ts#L514) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/fetchActions --- ```ts function fetchActions( publicKey: PublicKey, actionStates?: ActionStates, tokenId?: Field): Promise<{ "actions": string[][]; "hash": string; }[] | { "error": { "statusCode": 404; "statusText": string; }; }> ``` ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **actionStates?**: [`ActionStates`](../type-aliases/ActionStates.mdx) • **tokenId?**: [`Field`](../../../classes/Field.mdx) ## Returns `Promise`\<\{ `"actions"`: `string`[][]; `"hash"`: `string`; \}[] \| \{ `"error"`: \{ `"statusCode"`: `404`; `"statusText"`: `string`; \}; \}\> A list of emitted sequencing actions associated to the given public key. ## Source [lib/mina/mina-instance.ts:197](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L197) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/fetchEvents --- ```ts function fetchEvents( publicKey: PublicKey, tokenId: Field, filterOptions: EventActionFilterOptions): Promise<{ "blockHash": event.blockInfo.stateHash; "blockHeight": UInt32; "chainStatus": event.blockInfo.chainStatus; "events": { "data": string[]; "transactionInfo": { "hash": string; "memo": string; "status": string; }; }[]; "globalSlot": UInt32; "parentBlockHash": event.blockInfo.parentHash; }[]> ``` ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **tokenId**: [`Field`](../../../classes/Field.mdx) • **filterOptions**: `EventActionFilterOptions`= `{}` ## Returns `Promise`\<\{ `"blockHash"`: `event.blockInfo.stateHash`; `"blockHeight"`: [`UInt32`](../../../classes/UInt32.mdx); `"chainStatus"`: `event.blockInfo.chainStatus`; `"events"`: \{ `"data"`: `string`[]; `"transactionInfo"`: \{ `"hash"`: `string`; `"memo"`: `string`; `"status"`: `string`; \}; \}[]; `"globalSlot"`: [`UInt32`](../../../classes/UInt32.mdx); `"parentBlockHash"`: `event.blockInfo.parentHash`; \}[]\> A list of emitted events associated to the given public key. ## Source [lib/mina/mina-instance.ts:186](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L186) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/filterGroups --- ```ts function filterGroups(xs: AuthorizationKind[]): { "proof": proofCount; "signedPair": pairs.pairs; "signedSingle": singleCount; } ``` ## Parameters • **xs**: `AuthorizationKind`[] ## Returns ```ts { "proof": proofCount; "signedPair": pairs.pairs; "signedSingle": singleCount; } ``` ### proof ```ts proof: number = proofCount; ``` ### signedPair ```ts signedPair: number = pairs.pairs; ``` ### signedSingle ```ts signedSingle: number = singleCount; ``` ## Source [lib/mina/transaction-validation.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction-validation.ts#L130) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getAccount --- ```ts function getAccount(publicKey: PublicKey, tokenId?: Field): Account ``` ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **tokenId?**: [`Field`](../../../classes/Field.mdx) ## Returns [`Account`](../../../type-aliases/Account.mdx) The account data associated to the given public key. ## Source [lib/mina/mina-instance.ts:144](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L144) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getActions --- ```ts function getActions( publicKey: PublicKey, actionStates?: ActionStates, tokenId?: Field): { "actions": string[][]; "hash": string; }[] ``` ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **actionStates?**: [`ActionStates`](../type-aliases/ActionStates.mdx) • **tokenId?**: [`Field`](../../../classes/Field.mdx) ## Returns \{ `"actions"`: `string`[][]; `"hash"`: `string`; \}[] A list of emitted sequencing actions associated to the given public key. ## Source [lib/mina/mina-instance.ts:208](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L208) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getBalance --- ```ts function getBalance(publicKey: PublicKey, tokenId?: Field): UInt64 ``` ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **tokenId?**: [`Field`](../../../classes/Field.mdx) ## Returns [`UInt64`](../../../classes/UInt64.mdx) The balance associated to the given public key. ## Source [lib/mina/mina-instance.ts:179](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L179) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getNetworkConstants --- ```ts function getNetworkConstants(): NetworkConstants ``` ## Returns [`NetworkConstants`](../type-aliases/NetworkConstants.mdx) Data associated with the current Mina network constants. ## Source [lib/mina/mina-instance.ts:165](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L165) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getNetworkId --- ```ts function getNetworkId(): NetworkId ``` ## Returns `NetworkId` The current Mina network ID. ## Source [lib/mina/mina-instance.ts:158](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L158) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getNetworkState --- ```ts function getNetworkState(): PreconditionBaseTypes<{}> ``` ## Returns `PreconditionBaseTypes`\<\{\}\> Data associated with the current state of the Mina network. ## Source [lib/mina/mina-instance.ts:172](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L172) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/getProofsEnabled --- ```ts function getProofsEnabled(): boolean ``` ## Returns `boolean` ## Source [lib/mina/mina-instance.ts:216](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L216) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/hasAccount --- ```ts function hasAccount(publicKey: PublicKey, tokenId?: Field): boolean ``` Checks if an account exists within the ledger. ## Parameters • **publicKey**: [`PublicKey`](../../../classes/PublicKey.mdx) • **tokenId?**: [`Field`](../../../classes/Field.mdx) ## Returns `boolean` ## Source [lib/mina/mina-instance.ts:151](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L151) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/sender --- ```ts function sender(): PublicKey ``` Returns 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. ## Returns [`PublicKey`](../../../classes/PublicKey.mdx) ## Source [lib/mina/mina.ts:463](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina.ts#L463) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/setActiveInstance --- ```ts function setActiveInstance(m: Mina): void ``` Set the currently used Mina instance. ## Parameters • **m**: `Mina` ## Returns `void` ## Source [lib/mina/mina-instance.ts:126](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L126) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/transaction --- ## transaction(sender, f) ```ts function transaction(sender: FeePayerSpec, f: () => Promise): TransactionPromise ``` Construct a smart contract transaction. Within the callback passed to this function, you can call into the methods of smart contracts. ``` let tx = await Mina.transaction(sender, async () => { await myZkapp.update(); await someOtherZkapp.someOtherMethod(); }); ``` ### Parameters • **sender**: [`FeePayerSpec`](../type-aliases/FeePayerSpec.mdx) • **f** ### Returns [`TransactionPromise`](../../../type-aliases/TransactionPromise.mdx)\<`false`, `false`\> A transaction that can subsequently be submitted to the chain. ### Source [lib/mina/transaction.ts:564](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L564) ## transaction(f) ```ts function transaction(f: () => Promise): TransactionPromise ``` ### Parameters • **f** ### Returns [`TransactionPromise`](../../../type-aliases/TransactionPromise.mdx)\<`false`, `false`\> ### Source [lib/mina/transaction.ts:568](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L568) --- url: /zkapps/o1js-reference/namespaces/Mina/functions/waitForFunding --- ```ts function waitForFunding(address: string): Promise ``` ## Parameters • **address**: `string` ## Returns `Promise`\<`void`\> ## Source [lib/mina/mina.ts:490](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina.ts#L490) --- url: /zkapps/o1js-reference/namespaces/Mina/namespaces/TestPublicKey/README --- ## Index | Member | Description | | :------ | :------ | | [fromBase58](functions/fromBase58.mdx) | - | | [random](functions/random.mdx) | - | --- url: /zkapps/o1js-reference/namespaces/Mina/namespaces/TestPublicKey/functions/fromBase58 --- ```ts function fromBase58(base58: string): TestPublicKey ``` ## Parameters • **base58**: `string` ## Returns [`TestPublicKey`](../../../type-aliases/TestPublicKey.mdx) ## Source [lib/mina/local-blockchain.ts:64](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/local-blockchain.ts#L64) --- url: /zkapps/o1js-reference/namespaces/Mina/namespaces/TestPublicKey/functions/random --- ```ts function random(count: N): N extends 1 ? TestPublicKey : TupleN ``` ## Type parameters • **N** *extends* `number` = `1` ## Parameters • **count**: `N`= `undefined` ## Returns `N` *extends* `1` ? [`TestPublicKey`](../../../type-aliases/TestPublicKey.mdx) : [`TupleN`](../../../../../type-aliases/TupleN.mdx)\<[`TestPublicKey`](../../../type-aliases/TestPublicKey.mdx), `N`\> ## Source [lib/mina/local-blockchain.ts:55](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/local-blockchain.ts#L55) --- url: /zkapps/o1js-reference/namespaces/Mina/namespaces/Transaction/README --- ## Index | Member | Description | | :------ | :------ | | [fromJSON](functions/fromJSON.mdx) | - | --- url: /zkapps/o1js-reference/namespaces/Mina/namespaces/Transaction/functions/fromJSON --- ```ts function fromJSON(json: ZkappCommand): Transaction ``` ## Parameters • **json**: `ZkappCommand` ## Returns [`Transaction`](../../../type-aliases/Transaction.mdx)\<`false`, `false`\> ## Source [lib/mina/transaction.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L85) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/ActionStates --- ```ts type ActionStates: { "endActionState": Field; "fromActionState": Field; }; ``` ## Type declaration ### endActionState? ```ts optional endActionState: Field; ``` ### fromActionState? ```ts optional fromActionState: Field; ``` ## Source [lib/mina/mina-instance.ts:62](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L62) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/FeePayerSpec --- ```ts type FeePayerSpec: PublicKey | { "fee": number | string | UInt64; "memo": string; "nonce": number; "sender": PublicKey; } | undefined; ``` Allows you to specify information about the fee payer account and the transaction. ## Source [lib/mina/mina-instance.ts:52](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L52) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/IncludedTransaction --- ```ts type IncludedTransaction: Pick & { "status": "included"; }; ``` Represents a transaction that has been successfully included in a block. ## Type declaration ### status ```ts status: "included"; ``` #### Example ```ts try { const includedTx: IncludedTransaction = await pendingTransaction.wait(); // If wait() resolves, it means the transaction was successfully included. console.log(`Transaction ${includedTx.hash} included in a block.`); } catch (error) { // If wait() throws, the transaction was not included in a block. console.error('Transaction failed to be included in a block:', error); } ``` ## Source [lib/mina/transaction.ts:258](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L258) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/NetworkConstants --- ```ts type NetworkConstants: { "accountCreationFee": UInt64; "genesisTimestamp": UInt64; "slotTime": UInt64; }; ``` ## Type declaration ### accountCreationFee ```ts accountCreationFee: UInt64; ``` ### genesisTimestamp ```ts genesisTimestamp: UInt64; ``` ### slotTime ```ts slotTime: UInt64; ``` Duration of 1 slot in millisecondw ## Source [lib/mina/mina-instance.ts:67](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L67) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/PendingTransaction --- ```ts type PendingTransaction: Pick & { "data": SendZkAppResponse; "errors": string[]; "hash": string; "status": PendingTransactionStatus; "safeWait": Promise; "wait": Promise; }; ``` Represents a transaction that has been submitted to the blockchain but has not yet reached a final state. The [PendingTransaction](PendingTransaction.mdx) type extends certain functionalities from the base [Transaction](Transaction.mdx) type, adding methods to monitor the transaction's progress towards being finalized (either included in a block or rejected). ## Type declaration ### data? ```ts optional data: SendZkAppResponse; ``` Optional. Contains response data from a ZkApp transaction submission. ### errors ```ts errors: string[]; ``` An array of error messages related to the transaction processing. #### Example ```ts if (!pendingTransaction.status === 'rejected') { console.error(`Transaction errors: ${pendingTransaction.errors.join(', ')}`); } ``` ### hash ```ts hash: string; ``` Returns the transaction hash as a string identifier. #### Example ```ts const txHash = pendingTransaction.hash; console.log(`Transaction hash: ${txHash}`); ``` ### status ```ts status: PendingTransactionStatus; ``` #### Example ```ts if (pendingTransaction.status === 'pending') { console.log('Transaction accepted for processing by the Mina daemon.'); try { await pendingTransaction.wait(); console.log('Transaction successfully included in a block.'); } catch (error) { console.error('Transaction was rejected or failed to be included in a block:', error); } } else { console.error('Transaction was not accepted for processing by the Mina daemon.'); } ``` ### safeWait() Waits for the transaction to be included in a block. This method polls the Mina daemon to check the transaction's status #### Parameters • **options?** Configuration options for polling behavior. • **options.interval?**: `number` The time interval, in milliseconds, between each polling attempt. • **options.maxAttempts?**: `number` The maximum number of polling attempts. #### Returns `Promise`\<[`RejectedTransaction`](RejectedTransaction.mdx) \| [`IncludedTransaction`](IncludedTransaction.mdx)\> A promise that resolves to the transaction's final state. #### Example ```ts const transaction = await pendingTransaction.wait({ maxAttempts: 5, interval: 1000 }); console.log(transaction.status); // 'included' or 'rejected' ``` ### wait() Waits for the transaction to be included in a block. This method polls the Mina daemon to check the transaction's status, and throws an error if the transaction is rejected. #### Parameters • **options?** Configuration options for polling behavior. • **options.interval?**: `number` The interval, in milliseconds, between status checks. • **options.maxAttempts?**: `number` The maximum number of attempts to check the transaction status. #### Returns `Promise`\<[`IncludedTransaction`](IncludedTransaction.mdx)\> A promise that resolves to the transaction's final state or throws an error. #### Throws If the transaction is rejected or fails to finalize within the given attempts. #### Example ```ts try { const transaction = await pendingTransaction.wait({ maxAttempts: 10, interval: 2000 }); console.log('Transaction included in a block.'); } catch (error) { console.error('Transaction rejected or failed to finalize:', error); } ``` ## Source [lib/mina/transaction.ts:157](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L157) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/PendingTransactionPromise --- ```ts type PendingTransactionPromise: Promise & { "wait": PendingTransaction["wait"]; }; ``` A `Promise` with an additional `wait` method, which calls into the inner `TransactionStatus`'s `wait` method upon its resolution. ## Type declaration ### wait ```ts wait: PendingTransaction["wait"]; ``` Equivalent to calling the resolved `PendingTransaction`'s `wait` method. ## Source [lib/mina/transaction.ts:376](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L376) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/PendingTransactionStatus --- ```ts type PendingTransactionStatus: "pending" | "rejected"; ``` ## Source [lib/mina/transaction.ts:151](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L151) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/RejectedTransaction --- ```ts type RejectedTransaction: Pick & { "errors": string[]; "status": "rejected"; }; ``` Represents a transaction that has been rejected and not included in a blockchain block. ## Type declaration ### errors ```ts errors: string[]; ``` ### status ```ts status: "rejected"; ``` #### Example ```ts try { const txResult = await pendingTransaction.wait(); // This line will not execute if the transaction is rejected, as `.wait()` will throw an error instead. console.log(`Transaction ${txResult.hash} was successfully included in a block.`); } catch (error) { console.error(`Transaction ${error.transaction.hash} was rejected.`); error.errors.forEach((error, i) => { console.error(`Error ${i + 1}: ${error}`); }); } ``` ## Source [lib/mina/transaction.ts:282](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L282) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/TestPublicKey --- ```ts type TestPublicKey: PublicKey & { "key": PrivateKey; }; ``` ## Type declaration ### key ```ts key: PrivateKey; ``` ## Source [lib/mina/local-blockchain.ts:51](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/local-blockchain.ts#L51) --- url: /zkapps/o1js-reference/namespaces/Mina/type-aliases/Transaction --- ```ts type Transaction: TransactionCommon & { "safeSend": Promise; "send": PendingTransactionPromise; } & Proven extends false ? { "prove": Promise>; } : { "proofs": (Proof | undefined)[]; } & Signed extends false ? { "sign": Transaction; } : {}; ``` Defines the structure and operations associated with a transaction. This type encompasses methods for serializing the transaction, signing it, generating proofs, and submitting it to the network. ## Type declaration ### safeSend() Sends the [Transaction](Transaction.mdx) to the network. Unlike the standard Transaction.send, this function does not throw an error if internal errors are detected. Instead, it returns a [PendingTransaction](PendingTransaction.mdx) if the transaction is successfully sent for processing or a [RejectedTransaction](RejectedTransaction.mdx) if it encounters errors during processing or is outright rejected by the Mina daemon. #### Returns `Promise`\<[`PendingTransaction`](PendingTransaction.mdx) \| [`RejectedTransaction`](RejectedTransaction.mdx)\> A promise that resolves to a [PendingTransaction](PendingTransaction.mdx) if the transaction is accepted for processing, or a [RejectedTransaction](RejectedTransaction.mdx) if the transaction fails or is rejected. #### Example ```ts const result = await transaction.safeSend(); if (result.status === 'pending') { console.log('Transaction sent successfully to the Mina daemon.'); } else if (result.status === 'rejected') { console.error('Transaction failed with errors:', result.errors); } ``` ### send() #### Returns [`PendingTransactionPromise`](PendingTransactionPromise.mdx) ## Type parameters • **Proven** *extends* `boolean` • **Signed** *extends* `boolean` ## Source [lib/mina/transaction.ts:84](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L84) --- url: /zkapps/o1js-reference/namespaces/Mina/variables/activeInstance --- ```ts activeInstance: Mina; ``` ## Source [lib/mina/mina-instance.ts:108](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/mina-instance.ts#L108) --- url: /zkapps/o1js-reference/type-aliases/Account --- ```ts type Account: Types.Account; ``` ## Source [lib/mina/account.ts:19](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account.ts#L19) --- url: /zkapps/o1js-reference/type-aliases/Bool --- ```ts type Bool: Bool; ``` ## Source [lib/provable/wrapped.ts:70](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L70) --- url: /zkapps/o1js-reference/type-aliases/BoolVar --- ```ts type BoolVar: FieldVar; ``` ## Source [lib/provable/bool.ts:14](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/bool.ts#L14) --- url: /zkapps/o1js-reference/type-aliases/Bytes --- ```ts type Bytes: InternalBytes; ``` ## Source [lib/provable/wrapped-classes.ts:16](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped-classes.ts#L16) --- url: /zkapps/o1js-reference/type-aliases/Cache --- ```ts type Cache: { "canWrite": boolean; "debug": boolean; "read": undefined | Uint8Array; "write": void; }; ``` Interface for storing and retrieving values, for caching. `read()` and `write()` can just throw errors on failure. The data that will be passed to the cache for writing is exhaustively described by the [CacheHeader](CacheHeader.mdx) type. It represents one of the following: - The SRS. This is a deterministic lists of curve points (one per curve) that needs to be generated just once, to be used for polynomial commitments. - Lagrange basis commitments. Similar to the SRS, this will be created once for every power-of-2 circuit size. - Prover and verifier keys for every compiled circuit. Per smart contract or ZkProgram, several different keys are created: - a step prover key (`step-pk`) and verification key (`step-vk`) _for every method_. - a wrap prover key (`wrap-pk`) and verification key (`wrap-vk`) for the entire contract. ## Type declaration ### canWrite ```ts canWrite: boolean; ``` Indicates whether the cache is writable. ### debug? ```ts optional debug: boolean; ``` If `debug` is toggled, `read()` and `write()` errors are logged to the console. By default, cache errors are silent, because they don't necessarily represent an error condition, but could just be a cache miss, or file system permissions incompatible with writing data. ### read() Read a value from the cache. #### Parameters • **header**: [`CacheHeader`](CacheHeader.mdx) A small header to identify what is read from the cache. #### Returns `undefined` \| `Uint8Array` ### write() Write a value to the cache. #### Parameters • **header**: [`CacheHeader`](CacheHeader.mdx) A small header to identify what is written to the cache. This will be used by `read()` to retrieve the data. • **value**: `Uint8Array` The value to write to the cache, as a byte array. #### Returns `void` ## Source [lib/proof-system/cache.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/cache.ts#L37) --- url: /zkapps/o1js-reference/type-aliases/CacheHeader --- ```ts type CacheHeader: | StepKeyHeader<"step-pk"> | StepKeyHeader<"step-vk"> | WrapKeyHeader<"wrap-pk"> | WrapKeyHeader<"wrap-vk"> | PlainHeader<"srs"> | PlainHeader & CommonHeader; ``` A header that is passed to the caching layer, to support rich caching strategies. Both `uniqueId` and `programId` can safely be used as a file path. ## Source [lib/proof-system/cache.ts:106](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/cache.ts#L106) --- url: /zkapps/o1js-reference/type-aliases/ConstantField --- ```ts type ConstantField: Field & { "value": ConstantFieldVar; }; ``` ## Type declaration ### value ```ts value: ConstantFieldVar; ``` ## Source [lib/provable/field.ts:1246](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1246) --- url: /zkapps/o1js-reference/type-aliases/DeployArgs --- ```ts type DeployArgs: { "verificationKey": { "data": string; "hash": string | Field; }; } | undefined; ``` ## Source [lib/mina/zkapp.ts:1248](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/zkapp.ts#L1248) --- url: /zkapps/o1js-reference/type-aliases/Empty --- ```ts type Empty: Undefined; ``` ## Source [lib/proof-system/zkprogram.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L85) --- url: /zkapps/o1js-reference/type-aliases/FeatureFlags --- ```ts type FeatureFlags: { "foreignFieldAdd": boolean | undefined; "foreignFieldMul": boolean | undefined; "lookup": boolean | undefined; "rangeCheck0": boolean | undefined; "rangeCheck1": boolean | undefined; "rot": boolean | undefined; "runtimeTables": boolean | undefined; "xor": boolean | undefined; }; ``` ## Type declaration ### foreignFieldAdd ```ts foreignFieldAdd: boolean | undefined; ``` ### foreignFieldMul ```ts foreignFieldMul: boolean | undefined; ``` ### lookup ```ts lookup: boolean | undefined; ``` ### rangeCheck0 ```ts rangeCheck0: boolean | undefined; ``` ### rangeCheck1 ```ts rangeCheck1: boolean | undefined; ``` ### rot ```ts rot: boolean | undefined; ``` ### runtimeTables ```ts runtimeTables: boolean | undefined; ``` ### xor ```ts xor: boolean | undefined; ``` ## Source [lib/proof-system/feature-flags.ts:17](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/feature-flags.ts#L17) --- url: /zkapps/o1js-reference/type-aliases/Field --- ```ts type Field: Field; ``` ## Source [lib/provable/wrapped.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L42) --- url: /zkapps/o1js-reference/type-aliases/FlexibleProvable --- ```ts type FlexibleProvable: Provable | Struct; ``` ## Type parameters • **T** ## Source [lib/provable/types/struct.ts:61](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L61) --- url: /zkapps/o1js-reference/type-aliases/FlexibleProvablePure --- ```ts type FlexibleProvablePure: ProvablePure | StructPure; ``` ## Type parameters • **T** ## Source [lib/provable/types/struct.ts:62](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L62) --- url: /zkapps/o1js-reference/type-aliases/Group --- ```ts type Group: Group; ``` ## Source [lib/provable/wrapped.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L76) --- url: /zkapps/o1js-reference/type-aliases/InferProvable --- ```ts type InferProvable: GenericInferProvable; ``` ## Type parameters • **T** ## Source [lib/provable/types/provable-derivers.ts:65](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-derivers.ts#L65) --- url: /zkapps/o1js-reference/type-aliases/JsonProof --- ```ts type JsonProof: { "maxProofsVerified": 0 | 1 | 2; "proof": string; "publicInput": string[]; "publicOutput": string[]; }; ``` ## Type declaration ### maxProofsVerified ```ts maxProofsVerified: 0 | 1 | 2; ``` ### proof ```ts proof: string; ``` ### publicInput ```ts publicInput: string[]; ``` ### publicOutput ```ts publicOutput: string[]; ``` ## Source [lib/proof-system/zkprogram.ts:146](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L146) --- url: /zkapps/o1js-reference/type-aliases/MerkleListBase --- ```ts type MerkleListBase: { "data": Unconstrained[]>; "hash": Field; }; ``` Common base type for [MerkleList](../classes/MerkleList.mdx) and [MerkleListIterator](../classes/MerkleListIterator.mdx) ## Type parameters • **T** ## Type declaration ### data ```ts data: Unconstrained[]>; ``` ### hash ```ts hash: Field; ``` ## Source [lib/provable/merkle-list.ts:46](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L46) --- url: /zkapps/o1js-reference/type-aliases/MerkleListIteratorBase --- ```ts type MerkleListIteratorBase: { "currentHash": Field; "currentIndex": Unconstrained; "data": Unconstrained[]>; "hash": Field; }; ``` ## Type parameters • **T** ## Type declaration ### currentHash ```ts currentHash: Field; ``` The merkle list hash of `[data[currentIndex], ..., data[length-1]]` (when hashing from right to left). For example: - If `currentIndex === 0`, then `currentHash === this.hash` is the hash of the entire array. - If `currentIndex === length`, then `currentHash === emptyHash` is the hash of an empty array. ### currentIndex ```ts currentIndex: Unconstrained; ``` The index of the element that will be returned by the next call to `next()`. ### data ```ts readonly data: Unconstrained[]>; ``` ### hash ```ts readonly hash: Field; ``` ## Source [lib/provable/merkle-list.ts:383](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L383) --- url: /zkapps/o1js-reference/type-aliases/Option --- ```ts type Option: { "isSome": Bool; "value": T; } & { "assertSome": T; "orElse": T; }; ``` ## Type declaration ### isSome ```ts isSome: Bool; ``` ### value ```ts value: T; ``` ## Type declaration ### assertSome() #### Parameters • **message?**: `string` #### Returns `T` ### orElse() #### Parameters • **defaultValue**: `T` \| `V` #### Returns `T` ## Type parameters • **T** • **V** = `any` ## Source [lib/provable/option.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/option.ts#L37) --- url: /zkapps/o1js-reference/type-aliases/Provable --- ```ts type Provable: { "check": (value: T) => void; "fromFields": (fields: Field[], aux: any[]) => T; "fromValue": (x: TValue | T) => T; "toAuxiliary": (value?: T) => any[]; "toCanonical": (x: T) => T; "toFields": (value: T) => Field[]; "toValue": (x: T) => TValue; "sizeInFields": number; }; ``` `Provable` is the general interface for provable types in o1js. `Provable` describes how a type `T` is made up of [Field](../classes/Field.mdx) elements and "auxiliary" (non-provable) data. `Provable` is the required input type in several methods in o1js. One convenient way to create a `Provable` is using `Struct`. All built-in provable types in o1js ([Field](../classes/Field.mdx), [Bool](../classes/Bool.mdx), etc.) are instances of `Provable` as well. Note: These methods are meant to be used by the library internally and are not directly when writing provable code. ## Type parameters • **T** • **TValue** = `any` ## Type declaration ### check() ```ts check: (value: T) => void; ``` Add assertions to the proof to check if `value` is a valid member of type `T`. This function does not return anything, instead it creates any number of assertions to prove that `value` is a valid member of the type `T`. For instance, calling check function on the type [Bool](../classes/Bool.mdx) asserts that the value of the element is either 1 or 0. #### Parameters • **value**: `T` the element of type `T` to put assertions on. #### Returns `void` ### fromFields() ```ts fromFields: (fields: Field[], aux: any[]) => T; ``` A function that returns an element of type `T` from the given provable and "auxiliary" data. This function is the reverse operation of calling toFields and toAuxilary methods on an element of type `T`. #### Parameters • **fields**: [`Field`](../classes/Field.mdx)[] an array of [Field](../classes/Field.mdx) elements describing the provable data of the new `T` element. • **aux**: `any`[] an array of any type describing the "auxiliary" data of the new `T` element, optional. #### Returns `T` ### fromValue() ```ts fromValue: (x: TValue | T) => T; ``` Convert provable type from a normal JS type. #### Parameters • **x**: `TValue` \| `T` #### Returns `T` ### toAuxiliary() ```ts toAuxiliary: (value?: T) => any[]; ``` A function that takes `value` (optional), an element of type `T`, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of `value`. #### Parameters • **value?**: `T` the element of type `T` to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned. #### Returns `any`[] ### toCanonical()? ```ts optional toCanonical: (x: T) => T; ``` Optional method which transforms a provable type into its canonical representation. This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations. An example is the `ForeignField` class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error. Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. `toCanonical()` converts any input into a safe form and enables us to handle cases like this generically. Note: For most types, this method is the identity function. The identity function will also be used when the `toCanonical()` is not present on a type. #### Parameters • **x**: `T` #### Returns `T` ### toFields() ```ts toFields: (value: T) => Field[]; ``` A function that takes `value`, an element of type `T`, as argument and returns an array of [Field](../classes/Field.mdx) elements that make up the provable data of `value`. #### Parameters • **value**: `T` the element of type `T` to generate the [Field](../classes/Field.mdx) array from. #### Returns [`Field`](../classes/Field.mdx)[] ### toValue() ```ts toValue: (x: T) => TValue; ``` Convert provable type to a normal JS type. #### Parameters • **x**: `T` #### Returns `TValue` ### sizeInFields() Return the size of the `T` type in terms of [Field](../classes/Field.mdx) type, as [Field](../classes/Field.mdx) is the primitive type. #### Returns `number` A `number` representing the size of the `T` type in terms of [Field](../classes/Field.mdx) type. ## Source [lib/provable/types/provable-intf.ts:27](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L27) --- url: /zkapps/o1js-reference/type-aliases/ProvableExtended --- ```ts type ProvableExtended: Provable & ProvableExtension; ``` ## Type parameters • **T** • **TValue** = `any` • **TJson** = `any` ## Source [lib/provable/types/struct.ts:49](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L49) --- url: /zkapps/o1js-reference/type-aliases/ProvableHashable-1 --- ```ts type ProvableHashable: ProvableWithEmpty & { "toInput": (x: T) => HashInput; }; ``` ## Type declaration ### toInput() ```ts toInput: (x: T) => HashInput; ``` #### Parameters • **x**: `T` #### Returns `HashInput` ## Type parameters • **T** • **TValue** = `any` ## Source [lib/provable/types/provable-intf.ts:124](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L124) --- url: /zkapps/o1js-reference/type-aliases/ProvableHashable --- ```ts type ProvableHashable: Provable & Hashable; ``` ## Type parameters • **T** • **V** = `any` ## Source [lib/provable/crypto/poseidon.ts:32](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/poseidon.ts#L32) --- url: /zkapps/o1js-reference/type-aliases/ProvablePure --- ```ts type ProvablePure: Omit, "fromFields"> & { "fromFields": (fields: Field[]) => T; }; ``` `ProvablePure` is a special kind of [Provable](Provable.mdx) interface, where the "auxiliary" (non-provable) data is empty. This means the type consists only of field elements, in that sense it is "pure". Any instance of `ProvablePure` is also an instance of `Provable` where the "auxiliary" data is empty. Examples where `ProvablePure` is required are types of on-chain state, events and actions. ## Type declaration ### fromFields() ```ts fromFields: (fields: Field[]) => T; ``` #### Parameters • **fields**: [`Field`](../classes/Field.mdx)[] #### Returns `T` ## Type parameters • **T** • **TValue** = `any` ## Source [lib/provable/types/provable-intf.ts:114](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L114) --- url: /zkapps/o1js-reference/type-aliases/ProvableType --- ```ts type ProvableType: WithProvable>; ``` ## Type parameters • **T** = `any` • **V** = `any` ## Source [lib/provable/types/provable-intf.ts:132](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L132) --- url: /zkapps/o1js-reference/type-aliases/ProvableTypePure --- ```ts type ProvableTypePure: WithProvable>; ``` ## Type parameters • **T** = `any` • **V** = `any` ## Source [lib/provable/types/provable-intf.ts:133](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L133) --- url: /zkapps/o1js-reference/type-aliases/ProvableWithEmpty --- ```ts type ProvableWithEmpty: Provable & { "empty": () => T; }; ``` ## Type declaration ### empty() ```ts empty: () => T; ``` #### Returns `T` ## Type parameters • **T** • **TValue** = `any` ## Source [lib/provable/types/provable-intf.ts:118](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L118) --- url: /zkapps/o1js-reference/type-aliases/Reducer --- ```ts type Reducer: { "actionType": FlexibleProvablePure; }; ``` ## Type parameters • **Action** ## Type declaration ### actionType ```ts actionType: FlexibleProvablePure; ``` ## Source [lib/mina/actions/reducer.ts:17](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/actions/reducer.ts#L17) --- url: /zkapps/o1js-reference/type-aliases/ScalarConst --- ```ts type ScalarConst: [0, bigint]; ``` ## Source [lib/provable/scalar.ts:20](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/scalar.ts#L20) --- url: /zkapps/o1js-reference/type-aliases/State --- ```ts type State: { "fetch": Promise; "fromAppState": A; "get": A; "getAndRequireEquals": A; "requireEquals": void; "requireEqualsIf": void; "requireNothing": void; "set": void; }; ``` Gettable and settable state that can be checked for equality. ## Type parameters • **A** ## Type declaration ### fetch() Asynchronously fetch the on-chain state. This is intended for getting the state outside a smart contract. #### Returns `Promise`\<`undefined` \| `A`\> ### fromAppState() 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); ``` #### Parameters • **appState**: [`Field`](../classes/Field.mdx)[] #### Returns `A` ### get() 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(); ``` #### Returns `A` ### getAndRequireEquals() 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. #### Returns `A` ### requireEquals() 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. #### Parameters • **a**: `A` #### Returns `void` ### requireEqualsIf() 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. #### Parameters • **condition**: [`Bool`](../classes/Bool.mdx) • **a**: `A` #### Returns `void` ### requireNothing() **DANGER ZONE**: Override the error message that warns you when you use `.get()` without adding a precondition. #### Returns `void` ### set() Set the on-chain state to a new value. #### Parameters • **a**: `A` #### Returns `void` ## Source [lib/mina/state.ts:91](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/state.ts#L91) --- url: /zkapps/o1js-reference/type-aliases/Struct --- ```ts type Struct: ProvableExtended> & Constructor & { "_isStruct": true; }; ``` ## Type declaration ### \_isStruct ```ts _isStruct: true; ``` ## Type parameters • **T** ## Source [lib/provable/types/struct.ts:140](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/struct.ts#L140) --- url: /zkapps/o1js-reference/type-aliases/ToProvable --- ```ts type ToProvable: A extends { "provable": infer P; } ? P : A; ``` ## Type parameters • **A** *extends* [`WithProvable`](WithProvable.mdx)\<`any`\> ## Source [lib/provable/types/provable-intf.ts:135](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L135) --- url: /zkapps/o1js-reference/type-aliases/TransactionPromise --- ```ts type TransactionPromise: Promise> & { "send": PendingTransactionPromise; } & Proven extends false ? { "prove": TransactionPromise; } : { "proofs": Promise["proofs"]>; } & Signed extends false ? { "sign": TransactionPromise; } : {}; ``` A `Promise` with some additional methods for making chained method calls into the pending value upon its resolution. ## Type declaration ### send() Equivalent to calling the resolved `Transaction`'s `send` method. #### Returns [`PendingTransactionPromise`](../namespaces/Mina/type-aliases/PendingTransactionPromise.mdx) ## Type parameters • **Proven** *extends* `boolean` • **Signed** *extends* `boolean` ## Source [lib/mina/transaction.ts:314](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/transaction.ts#L314) --- url: /zkapps/o1js-reference/type-aliases/TransactionStatus --- ```ts type TransactionStatus: "INCLUDED" | "PENDING" | "UNKNOWN"; ``` INCLUDED: A transaction that is on the longest chain PENDING: A transaction either in the transition frontier or in transaction pool but is not on the longest chain UNKNOWN: The transaction has either been snarked, reached finality through consensus or has been dropped ## Source [lib/mina/graphql.ts:216](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/graphql.ts#L216) --- url: /zkapps/o1js-reference/type-aliases/TupleN --- ```ts type TupleN: N extends N ? number extends N ? [...T[]] : [...TupleRec] : never; ``` tuple type that has the length as generic parameter ## Type parameters • **T** • **N** *extends* `number` ## Source [lib/util/types.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/util/types.ts#L28) --- url: /zkapps/o1js-reference/type-aliases/Undefined --- ```ts type Undefined: undefined; ``` ## Source [lib/proof-system/zkprogram.ts:82](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L82) --- url: /zkapps/o1js-reference/type-aliases/VarField --- ```ts type VarField: Field & { "value": VarFieldVar; }; ``` ## Type declaration ### value ```ts value: VarFieldVar; ``` ## Source [lib/provable/field.ts:1242](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/field.ts#L1242) --- url: /zkapps/o1js-reference/type-aliases/Void --- ```ts type Void: undefined; ``` ## Source [lib/proof-system/zkprogram.ts:87](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L87) --- url: /zkapps/o1js-reference/type-aliases/WithHash --- ```ts type WithHash: { "element": T; "previousHash": Field; }; ``` ## Type parameters • **T** ## Type declaration ### element ```ts element: T; ``` ### previousHash ```ts previousHash: Field; ``` ## Source [lib/provable/merkle-list.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L28) --- url: /zkapps/o1js-reference/type-aliases/WithProvable --- ```ts type WithProvable: { "provable": A; } | A; ``` ## Type parameters • **A** ## Source [lib/provable/types/provable-intf.ts:130](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L130) --- url: /zkapps/o1js-reference/type-aliases/Witness --- ```ts type Witness: { "isLeft": boolean; "sibling": Field; }[]; ``` ## Source [lib/provable/merkle-tree.ts:16](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-tree.ts#L16) --- url: /zkapps/o1js-reference/type-aliases/ZkProgram --- ```ts type ZkProgram: ReturnType; ``` ## Type parameters • **Config** *extends* \{ `"methods"`: `{ [I in string]: Object }`; `"publicInput"`: [`ProvableTypePure`](ProvableTypePure.mdx); `"publicOutput"`: [`ProvableTypePure`](ProvableTypePure.mdx); \} • **Methods** *extends* `{ [I in keyof Config["methods"]]: Method>, InferProvableOrVoid>, Config["methods"][I]> }` ## Source [lib/proof-system/zkprogram.ts:174](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L174) --- url: /zkapps/o1js-reference/type-aliases/ZkappPublicInput --- ```ts type ZkappPublicInput: { "accountUpdate": Field; "calls": Field; }; ``` The public input for zkApps consists of certain hashes of the proving account update (and its child updates) which is constructed during method execution. For SmartContract proving, a method is run twice: First outside the proof, to obtain the public input, and once in the prover, which takes the public input as input. The current transaction is hashed again inside the prover, which asserts that the result equals the input public input, as part of the snark circuit. The block producer will also hash the transaction they receive and pass it as a public input to the verifier. Thus, the transaction is fully constrained by the proof - the proof couldn't be used to attest to a different transaction. ## Type declaration ### accountUpdate ```ts accountUpdate: Field; ``` ### calls ```ts calls: Field; ``` ## Source [lib/mina/account-update.ts:2050](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L2050) --- url: /zkapps/o1js-reference/variables/Account --- ```ts Account: GenericProvableExtended; ``` ## Source [lib/mina/account.ts:19](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account.ts#L19) --- url: /zkapps/o1js-reference/variables/Bool --- ```ts const Bool: typeof Bool & (...args: [boolean | FieldVar | Bool]) => Bool; ``` A boolean value. You can create it like this: ## Example ``` const b = Bool(true); ``` You can also combine multiple Bools with boolean operations: ## Example ```ts const c = Bool(false); const d = b.or(c).and(false).not(); d.assertTrue(); ``` Bools are often created by methods on other types such as `Field.equals()`: ```ts const b: Bool = Field(5).equals(6); ``` ## Source [lib/provable/wrapped.ts:70](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L70) --- url: /zkapps/o1js-reference/variables/Cache --- ```ts Cache: { "FileSystem": (cacheDirectory: string, debug?: boolean) => Cache; "FileSystemDefault": Cache; "None": Cache; }; ``` ## Type declaration ### FileSystem() ```ts FileSystem: (cacheDirectory: string, debug?: boolean) => Cache; ``` #### Parameters • **cacheDirectory**: `string` • **debug?**: `boolean` #### Returns [`Cache`](../type-aliases/Cache.mdx) ### FileSystemDefault ```ts FileSystemDefault: Cache; ``` ### None ```ts None: Cache; ``` ## Source [lib/proof-system/cache.ts:37](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/cache.ts#L37) --- url: /zkapps/o1js-reference/variables/Crypto --- ```ts const Crypto: { "CurveParams": CurveParams_; "createCurve": {}; }; ``` ## Type declaration ### CurveParams ```ts CurveParams: {} = CurveParams_; ``` Parameters defining an elliptic curve in short Weierstraß form y^2 = x^3 + ax + b ### createCurve() Create elliptic curve arithmetic methods. #### Parameters • **params**: `CurveParams` #### Returns ```ts {} ``` ## Source [lib/provable/crypto/crypto.ts:8](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/crypto.ts#L8) --- url: /zkapps/o1js-reference/variables/Empty --- ```ts Empty: ProvablePureExtended; ``` ## Source [lib/proof-system/zkprogram.ts:85](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L85) --- url: /zkapps/o1js-reference/variables/FeatureFlags --- ```ts FeatureFlags: { "allMaybe": { "foreignFieldAdd": undefined; "foreignFieldMul": undefined; "lookup": undefined; "rangeCheck0": undefined; "rangeCheck1": undefined; "rot": undefined; "runtimeTables": undefined; "xor": undefined; }; "allNone": { "foreignFieldAdd": false; "foreignFieldMul": false; "lookup": false; "rangeCheck0": false; "rangeCheck1": false; "rot": false; "runtimeTables": false; "xor": false; }; "fromGates": featureFlagsFromGates; "fromZkProgram": (program: AnalysableProgram) => Promise; "fromZkProgramList": (programs: AnalysableProgram[]) => Promise; }; ``` Feature flags indicate what custom gates are used in a proof of circuit. Side loading, for example, requires a set of feature flags in advance (at compile time) in order to verify and side load proofs. If the side loaded proofs and verification keys do not match the specified feature flag configurations, the verification will fail. Flags specified as `undefined` are considered as `maybe` by Pickles. This means, proofs can be sided loaded that can, but don't have to, use a specific custom gate. _Note:_ `Maybe` feature flags incur a proving overhead. ## Type declaration ### allMaybe ```ts allMaybe: { "foreignFieldAdd": undefined; "foreignFieldMul": undefined; "lookup": undefined; "rangeCheck0": undefined; "rangeCheck1": undefined; "rot": undefined; "runtimeTables": undefined; "xor": undefined; }; ``` Returns a feature flag configuration where all flags are optional. ### allMaybe.foreignFieldAdd ```ts foreignFieldAdd: undefined = undefined; ``` ### allMaybe.foreignFieldMul ```ts foreignFieldMul: undefined = undefined; ``` ### allMaybe.lookup ```ts lookup: undefined = undefined; ``` ### allMaybe.rangeCheck0 ```ts rangeCheck0: undefined = undefined; ``` ### allMaybe.rangeCheck1 ```ts rangeCheck1: undefined = undefined; ``` ### allMaybe.rot ```ts rot: undefined = undefined; ``` ### allMaybe.runtimeTables ```ts runtimeTables: undefined = undefined; ``` ### allMaybe.xor ```ts xor: undefined = undefined; ``` ### allNone ```ts allNone: { "foreignFieldAdd": false; "foreignFieldMul": false; "lookup": false; "rangeCheck0": false; "rangeCheck1": false; "rot": false; "runtimeTables": false; "xor": false; }; ``` Returns a feature flag configuration where all flags are set to false. ### allNone.foreignFieldAdd ```ts foreignFieldAdd: boolean = false; ``` ### allNone.foreignFieldMul ```ts foreignFieldMul: boolean = false; ``` ### allNone.lookup ```ts lookup: boolean = false; ``` ### allNone.rangeCheck0 ```ts rangeCheck0: boolean = false; ``` ### allNone.rangeCheck1 ```ts rangeCheck1: boolean = false; ``` ### allNone.rot ```ts rot: boolean = false; ``` ### allNone.runtimeTables ```ts runtimeTables: boolean = false; ``` ### allNone.xor ```ts xor: boolean = false; ``` ### fromGates() ```ts fromGates: (gates: Gate[]) => FeatureFlags = featureFlagsFromGates; ``` Given a list of gates, returns the feature flag configuration that the gates use. #### Parameters • **gates**: `Gate`[] #### Returns [`FeatureFlags`](../type-aliases/FeatureFlags.mdx) ### fromZkProgram() ```ts fromZkProgram: (program: AnalysableProgram) => Promise; ``` Given a ZkProgram, return the feature flag configuration that fits the given program. This function considers all methods of the specified ZkProgram and finds a configuration that fits all. #### Parameters • **program**: `AnalysableProgram` #### Returns `Promise`\<[`FeatureFlags`](../type-aliases/FeatureFlags.mdx)\> ### fromZkProgramList() ```ts fromZkProgramList: (programs: AnalysableProgram[]) => Promise; ``` #### Parameters • **programs**: `AnalysableProgram`[] #### Returns `Promise`\<[`FeatureFlags`](../type-aliases/FeatureFlags.mdx)\> ## Source [lib/proof-system/feature-flags.ts:17](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/feature-flags.ts#L17) --- url: /zkapps/o1js-reference/variables/Field --- ```ts const Field: typeof Field & (...args: [ | string | number | bigint | FieldConst | FieldVar | Field]) => Field; ``` A [Field](Field.mdx) is an element of a prime order [finite field](https://en.wikipedia.org/wiki/Finite_field). Every other provable type is built using the [Field](Field.mdx) type. The field is the [pasta base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) of order 2^254 + 0x224698fc094cf91b992d30ed00000001 ([Field.ORDER](../classes/Field.mdx#order)). You can create a new Field from everything "field-like" (`bigint`, integer `number`, decimal `string`, `Field`). ## Example ``` Field(10n); // Field construction from a bigint Field(100); // Field construction from a number Field("1"); // Field construction from a decimal string ``` **Beware**: Fields _cannot_ be constructed from fractional numbers or alphanumeric strings: ```ts Field(3.141); // ERROR: Cannot convert a float to a field element Field("abc"); // ERROR: Invalid argument "abc" ``` Creating a Field from a negative number can result in unexpected behavior if you are not familiar with [modular arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic). ## Example ``` const x = Field(-1); // valid Field construction from negative number const y = Field(Field.ORDER - 1n); // same as `x` ``` **Important**: All the functions defined on a Field (arithmetic, logic, etc.) take their arguments as "field-like". A Field itself is also defined as a "field-like" element. ## Param the value to convert to a [Field](Field.mdx) ## Source [lib/provable/wrapped.ts:42](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L42) --- url: /zkapps/o1js-reference/variables/Gadgets --- ```ts const Gadgets: { "BLAKE2B": BLAKE2B; "Field3": { "provable": { "fromValue": Field3; "toValue": bigint; }; "from": Field3; "isConstant": boolean; "toBigint": bigint; "toBigints": [...{ [i in string | number | symbol]: bigint }[]]; }; "ForeignField": { "Sum": Sum; "add": Field3; "assertAlmostReduced": void; "assertLessThan": void; "assertLessThanOrEqual": void; "assertMul": void; "div": Field3; "inv": Field3; "mul": Field3; "neg": Field3; "sub": Field3; "sum": Field3; "toCanonical": Field3; }; "SHA256": SHA256; "addMod32": (x: Field, y: Field) => Field; "addMod64": (x: Field, y: Field) => Field; "arrayGet": (array: Field[], index: Field) => Field; "divMod32": (n: Field, nBits: number) => { "quotient": Field; "remainder": Field; }; "divMod64": (n: Field, nBits: number) => { "quotient": Field; "remainder": Field; }; "and": Field; "compactMultiRangeCheck": [Field, Field, Field]; "isDefinitelyInRangeN": Bool; "leftShift32": Field; "leftShift64": Field; "multiRangeCheck": void; "not": Field; "or": Field; "rangeCheck16": void; "rangeCheck32": void; "rangeCheck3x12": void; "rangeCheck64": [Field, Field, Field, Field]; "rangeCheck8": void; "rangeCheckN": void; "rightShift64": Field; "rotate32": Field; "rotate64": Field; "xor": Field; }; ``` ## Type declaration ### BLAKE2B ```ts BLAKE2B: { get "IV": UInt64[]; "hash": Bytes; }; ``` Implementation of the [BLAKE2b hash function.](https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2) Hash function with arbitrary length output. Applies the BLAKE2b hash function to a list of byte-sized elements. The function accepts [Bytes](../type-aliases/Bytes.mdx) as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using Gadgets.rangeCheck8). Alternatively, you can pass plain `number[]`, `bigint[]` or `Uint8Array` to perform a hash outside provable code. Produces an output of [Bytes](../type-aliases/Bytes.mdx) that conforms to the chosen digest length. #### Param [Bytes](../type-aliases/Bytes.mdx) representing the message to hash. ```ts let preimage = Bytes.fromString("hello world"); let digest = Gadgets.BLAKE2b.hash(preimage); ``` ### BLAKE2B.IV ```ts get IV(): UInt64[] ``` #### Returns [`UInt64`](../classes/UInt64.mdx)[] #### Source [lib/provable/gadgets/blake2b.ts:77](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/gadgets/blake2b.ts#L77) ### BLAKE2B.hash() #### Parameters • **data**: `FlexibleBytes` • **digestLength**: `number`= `64` #### Returns `Bytes` ### Field3 ```ts Field3: { "provable": { "fromValue": Field3; "toValue": bigint; }; "from": Field3; "isConstant": boolean; "toBigint": bigint; "toBigints": [...{ [i in string | number | symbol]: bigint }[]]; }; ``` ### Field3.provable ```ts provable: { "fromValue": Field3; "toValue": bigint; }; ``` `Provable` interface for `Field3 = [Field, Field, Field]`. Note: Witnessing this creates a plain tuple of field elements without any implicit range checks. ### Field3.provable.fromValue() #### Parameters • **x**: `bigint` \| `Field3` #### Returns `Field3` ### Field3.provable.toValue() #### Parameters • **x**: `Field3` #### Returns `bigint` ### Field3.from() Turn a bigint into a 3-tuple of Fields #### Parameters • **x**: `bigint` \| `Field3` #### Returns `Field3` ### Field3.isConstant() Check whether a 3-tuple of Fields is constant #### Parameters • **x**: `Field3` #### Returns `boolean` ### Field3.toBigint() Turn a 3-tuple of Fields into a bigint #### Parameters • **x**: `Field3` #### Returns `bigint` ### Field3.toBigints() Turn several 3-tuples of Fields into bigints #### Type parameters • **T** *extends* `Tuple`\<`Field3`\> #### Parameters • ...**xs**: `T` #### Returns [...\{ [i in string \| number \| symbol]: bigint \}[]] ### ForeignField ```ts ForeignField: { "Sum": Sum; "add": Field3; "assertAlmostReduced": void; "assertLessThan": void; "assertLessThanOrEqual": void; "assertMul": void; "div": Field3; "inv": Field3; "mul": Field3; "neg": Field3; "sub": Field3; "sum": Field3; "toCanonical": Field3; }; ``` Gadgets for foreign field operations. A _foreign field_ is a finite field different from the native field of the proof system. The `ForeignField` namespace exposes operations like modular addition and multiplication, which work for any finite field of size less than 2^259. Foreign field elements are represented as 3 limbs of native field elements. Each limb holds 88 bits of the total, in little-endian order. All `ForeignField` gadgets expect that their input limbs are constrained to the range [0, 2^88). Range checks on outputs are added by the gadget itself. ### ForeignField.Sum() Lazy sum of Field3 elements, which can be used as input to Gadgets.ForeignField.assertMul. #### Parameters • **x**: `Field3` #### Returns `Sum` ### ForeignField.add() Foreign field addition: `x + y mod f` The modulus `f` does not need to be prime. Inputs and outputs are 3-tuples of native Fields. Each input limb is assumed to be in the range [0, 2^88), and the gadget is invalid if this is not the case. The result limbs are guaranteed to be in the same range. #### Parameters • **x**: `Field3` left summand • **y**: `Field3` right summand • **f**: `bigint` modulus #### Returns `Field3` x + y mod f #### Example ```ts let x = Provable.witness(Field3, () => 9n); let y = Provable.witness(Field3, () => 10n); // range check x and y Gadgets.multiRangeCheck(x); Gadgets.multiRangeCheck(y); // compute x + y mod 17 let z = ForeignField.add(x, y, 17n); Provable.log(z); // ['2', '0', '0'] = limb representation of 2 = 9 + 10 mod 17 ``` **Warning**: The gadget does not assume that inputs are reduced modulo f, and does not prove that the result is reduced modulo f. It only guarantees that the result is in the correct residue class. ### ForeignField.assertAlmostReduced() Prove that each of the given Field3 elements is "almost" reduced modulo f, i.e., satisfies the assumptions required by Gadgets.ForeignField.mul and other gadgets: - each limb is in the range [0, 2^88) - the most significant limb is less or equal than the modulus, x[2] ≤ f[2] **Note**: This method is most efficient when the number of input elements is a multiple of 3. #### Parameters • **xs**: `Field3`[] • **f**: `bigint` • **\_\_namedParameters**= `{}` • **\_\_namedParameters.skipMrc**: `undefined` \| `boolean`= `false` #### Returns `void` #### Throws if any of the assumptions is violated. #### Example ```ts let x = Provable.witness(Field3, () => 4n); let y = Provable.witness(Field3, () => 5n); let z = Provable.witness(Field3, () => 10n); ForeignField.assertAlmostReduced([x, y, z], f); // now we can use x, y, z as inputs to foreign field multiplication let xy = ForeignField.mul(x, y, f); let xyz = ForeignField.mul(xy, z, f); // since xy is an input to another multiplication, we need to prove that it is almost reduced again! ForeignField.assertAlmostReduced([xy], f); // TODO: would be more efficient to batch this with 2 other elements ``` ### ForeignField.assertLessThan() Prove that x < f for any constant f < 2^264, or for another `Field3` f. If f is a finite field modulus, this means that the given field element is fully reduced modulo f. This is a stronger statement than [ForeignField.assertAlmostReduced](../classes/ForeignField.mdx#assertalmostreduced-1) and also uses more constraints; it should not be needed in most use cases. **Note**: This assumes that the limbs of x are in the range [0, 2^88), in contrast to [ForeignField.assertAlmostReduced](../classes/ForeignField.mdx#assertalmostreduced-1) which adds that check itself. #### Parameters • **x**: `Field3` • **f**: `bigint` \| `Field3` #### Returns `void` #### Throws if x is greater or equal to f. #### Example ```ts let x = Provable.witness(Field3, () => 0x1235n); // range check limbs of x Gadgets.multiRangeCheck(x); // prove that x is fully reduced mod f Gadgets.ForeignField.assertLessThan(x, f); ``` ### ForeignField.assertLessThanOrEqual() Prove that x ≤ f for any constant f < 2^264, or for another `Field3` f. See [ForeignField.assertLessThan](../classes/ForeignField.mdx#assertlessthan) for details and usage examples. #### Parameters • **x**: `Field3` • **f**: `bigint` \| `Field3` #### Returns `void` ### ForeignField.assertMul() Optimized multiplication of sums in a foreign field, for example: `(x - y)*z = a + b + c mod f` Note: This is much more efficient than using Gadgets.ForeignField.add and Gadgets.ForeignField.sub separately to compute the multiplication inputs and outputs, and then using Gadgets.ForeignField.mul to constrain the result. The sums passed into this method are "lazy sums" created with Gadgets.ForeignField.Sum. You can also pass in plain Field3 elements. **Assumptions**: The assumptions on the _summands_ are analogous to the assumptions described in Gadgets.ForeignField.mul: - each summand's limbs are in the range [0, 2^88) - summands that are part of a multiplication input satisfy `x[2] <= f[2]` #### Parameters • **x**: `Field3` \| `Sum` • **y**: `Field3` \| `Sum` • **z**: `Field3` \| `Sum` • **f**: `bigint` #### Returns `void` #### Throws if the modulus is so large that the second assumption no longer suffices for validity of the multiplication. For small sums and moduli < 2^256, this will not fail. #### Throws if the provided multiplication result is not correct modulo f. #### Example ```ts // range-check x, y, z, a, b, c ForeignField.assertAlmostReduced([x, y, z], f); Gadgets.multiRangeCheck(a); Gadgets.multiRangeCheck(b); Gadgets.multiRangeCheck(c); // create lazy input sums let xMinusY = ForeignField.Sum(x).sub(y); let aPlusBPlusC = ForeignField.Sum(a).add(b).add(c); // assert that (x - y)*z = a + b + c mod f ForeignField.assertMul(xMinusY, z, aPlusBPlusC, f); ``` ### ForeignField.div() Foreign field division: `x * y^(-1) mod f` See Gadgets.ForeignField.mul for assumptions on inputs and usage examples. This gadget adds an extra bound check on the result, so it can be used directly in another foreign field multiplication. #### Parameters • **x**: `Field3` • **y**: `Field3` • **f**: `bigint` #### Returns `Field3` #### Throws Different than Gadgets.ForeignField.mul, this fails on unreduced input `x`, because it checks that `x === (x/y)*y` and the right side will be reduced. ### ForeignField.inv() Foreign field inverse: `x^(-1) mod f` See Gadgets.ForeignField.mul for assumptions on inputs and usage examples. This gadget adds an extra bound check on the result, so it can be used directly in another foreign field multiplication. #### Parameters • **x**: `Field3` • **f**: `bigint` #### Returns `Field3` ### ForeignField.mul() Foreign field multiplication: `x * y mod f` The modulus `f` does not need to be prime, but has to be smaller than 2^259. **Assumptions**: In addition to the assumption that input limbs are in the range [0, 2^88), as in all foreign field gadgets, this assumes an additional bound on the inputs: `x * y < 2^264 * p`, where p is the native modulus. We usually assert this bound by proving that `x[2] < f[2] + 1`, where `x[2]` is the most significant limb of x. To do this, we use an 88-bit range check on `2^88 - x[2] - (f[2] + 1)`, and same for y. The implication is that x and y are _almost_ reduced modulo f. All of the above assumptions are checked by Gadgets.ForeignField.assertAlmostReduced. **Warning**: This gadget does not add the extra bound check on the result. So, to use the result in another foreign field multiplication, you have to add the bound check on it yourself, again. #### Parameters • **x**: `Field3` • **y**: `Field3` • **f**: `bigint` #### Returns `Field3` #### Example ```ts // example modulus: secp256k1 prime let f = (1n << 256n) - (1n << 32n) - 0b1111010001n; let x = Provable.witness(Field3, () => f - 1n); let y = Provable.witness(Field3, () => f - 2n); // range check x, y and prove additional bounds x[2] <= f[2] ForeignField.assertAlmostReduced([x, y], f); // compute x * y mod f let z = ForeignField.mul(x, y, f); Provable.log(z); // ['2', '0', '0'] = limb representation of 2 = (-1)*(-2) mod f ``` ### ForeignField.neg() Foreign field negation: `-x mod f = f - x` See [ForeignField.add](../classes/ForeignField.mdx#add) for assumptions and usage examples. #### Parameters • **x**: `Field3` • **f**: `bigint` #### Returns `Field3` #### Throws fails if `x > f`, where `f - x < 0`. ### ForeignField.sub() Foreign field subtraction: `x - y mod f` See Gadgets.ForeignField.add for assumptions and usage examples. #### Parameters • **x**: `Field3` • **y**: `Field3` • **f**: `bigint` #### Returns `Field3` #### Throws fails if `x - y < -f`, where the result cannot be brought back to a positive number by adding `f` once. ### ForeignField.sum() Foreign field sum: `xs[0] + signs[0] * xs[1] + ... + signs[n-1] * xs[n] mod f` This gadget takes a list of inputs and a list of signs (of size one less than the inputs), and computes a chain of additions or subtractions, depending on the sign. A sign is of type `1n | -1n`, where `1n` represents addition and `-1n` represents subtraction. **Note**: For 3 or more inputs, `sum()` uses fewer constraints than a sequence of `add()` and `sub()` calls, because we can avoid range checks on intermediate results. See Gadgets.ForeignField.add for assumptions on inputs. #### Parameters • **xs**: `Field3`[] • **signs**: (`1n` \| `-1n`)[] • **f**: `bigint` #### Returns `Field3` #### Example ```ts let x = Provable.witness(Field3, () => 4n); let y = Provable.witness(Field3, () => 5n); let z = Provable.witness(Field3, () => 10n); // range check x, y, z Gadgets.multiRangeCheck(x); Gadgets.multiRangeCheck(y); Gadgets.multiRangeCheck(z); // compute x + y - z mod 17 let sum = ForeignField.sum([x, y, z], [1n, -1n], 17n); Provable.log(sum); // ['16', '0', '0'] = limb representation of 16 = 4 + 5 - 10 mod 17 ``` ### ForeignField.toCanonical() Convert x, which may be unreduced, to a canonical representative xR < f such that x = xR mod f Note: This method is complete, it works for all unreduced field elements. It can therefore be used to protect against incompleteness of field operations in other places. #### Parameters • **x**: `Field3` • **f**: `bigint` #### Returns `Field3` ### SHA256 ```ts SHA256: { "compression": sha256Compression; "createMessageSchedule": (M: UInt32[]) => UInt32[]; "padding": (data: FlexibleBytes) => UInt32[][]; get "initialState": UInt32[]; "hash": Bytes; }; ``` Implementation of the [SHA256 hash function.](https://en.wikipedia.org/wiki/SHA-2) Hash function with 256bit output. Applies the SHA2-256 hash function to a list of byte-sized elements. The function accepts [Bytes](../type-aliases/Bytes.mdx) as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using Gadgets.rangeCheck8). Alternatively, you can pass plain `number[]`, `bigint[]` or `Uint8Array` to perform a hash outside provable code. Produces an output of [Bytes](../type-aliases/Bytes.mdx) that conforms to the chosen bit length. #### Param [Bytes](../type-aliases/Bytes.mdx) representing the message to hash. ```ts let preimage = Bytes.fromString("hello world"); let digest = Gadgets.SHA256.hash(preimage); ``` ### SHA256.compression() ```ts compression: (H: UInt32[], W: UInt32[]) => UInt32[] = sha256Compression; ``` Performs the SHA-256 compression function on the given hash values and message schedule. #### Parameters • **H**: [`UInt32`](../classes/UInt32.mdx)[] The initial or intermediate hash values (8-element array of UInt32). • **W**: [`UInt32`](../classes/UInt32.mdx)[] The message schedule (64-element array of UInt32). #### Returns [`UInt32`](../classes/UInt32.mdx)[] The updated intermediate hash values after compression. ### SHA256.createMessageSchedule() ```ts createMessageSchedule: (M: UInt32[]) => UInt32[]; ``` Prepares the message schedule for the SHA-256 compression function from the given message block. #### Parameters • **M**: [`UInt32`](../classes/UInt32.mdx)[] The 512-bit message block (16-element array of UInt32). #### Returns [`UInt32`](../classes/UInt32.mdx)[] The message schedule (64-element array of UInt32). ### SHA256.padding() ```ts padding: (data: FlexibleBytes) => UInt32[][]; ``` #### Parameters • **data**: `FlexibleBytes` #### Returns [`UInt32`](../classes/UInt32.mdx)[][] ### SHA256.initialState ```ts get initialState(): UInt32[] ``` #### Returns [`UInt32`](../classes/UInt32.mdx)[] #### Source [lib/provable/gadgets/sha256.ts:100](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/gadgets/sha256.ts#L100) ### SHA256.hash() #### Parameters • **data**: `FlexibleBytes` #### Returns `Bytes` ### addMod32() ```ts addMod32: (x: Field, y: Field) => Field; ``` #### Parameters • **x**: [`Field`](../classes/Field.mdx) • **y**: [`Field`](../classes/Field.mdx) #### Returns [`Field`](../classes/Field.mdx) ### addMod64() ```ts addMod64: (x: Field, y: Field) => Field; ``` #### Parameters • **x**: [`Field`](../classes/Field.mdx) • **y**: [`Field`](../classes/Field.mdx) #### Returns [`Field`](../classes/Field.mdx) ### arrayGet() ```ts arrayGet: (array: Field[], index: Field) => Field; ``` Get value from array in O(n) rows. Assumes that index is in [0, n), returns an unconstrained result otherwise. Note: This saves 0.5*n constraints compared to equals() + switch() even if equals() were implemented optimally. #### Parameters • **array**: [`Field`](../classes/Field.mdx)[] • **index**: [`Field`](../classes/Field.mdx) #### Returns [`Field`](../classes/Field.mdx) ### divMod32() ```ts divMod32: (n: Field, nBits: number) => { "quotient": Field; "remainder": Field; }; ``` #### Parameters • **n**: [`Field`](../classes/Field.mdx) • **nBits**: `number`= `64` #### Returns ```ts { "quotient": Field; "remainder": Field; } ``` ##### quotient ```ts quotient: Field; ``` ##### remainder ```ts remainder: Field; ``` ### divMod64() ```ts divMod64: (n: Field, nBits: number) => { "quotient": Field; "remainder": Field; }; ``` #### Parameters • **n**: [`Field`](../classes/Field.mdx) • **nBits**: `number`= `128` #### Returns ```ts { "quotient": Field; "remainder": Field; } ``` ##### quotient ```ts quotient: Field; ``` ##### remainder ```ts remainder: Field; ``` ### and() Bitwise AND gadget on [Field](Field.mdx) elements. Equivalent to the [bitwise AND `&` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND). The AND gate works by comparing two bits and returning `1` if both bits are `1`, and `0` otherwise. It can be checked by a double generic gate that verifies the following relationship between the values below (in the process it also invokes the Gadgets.xor gadget which will create additional constraints depending on `length`). The generic gate verifies:\ `a + b = sum` and the conjunction equation `2 * and = sum - xor`\ Where:\ `a + b = sum`\ `a ^ b = xor`\ `a & b = and` You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#and) The `length` parameter lets you define how many bits should be compared. `length` is rounded to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values are constrained to fit into `paddedLength` bits. The output is guaranteed to have at most `paddedLength` bits as well. **Note:** Specifying a larger `length` parameter adds additional constraints. **Note:** Both [Field](Field.mdx) elements need to fit into `2^paddedLength - 1`. Otherwise, an error is thrown and no proof can be generated. For example, with `length = 2` (`paddedLength = 16`), `and()` will fail for any input that is larger than `2**16`. #### Parameters • **a**: [`Field`](../classes/Field.mdx) • **b**: [`Field`](../classes/Field.mdx) • **length**: `number` #### Returns [`Field`](../classes/Field.mdx) #### Example ```typescript let a = Field(3); // ... 000011 let b = Field(5); // ... 000101 let c = Gadgets.and(a, b, 2); // ... 000001 c.assertEquals(1); ``` ### compactMultiRangeCheck() Compact multi-range check This is a variant of multiRangeCheck where the first two variables are passed in combined form xy = x + 2^88*y. The gadget - splits up xy into x and y - proves that xy = x + 2^88*y - proves that x, y, z are all in the range [0, 2^88). The split form [x, y, z] is returned. #### Parameters • **xy**: [`Field`](../classes/Field.mdx) • **z**: [`Field`](../classes/Field.mdx) #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] #### Example ```ts let [x, y] = Gadgets.compactMultiRangeCheck([xy, z]); ``` #### Throws Throws an error if `xy` exceeds 2*88 = 176 bits, or if z exceeds 88 bits. ### isDefinitelyInRangeN() Returns a boolean which being true proves that x is in the range [0, 2^n). **Beware**: The output being false does **not** prove that x is not in the range [0, 2^n). This should not be viewed as a standalone provable method but as an advanced helper function for gadgets which need a weakened form of range check. #### Parameters • **n**: `number` The number of bits to be considered for the range check. • **x**: [`Field`](../classes/Field.mdx) The value to be weakly range-checked. #### Returns [`Bool`](../classes/Bool.mdx) a Bool that is definitely only true if the input is in the range [0, 2^n), but could also be false _even if_ the input is in the range [0, 2^n). #### Example ```ts const x = Provable.witness(Field, () => Field(12345678n)); let definitelyInRange = Gadgets.isDefinitelyInRangeN(32, x); // could be true or false ``` ### leftShift32() Performs a left shift operation on the provided [Field](Field.mdx) element. This operation is similar to the `<<` shift operation in JavaScript, where bits are shifted to the left, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 32-bit representation of the number, where the most significant (32th) bit is on the left end and the least significant bit is on the right end. **Important:** The gadgets assumes that its input is at most 32 bits in size. The output is range checked to 32 bits. #### Parameters • **field**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to shift. • **bits**: `number` Amount of bits to shift the [Field](Field.mdx) element to the left. The amount should be between 0 and 32 (or else the shift will fail). #### Returns [`Field`](../classes/Field.mdx) #### Example ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.leftShift32(x, 2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary ``` ### leftShift64() Performs a left shift operation on the provided [Field](Field.mdx) element. This operation is similar to the `<<` shift operation in JavaScript, where bits are shifted to the left, and the overflowing bits are discarded. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. **Important:** The gadgets assumes that its input is at most 64 bits in size. If the input exceeds 64 bits, the gadget is invalid and fails to prove correct execution of the shift. Therefore, to safely use `leftShift()`, you need to make sure that the values passed in are range checked to 64 bits. For example, this can be done with Gadgets.rangeCheck64. #### Parameters • **field**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to shift. • **bits**: `number` Amount of bits to shift the [Field](Field.mdx) element to the left. The amount should be between 0 and 64 (or else the shift will fail). #### Returns [`Field`](../classes/Field.mdx) #### Throws Throws an error if the input value exceeds 64 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.leftShift64(x, 2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); leftShift64(xLarge, 32); // throws an error since input exceeds 64 bits ``` ### multiRangeCheck() Multi-range check. Proves that x, y, z are all in the range [0, 2^88). This takes 4 rows, so it checks 88*3/4 = 66 bits per row. This is slightly more efficient than 64-bit range checks, which can do 64 bits in 1 row. In particular, the 3x88-bit range check supports bigints up to 264 bits, which in turn is enough to support foreign field multiplication with moduli up to 2^259. #### Parameters • **limbs**: `Field3` #### Returns `void` #### Example ```ts Gadgets.multiRangeCheck([x, y, z]); ``` #### Throws Throws an error if one of the input values exceeds 88 bits. ### not() Bitwise NOT gate on [Field](Field.mdx) elements. Similar to the [bitwise NOT `~` operator in JavaScript](https://developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/Operators/Bitwise_NOT). **Note:** The NOT gate only operates over the amount of bits specified by the `length` parameter. A NOT gate works by returning `1` in each bit position if the corresponding bit of the operand is `0`, and returning `0` if the corresponding bit of the operand is `1`. The `length` parameter lets you define how many bits to NOT. **Note:** Specifying a larger `length` parameter adds additional constraints. The operation will fail if the length or the input value is larger than 254. NOT is implemented in two different ways. If the `checked` parameter is set to `true` the Gadgets.xor gadget is reused with a second argument to be an all one bitmask the same length. This approach needs as many rows as an XOR would need for a single negation. If the `checked` parameter is set to `false`, NOT is implemented as a subtraction of the input from the all one bitmask. This implementation is returned by default if no `checked` parameter is provided. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#not) #### Parameters • **a**: [`Field`](../classes/Field.mdx) The value to apply NOT to. The operation will fail if the value is larger than 254. • **length**: `number` The number of bits to be considered for the NOT operation. • **checked**: `boolean`= `false` Optional boolean to determine if the checked or unchecked not implementation is used. If it is set to `true` the Gadgets.xor gadget is reused. If it is set to `false`, NOT is implemented as a subtraction of the input from the all one bitmask. It is set to `false` by default if no parameter is provided. #### Returns [`Field`](../classes/Field.mdx) #### Example ```ts // not-ing 4 bits with the unchecked version let a = Field(0b0101); let b = Gadgets.not(a,4,false); b.assertEquals(0b1010); // not-ing 4 bits with the checked version utilizing the xor gadget let a = Field(0b0101); let b = Gadgets.not(a,4,true); b.assertEquals(0b1010); ``` #### Throws Throws an error if the input value exceeds 254 bits. ### or() Bitwise OR gadget on [Field](Field.mdx) elements. Equivalent to the [bitwise OR `|` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR). The OR gate works by comparing two bits and returning `1` if at least one bit is `1`, and `0` otherwise. The `length` parameter lets you define how many bits should be compared. `length` is rounded to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values are constrained to fit into `paddedLength` bits. The output is guaranteed to have at most `paddedLength` bits as well. **Note:** Specifying a larger `length` parameter adds additional constraints. **Note:** Both [Field](Field.mdx) elements need to fit into `2^paddedLength - 1`. Otherwise, an error is thrown and no proof can be generated. For example, with `length = 2` (`paddedLength = 16`), `and()` will fail for any input that is larger than `2**16`. #### Parameters • **a**: [`Field`](../classes/Field.mdx) • **b**: [`Field`](../classes/Field.mdx) • **length**: `number` #### Returns [`Field`](../classes/Field.mdx) #### Example ```typescript let a = Field.from(3); // ... 000011 let b = Field.from(5); // ... 000101 let c = Gadgets.or(a, b, 16); // ... 000111 c.assertEquals(7); ``` ### rangeCheck16() #### Parameters • **x**: [`Field`](../classes/Field.mdx) #### Returns `void` ### rangeCheck32() Asserts that the input value is in the range [0, 2^32). This function proves that the provided field element can be represented with 32 bits. If the field element exceeds 32 bits, an error is thrown. #### Parameters • **x**: [`Field`](../classes/Field.mdx) The value to be range-checked. #### Returns `void` #### Throws Throws an error if the input value exceeds 32 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(12345678n)); Gadgets.rangeCheck32(x); // successfully proves 32-bit range const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rangeCheck32(xLarge); // throws an error since input exceeds 32 bits ``` **Note**: Small "negative" field element inputs are interpreted as large integers close to the field size, and don't pass the 32-bit check. If you want to prove that a value lies in the int32 range [-2^31, 2^31), you could use `rangeCheck32(x.add(1n << 31n))`. ### rangeCheck3x12() Checks that three [Field](Field.mdx) elements are in the range [0, 2^12) (using only one row). Internally, this gadget relies on the 12-bit [range check table](https://github.com/o1-labs/proof-systems/blob/master/kimchi/src/circuits/lookup/tables/mod.rs). All three inputs are checked to be included in that table. It's possible to use this as a range check for bit lengths n < 12, by passing in _two values_. - the value to be checked, `x`, to prove that x in [0, 2^12) - x scaled by 2^(12 - n), to prove that either x in [0, 2^n) or `x * 2^(12 - n)` overflows the field size (which is excluded by the first check) Note that both of these checks are necessary to prove x in [0, 2^n). You can find more details about lookups in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=lookup%20gate#lookup) #### Parameters • **v0**: [`Field`](../classes/Field.mdx) The first [Field](Field.mdx) element to be checked. • **v1**: [`Field`](../classes/Field.mdx) The second [Field](Field.mdx) element to be checked. • **v2**: [`Field`](../classes/Field.mdx) The third [Field](Field.mdx) element to be checked. #### Returns `void` #### Throws Throws an error if one of the input values exceeds 2^12. #### Example ```typescript let a = Field(4000); rangeCheck3x12(a, Field(0), Field(0)); // works, since `a` is less than 12 bits let aScaled = a.mul(1 << 4); // scale `a`, to assert that it's less than 8 bits rangeCheck3x12(a, aScaled, Field(0)); // throws an error, since `a` is greater than 8 bits (and so `aScaled` is greater than 12 bits) ``` ### rangeCheck64() Asserts that the input value is in the range [0, 2^64). This function proves that the provided field element can be represented with 64 bits. If the field element exceeds 64 bits, an error is thrown. #### Parameters • **x**: [`Field`](../classes/Field.mdx) The value to be range-checked. #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] #### Throws Throws an error if the input value exceeds 64 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(12345678n)); Gadgets.rangeCheck64(x); // successfully proves 64-bit range const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rangeCheck64(xLarge); // throws an error since input exceeds 64 bits ``` **Note**: Small "negative" field element inputs are interpreted as large integers close to the field size, and don't pass the 64-bit check. If you want to prove that a value lies in the int64 range [-2^63, 2^63), you could use `rangeCheck64(x.add(1n << 63n))`. _Advanced usage_: This returns the 4 highest limbs of x, in reverse order, i.e. [x52, x40, x28, x16]. This is useful if you want to do a range check for 52, 40, 28, or 16 bits instead of 64, by constraining some of the returned limbs to be 0. ### rangeCheck8() Asserts that the input value is in the range [0, 2^8). See Gadgets.rangeCheck64 for analogous details and usage examples. #### Parameters • **x**: [`Field`](../classes/Field.mdx) #### Returns `void` ### rangeCheckN() Asserts that the input value is in the range [0, 2^n). `n` must be a multiple of 16. This function proves that the provided field element can be represented with `n` bits. If the field element exceeds `n` bits, an error is thrown. #### Parameters • **n**: `number` The number of bits to be considered for the range check. • **x**: [`Field`](../classes/Field.mdx) The value to be range-checked. • **message?**: `string` Optional message to be displayed when the range check fails. #### Returns `void` #### Throws Throws an error if the input value exceeds `n` bits. #### Example ```ts const x = Provable.witness(Field, () => Field(12345678n)); Gadgets.rangeCheckN(32, x); // successfully proves 32-bit range const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rangeCheckN(32, xLarge); // throws an error since input exceeds 32 bits ``` ### rightShift64() Performs a right shift operation on the provided [Field](Field.mdx) element. This is similar to the `>>` shift operation in JavaScript, where bits are moved to the right. The `rightShift64` function utilizes the rotation method internally to implement this operation. * It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. **Important:** The gadgets assumes that its input is at most 64 bits in size. If the input exceeds 64 bits, the gadget is invalid and fails to prove correct execution of the shift. To safely use `rightShift64()`, you need to make sure that the value passed in is range-checked to 64 bits; for example, using Gadgets.rangeCheck64. #### Parameters • **field**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to shift. • **bits**: `number` Amount of bits to shift the [Field](Field.mdx) element to the right. The amount should be between 0 and 64 (or else the shift will fail). #### Returns [`Field`](../classes/Field.mdx) #### Throws Throws an error if the input value exceeds 64 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.rightShift64(x, 2); // right shift by 2 bits y.assertEquals(0b000011); // 3 in binary const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); rightShift64(xLarge, 32); // throws an error since input exceeds 64 bits ``` ### rotate32() A (left and right) rotation operates similarly to the shift operation (`<<` for left and `>>` for right) in JavaScript, with the distinction that the bits are circulated to the opposite end of a 32-bit representation rather than being discarded. For a left rotation, this means that bits shifted off the left end reappear at the right end. Conversely, for a right rotation, bits shifted off the right end reappear at the left end. It’s important to note that these operations are performed considering the big-endian 32-bit representation of the number, where the most significant (32th) bit is on the left end and the least significant bit is on the right end. The `direction` parameter is a string that accepts either `'left'` or `'right'`, determining the direction of the rotation. **Important:** The gadget assumes that its input is at most 32 bits in size. If the input exceeds 32 bits, the gadget is invalid and fails to prove correct execution of the rotation. To safely use `rotate32()`, you need to make sure that the value passed in is range-checked to 32 bits; for example, using Gadgets.rangeCheck32. #### Parameters • **field**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to rotate. • **bits**: `number` amount of bits to rotate this [Field](Field.mdx) element with. • **direction**: `"left"` \| `"right"`= `'left'` left or right rotation direction. #### Returns [`Field`](../classes/Field.mdx) #### Throws Throws an error if the input value exceeds 32 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(0b001100)); const y = Gadgets.rotate32(x, 2, 'left'); // left rotation by 2 bits const z = Gadgets.rotate32(x, 2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rotate32(xLarge, 32, "left"); // throws an error since input exceeds 32 bits ``` ### rotate64() A (left and right) rotation operates similarly to the shift operation (`<<` for left and `>>` for right) in JavaScript, with the distinction that the bits are circulated to the opposite end of a 64-bit representation rather than being discarded. For a left rotation, this means that bits shifted off the left end reappear at the right end. Conversely, for a right rotation, bits shifted off the right end reappear at the left end. It’s important to note that these operations are performed considering the big-endian 64-bit representation of the number, where the most significant (64th) bit is on the left end and the least significant bit is on the right end. The `direction` parameter is a string that accepts either `'left'` or `'right'`, determining the direction of the rotation. **Important:** The gadget assumes that its input is at most 64 bits in size. If the input exceeds 64 bits, the gadget is invalid and fails to prove correct execution of the rotation. To safely use `rotate64()`, you need to make sure that the value passed in is range-checked to 64 bits; for example, using Gadgets.rangeCheck64. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#rotation) #### Parameters • **field**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to rotate. • **bits**: `number` amount of bits to rotate this [Field](Field.mdx) element with. • **direction**: `"left"` \| `"right"`= `'left'` left or right rotation direction. #### Returns [`Field`](../classes/Field.mdx) #### Throws Throws an error if the input value exceeds 64 bits. #### Example ```ts const x = Provable.witness(Field, () => Field(0b001100)); const y = Gadgets.rotate64(x, 2, 'left'); // left rotation by 2 bits const z = Gadgets.rotate64(x, 2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rotate64(xLarge, 32, "left"); // throws an error since input exceeds 64 bits ``` ### xor() Bitwise XOR gadget on [Field](Field.mdx) elements. Equivalent to the [bitwise XOR `^` operator in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR). A XOR gate works by comparing two bits and returning `1` if two bits differ, and `0` if two bits are equal. This gadget builds a chain of XOR gates recursively. Each XOR gate can verify 16 bit at most. If your input elements exceed 16 bit, another XOR gate will be added to the chain. The `length` parameter lets you define how many bits should be compared. `length` is rounded to the nearest multiple of 16, `paddedLength = ceil(length / 16) * 16`, and both input values are constrained to fit into `paddedLength` bits. The output is guaranteed to have at most `paddedLength` bits as well. **Note:** Specifying a larger `length` parameter adds additional constraints. It is also important to mention that specifying a smaller `length` allows the verifier to infer the length of the original input data (e.g. smaller than 16 bit if only one XOR gate has been used). A zkApp developer should consider these implications when choosing the `length` parameter and carefully weigh the trade-off between increased amount of constraints and security. **Important:** Both [Field](Field.mdx) elements need to fit into `2^paddedLength - 1`. Otherwise, an error is thrown and no proof can be generated. For example, with `length = 2` (`paddedLength = 16`), `xor()` will fail for any input that is larger than `2**16`. You can find more details about the implementation in the [Mina book](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#xor-1) #### Parameters • **a**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to compare. • **b**: [`Field`](../classes/Field.mdx) [Field](Field.mdx) element to compare. • **length**: `number` amount of bits to compare. #### Returns [`Field`](../classes/Field.mdx) #### Throws Throws an error if the input values exceed `2^paddedLength - 1`. #### Example ```ts let a = Field(0b0101); let b = Field(0b0011); let c = Gadgets.xor(a, b, 4); // xor-ing 4 bits c.assertEquals(0b0110); ``` ## Source [lib/provable/gadgets/gadgets.ts:39](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/gadgets/gadgets.ts#L39) --- url: /zkapps/o1js-reference/variables/Group --- ```ts const Group: typeof Group & (...args: [{ "x": | string | number | bigint | FieldVar | Field; "y": | string | number | bigint | FieldVar | Field; }]) => Group; ``` An element of a Group. ## Source [lib/provable/wrapped.ts:76](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/wrapped.ts#L76) --- url: /zkapps/o1js-reference/variables/Hash --- ```ts const Hash: { "BLAKE2B": { "hash": Bytes; }; "Keccak256": { "hash": Bytes; }; "Keccak384": { "hash": Bytes; }; "Keccak512": { "hash": Bytes; }; "Poseidon": { "Sponge": typeof Sponge; "Unsafe": { "hashToGroup": Group; }; "hash": Field; "hashPacked": Field; "hashToGroup": Group; "hashWithPrefix": Field; "initialState": [Field, Field, Field]; "update": [Field, Field, Field]; }; "SHA2_256": { "hash": Gadgets.SHA256.hash; }; "SHA3_256": { "hash": Bytes; }; "SHA3_384": { "hash": Bytes; }; "SHA3_512": { "hash": Bytes; }; "hash": Poseidon.hash; }; ``` A collection of hash functions which can be used in provable code. ## Type declaration ### BLAKE2B ```ts BLAKE2B: { "hash": Bytes; }; ``` ### BLAKE2B.hash() #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### Keccak256 ```ts Keccak256: { "hash": Bytes; }; ``` The pre-NIST Keccak hash function with an output length of 256 bits. ### Keccak256.hash() Hashes the given bytes using Keccak-256. This is an alias for `Keccak.preNist(256, bytes)`.\ See Keccak.preNist for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### Keccak384 ```ts Keccak384: { "hash": Bytes; }; ``` The pre-NIST Keccak hash function with an output length of 384 bits. ### Keccak384.hash() Hashes the given bytes using Keccak-384. This is an alias for `Keccak.preNist(384, bytes)`.\ See Keccak.preNist for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### Keccak512 ```ts Keccak512: { "hash": Bytes; }; ``` The pre-NIST Keccak hash function with an output length of 512 bits. ### Keccak512.hash() Hashes the given bytes using Keccak-512. This is an alias for `Keccak.preNist(512, bytes)`.\ See Keccak.preNist for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### Poseidon ```ts Poseidon: { "Sponge": typeof Sponge; "Unsafe": { "hashToGroup": Group; }; "hash": Field; "hashPacked": Field; "hashToGroup": Group; "hashWithPrefix": Field; "initialState": [Field, Field, Field]; "update": [Field, Field, Field]; }; ``` ### Poseidon.Sponge ```ts Sponge: typeof Sponge; ``` ### Poseidon.Unsafe ```ts Unsafe: { "hashToGroup": Group; }; ``` ### Poseidon.Unsafe.hashToGroup() Low-level version of `Poseidon.hashToGroup()`. **Warning**: This function is marked unsafe because its output is not deterministic. It returns the square root of a value without constraining which of the two possible square roots is chosen. This allows the prover to choose between two different hashes, which can be a vulnerability if consuming code treats the output as unique. #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Group`](../classes/Group.mdx) ### Poseidon.hash() #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Field`](../classes/Field.mdx) ### Poseidon.hashPacked() Hashes a provable type efficiently. ```ts let skHash = Poseidon.hashPacked(PrivateKey, secretKey); ``` Note: Instead of just doing `Poseidon.hash(value.toFields())`, this uses the `toInput()` method on the provable type to pack the input into as few field elements as possible. This saves constraints because packing has a much lower per-field element cost than hashing. #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<`Hashable`\<`T`\>\> • **value**: `T` #### Returns [`Field`](../classes/Field.mdx) ### Poseidon.hashToGroup() Hashes a list of field elements to a point on the Pallas curve. The output point is deterministic and its discrete log is not efficiently computable. #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Group`](../classes/Group.mdx) ### Poseidon.hashWithPrefix() #### Parameters • **prefix**: `string` • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Field`](../classes/Field.mdx) ### Poseidon.initialState() #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] ### Poseidon.update() #### Parameters • **state**: [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] ### SHA2\_256 ```ts SHA2_256: { "hash": Gadgets.SHA256.hash; }; ``` The SHA2 hash function with an output length of 256 bits. ### SHA2\_256.hash() ```ts hash: (data: FlexibleBytes) => Bytes = Gadgets.SHA256.hash; ``` Hashes the given bytes using SHA2-256. This is an alias for `Gadgets.SHA256.hash(bytes)`.\ See Gadgets.SHA256.hash for details and usage examples. #### Parameters • **data**: `FlexibleBytes` #### Returns `Bytes` ### SHA3\_256 ```ts SHA3_256: { "hash": Bytes; }; ``` The SHA3 hash function with an output length of 256 bits. ### SHA3\_256.hash() Hashes the given bytes using SHA3-256. This is an alias for `Keccak.nistSha3(256, bytes)`.\ See Keccak.nistSha3 for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### SHA3\_384 ```ts SHA3_384: { "hash": Bytes; }; ``` The SHA3 hash function with an output length of 384 bits. ### SHA3\_384.hash() Hashes the given bytes using SHA3-384. This is an alias for `Keccak.nistSha3(384, bytes)`.\ See Keccak.nistSha3 for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### SHA3\_512 ```ts SHA3_512: { "hash": Bytes; }; ``` The SHA3 hash function with an output length of 512 bits. ### SHA3\_512.hash() Hashes the given bytes using SHA3-512. This is an alias for `Keccak.nistSha3(512, bytes)`.\ See Keccak.nistSha3 for details and usage examples. #### Parameters • **bytes**: `Bytes` #### Returns `Bytes` ### hash() ```ts hash: (input: Field[]) => Field = Poseidon.hash; ``` Hashes the given field elements using [Poseidon](https://eprint.iacr.org/2019/458.pdf). Alias for `Poseidon.hash()`. ```ts let hash = Hash.hash([a, b, c]); ``` **Important:** This is by far the most efficient hash function o1js has available in provable code. Use it by default, if no compatibility concerns require you to use a different hash function. The Poseidon implementation operates over the native [Pallas base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) and uses parameters generated specifically for the [Mina](https://minaprotocol.com) blockchain. We use a `rate` of 2, which means that 2 field elements are hashed per permutation. A permutation causes 11 rows in the constraint system. You can find the full set of Poseidon parameters [here](https://github.com/o1-labs/o1js-bindings/blob/main/crypto/constants.ts). #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Field`](../classes/Field.mdx) ## Source [lib/provable/crypto/hash.ts:11](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/hash.ts#L11) --- url: /zkapps/o1js-reference/variables/Keccak --- ```ts const Keccak: { "ethereum": Bytes; "nistSha3": Bytes; "preNist": Bytes; }; ``` ## Type declaration ### ethereum() Ethereum-Compatible Keccak-256 Hash Function. This is a specialized variant of Keccak.preNist configured for a 256-bit output length. Primarily used in Ethereum for hashing transactions, messages, and other types of payloads. The function accepts [Bytes](../functions/Bytes.mdx) as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using Gadgets.rangeCheck8). Alternatively, you can pass plain `number[]` of `Uint8Array` to perform a hash outside provable code. Produces an output of [Bytes](../functions/Bytes.mdx) of length 32. Both input and output bytes are big-endian. #### Parameters • **message**: `FlexibleBytes` Big-endian [Bytes](../functions/Bytes.mdx) representing the message to hash. ```ts let preimage = Bytes.fromString("hello world"); let digest = Keccak.ethereum(preimage); ``` #### Returns `Bytes` ### nistSha3() Implementation of [NIST SHA-3](https://csrc.nist.gov/pubs/fips/202/final) Hash Function. Supports output lengths of 256, 384, or 512 bits. Applies the SHA-3 hash function to a list of big-endian byte-sized [Field](../classes/Field.mdx) elements, flexible to handle varying output lengths (256, 384, 512 bits) as specified. The function accepts [Bytes](../functions/Bytes.mdx) as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using Gadgets.rangeCheck8). Alternatively, you can pass plain `number[]` of `Uint8Array` to perform a hash outside provable code. Produces an output of [Bytes](../functions/Bytes.mdx) that conforms to the chosen bit length. Both input and output bytes are big-endian. #### Parameters • **len**: `256` \| `384` \| `512` Desired output length in bits. Valid options: 256, 384, 512. • **message**: `FlexibleBytes` Big-endian [Bytes](../functions/Bytes.mdx) representing the message to hash. ```ts let preimage = Bytes.fromString("hello world"); let digest256 = Keccak.nistSha3(256, preimage); let digest384 = Keccak.nistSha3(384, preimage); let digest512 = Keccak.nistSha3(512, preimage); ``` #### Returns `Bytes` ### preNist() Implementation of [pre-NIST Keccak](https://keccak.team/keccak.html) hash function. Supports output lengths of 256, 384, or 512 bits. Keccak won the SHA-3 competition and was slightly altered before being standardized as SHA-3 by NIST in 2015. This variant was used in Ethereum before the NIST standardization, by specifying `len` as 256 bits you can obtain the same hash function as used by Ethereum Keccak.ethereum. The function applies the pre-NIST Keccak hash function to a list of byte-sized [Field](../classes/Field.mdx) elements and is flexible to handle varying output lengths (256, 384, 512 bits) as specified. Keccak.preNist accepts [Bytes](../functions/Bytes.mdx) as the input message, which is a type that represents a static-length list of byte-sized field elements (range-checked using Gadgets.rangeCheck8). Alternatively, you can pass plain `number[]` of `Uint8Array` to perform a hash outside provable code. Produces an output of [Bytes](../functions/Bytes.mdx) that conforms to the chosen bit length. Both input and output bytes are big-endian. #### Parameters • **len**: `256` \| `384` \| `512` Desired output length in bits. Valid options: 256, 384, 512. • **message**: `FlexibleBytes` Big-endian [Bytes](../functions/Bytes.mdx) representing the message to hash. ```ts let preimage = Bytes.fromString("hello world"); let digest256 = Keccak.preNist(256, preimage); let digest384 = Keccak.preNist(384, preimage); let digest512= Keccak.preNist(512, preimage); ``` #### Returns `Bytes` ## Source [lib/provable/crypto/keccak.ts:11](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/keccak.ts#L11) --- url: /zkapps/o1js-reference/variables/Permissions --- ```ts Permissions: { "VerificationKey": { "impossibleDuringCurrentVersion": () => VerificationKeyPermission; "none": () => VerificationKeyPermission; "proofDuringCurrentVersion": () => VerificationKeyPermission; "proofOrSignature": () => VerificationKeyPermission; "signature": () => VerificationKeyPermission; }; "allImpossible": () => Permissions; "default": () => Permissions; "dummy": () => Permissions; "fromJSON": (permissions: {}) => Permissions; "fromString": (permission: AuthRequired) => AuthRequired; "impossible": () => AuthRequired; "initial": () => Permissions; "none": () => AuthRequired; "proof": () => AuthRequired; "proofOrSignature": () => AuthRequired; "signature": () => AuthRequired; }; ``` ## Type declaration ### VerificationKey ```ts VerificationKey: { "impossibleDuringCurrentVersion": () => VerificationKeyPermission; "none": () => VerificationKeyPermission; "proofDuringCurrentVersion": () => VerificationKeyPermission; "proofOrSignature": () => VerificationKeyPermission; "signature": () => VerificationKeyPermission; }; ``` Special Verification key permissions. The difference to normal permissions is that `Permission.proof` and `Permission.impossible` are replaced by less restrictive permissions: - `impossible` is replaced by `impossibleDuringCurrentVersion` - `proof` is replaced by `proofDuringCurrentVersion` The issue is that a future hardfork which changes the proof system could mean that old verification keys can no longer be used to verify proofs in the new proof system, and the zkApp would have to be redeployed to adapt the verification key. Having either `impossible` or `proof` would mean that these zkApps can't be upgraded after this hypothetical hardfork, and would become unusable. Such a future hardfork would manifest as an increment in the "transaction version" of zkApps, which you can check with (). The `impossibleDuringCurrentVersion` and `proofDuringCurrentVersion` have an additional `txnVersion` field. These permissions follow the same semantics of not upgradable, or only upgradable with proofs, _as long as_ the current transaction version is the same as the one on the permission. Once the current transaction version is higher than the one on the permission, the permission is treated as `signature`, and the zkApp can be redeployed with a signature of the original account owner. ### VerificationKey.impossibleDuringCurrentVersion() ```ts impossibleDuringCurrentVersion: () => VerificationKeyPermission; ``` Modification is impossible, as long as the network accepts the current [TransactionVersion](TransactionVersion.mdx). After a hardfork that increments the transaction version, the permission is treated as `signature`. #### Returns `VerificationKeyPermission` ### VerificationKey.none() ```ts none: () => VerificationKeyPermission; ``` Modification is always permitted #### Returns `VerificationKeyPermission` ### VerificationKey.proofDuringCurrentVersion() ```ts proofDuringCurrentVersion: () => VerificationKeyPermission; ``` Modification is permitted by zkapp proofs only; as long as the network accepts the current [TransactionVersion](TransactionVersion.mdx). After a hardfork that increments the transaction version, the permission is treated as `signature`. #### Returns `VerificationKeyPermission` ### VerificationKey.proofOrSignature() ```ts proofOrSignature: () => VerificationKeyPermission; ``` Modification is permitted by zkapp proofs or signatures #### Returns `VerificationKeyPermission` ### VerificationKey.signature() ```ts signature: () => VerificationKeyPermission; ``` Modification is permitted by signatures only, using the private key of the zkapp account #### Returns `VerificationKeyPermission` ### allImpossible() ```ts allImpossible: () => Permissions; ``` #### Returns [`Permissions`](../interfaces/Permissions.mdx) ### default() ```ts default: () => Permissions; ``` Default permissions are: [Permissions.editState](../interfaces/Permissions.mdx#editstate) = Permission.proof [Permissions.send](../interfaces/Permissions.mdx#send) = Permission.signature [Permissions.receive](../interfaces/Permissions.mdx#receive) = Permission.none [Permissions.setDelegate](../interfaces/Permissions.mdx#setdelegate) = Permission.signature [Permissions.setPermissions](../interfaces/Permissions.mdx#setpermissions) = Permission.signature [Permissions.setVerificationKey](../interfaces/Permissions.mdx#setverificationkey) = Permission.signature [Permissions.setZkappUri](../interfaces/Permissions.mdx#setzkappuri) = Permission.signature [Permissions.editActionState](../interfaces/Permissions.mdx#editactionstate) = Permission.proof [Permissions.setTokenSymbol](../interfaces/Permissions.mdx#settokensymbol) = Permission.signature #### Returns [`Permissions`](../interfaces/Permissions.mdx) ### dummy() ```ts dummy: () => Permissions; ``` #### Returns [`Permissions`](../interfaces/Permissions.mdx) ### fromJSON() ```ts fromJSON: (permissions: {}) => Permissions; ``` #### Parameters • **permissions** #### Returns [`Permissions`](../interfaces/Permissions.mdx) ### fromString() ```ts fromString: (permission: AuthRequired) => AuthRequired; ``` #### Parameters • **permission**: `AuthRequired` #### Returns `AuthRequired` ### impossible() ```ts impossible: () => AuthRequired; ``` Modification is impossible. #### Returns `AuthRequired` ### initial() ```ts initial: () => Permissions; ``` #### Returns [`Permissions`](../interfaces/Permissions.mdx) ### none() ```ts none: () => AuthRequired; ``` Modification is always permitted #### Returns `AuthRequired` ### proof() ```ts proof: () => AuthRequired; ``` Modification is permitted by zkapp proofs only #### Returns `AuthRequired` ### proofOrSignature() ```ts proofOrSignature: () => AuthRequired; ``` Modification is permitted by zkapp proofs or signatures #### Returns `AuthRequired` ### signature() ```ts signature: () => AuthRequired; ``` Modification is permitted by signatures only, using the private key of the zkapp account #### Returns `AuthRequired` ## Source [lib/mina/account-update.ts:327](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L327) --- url: /zkapps/o1js-reference/variables/Poseidon --- ```ts const Poseidon: { "Sponge": typeof Sponge; "Unsafe": { "hashToGroup": Group; }; "hash": Field; "hashPacked": Field; "hashToGroup": Group; "hashWithPrefix": Field; "initialState": [Field, Field, Field]; "update": [Field, Field, Field]; }; ``` ## Type declaration ### Sponge ```ts Sponge: typeof Sponge; ``` ### Unsafe ```ts Unsafe: { "hashToGroup": Group; }; ``` ### Unsafe.hashToGroup() Low-level version of `Poseidon.hashToGroup()`. **Warning**: This function is marked unsafe because its output is not deterministic. It returns the square root of a value without constraining which of the two possible square roots is chosen. This allows the prover to choose between two different hashes, which can be a vulnerability if consuming code treats the output as unique. #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Group`](../classes/Group.mdx) ### hash() #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Field`](../classes/Field.mdx) ### hashPacked() Hashes a provable type efficiently. ```ts let skHash = Poseidon.hashPacked(PrivateKey, secretKey); ``` Note: Instead of just doing `Poseidon.hash(value.toFields())`, this uses the `toInput()` method on the provable type to pack the input into as few field elements as possible. This saves constraints because packing has a much lower per-field element cost than hashing. #### Type parameters • **T** #### Parameters • **type**: [`WithProvable`](../type-aliases/WithProvable.mdx)\<`Hashable`\<`T`\>\> • **value**: `T` #### Returns [`Field`](../classes/Field.mdx) ### hashToGroup() Hashes a list of field elements to a point on the Pallas curve. The output point is deterministic and its discrete log is not efficiently computable. #### Parameters • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Group`](../classes/Group.mdx) ### hashWithPrefix() #### Parameters • **prefix**: `string` • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [`Field`](../classes/Field.mdx) ### initialState() #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] ### update() #### Parameters • **state**: [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] • **input**: [`Field`](../classes/Field.mdx)[] #### Returns [[`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx), [`Field`](../classes/Field.mdx)] ## Source [lib/provable/crypto/poseidon.ts:56](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/crypto/poseidon.ts#L56) --- url: /zkapps/o1js-reference/variables/ProvableType --- ```ts ProvableType: { "get": ToProvable; "synthesize": T; }; ``` ## Type declaration ### get() #### Type parameters • **A** *extends* `unknown` #### Parameters • **type**: `A` #### Returns [`ToProvable`](../type-aliases/ToProvable.mdx)\<`A`\> ### synthesize() Create some value of type `T` from its provable type description. #### Type parameters • **T** #### Parameters • **type**: [`ProvableType`](../type-aliases/ProvableType.mdx)\<`T`, `any`\> #### Returns `T` ## Source [lib/provable/types/provable-intf.ts:132](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/types/provable-intf.ts#L132) --- url: /zkapps/o1js-reference/variables/TokenId --- ```ts const TokenId: { "default": Field; "derive": Field; "fromBase58": Field; "toBase58": string; }; ``` ## Type declaration ### default ```ts default: Field; ``` ### derive() #### Parameters • **tokenOwner**: [`PublicKey`](../classes/PublicKey.mdx) • **parentTokenId**: [`Field`](../classes/Field.mdx)= `undefined` #### Returns [`Field`](../classes/Field.mdx) ### fromBase58() #### Parameters • **base58**: `string` #### Returns [`Field`](../classes/Field.mdx) ### toBase58() #### Parameters • **t**: [`Field`](../classes/Field.mdx) #### Returns `string` ## Source [lib/mina/account-update.ts:666](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L666) --- url: /zkapps/o1js-reference/variables/TransactionVersion --- ```ts const TransactionVersion: { "current": () => UInt32; }; ``` ## Type declaration ### current() ```ts current: () => UInt32; ``` #### Returns [`UInt32`](../classes/UInt32.mdx) ## Source [lib/mina/account-update.ts:119](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L119) --- url: /zkapps/o1js-reference/variables/TupleN --- ```ts TupleN: { "fromArray": TupleN; "hasLength": tuple is TupleN; "map": [...{ [i in string | number | symbol]: B }[]]; }; ``` ## Type declaration ### fromArray() #### Type parameters • **T** • **N** *extends* `number` #### Parameters • **n**: `N` • **arr**: `T`[] #### Returns [`TupleN`](../type-aliases/TupleN.mdx)\<`T`, `N`\> ### hasLength() #### Type parameters • **T** • **N** *extends* `number` #### Parameters • **n**: `N` • **tuple**: `T`[] #### Returns `tuple is TupleN` ### map() #### Type parameters • **T** *extends* `Tuple`\<`any`\> • **B** #### Parameters • **tuple**: `T` • **f** #### Returns [...\{ [i in string \| number \| symbol]: B \}[]] ## Source [lib/util/types.ts:28](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/util/types.ts#L28) --- url: /zkapps/o1js-reference/variables/Undefined --- ```ts Undefined: ProvablePureExtended; ``` ## Source [lib/proof-system/zkprogram.ts:82](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L82) --- url: /zkapps/o1js-reference/variables/Void --- ```ts Void: ProvablePureExtended; ``` ## Source [lib/proof-system/zkprogram.ts:87](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/proof-system/zkprogram.ts#L87) --- url: /zkapps/o1js-reference/variables/ZkappPublicInput --- ```ts ZkappPublicInput: ProvablePureExtended<{ "accountUpdate": Field; "calls": Field; }, { "accountUpdate": Field; "calls": Field; }, { "accountUpdate": Field; "calls": Field; }>; ``` ## Type declaration ### accountUpdate ```ts accountUpdate: Field = Field; ``` ### calls ```ts calls: Field = Field; ``` ## Source [lib/mina/account-update.ts:2050](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/mina/account-update.ts#L2050) --- url: /zkapps/o1js-reference/variables/emptyHash --- ```ts const emptyHash: Field; ``` ## Source [lib/provable/merkle-list.ts:24](https://github.com/o1-labs/o1js/blob/6ebbc23710f6de023fea6d83dc93c5a914c571f2/src/lib/provable/merkle-list.ts#L24) --- url: /zkapps/o1js/basic-concepts --- # o1js Basic Concepts o1js is a TypeScript (TS) library for writing general-purpose zero knowledge (zk) programs and writing zk smart contracts for Mina. ## Field Field elements are the basic unit of data in zero knowledge proof programming. Each field element can store a number up to almost 256 bits in size. You can think of a field element as a `uint256` in Solidity. :::note For the cryptography inclined, the exact max value that a field can store is: 28,948,022,309,329,048,855,892,746,252,171,976,963,363,056,481,941,560,715,954,676,764,349,967,630,336. ::: For example, in typical programming, you might use: `const sum = 1 + 3`. In o1js, you write this as: `const sum = new Field(1).add(new Field(3))` This can be simplified as: `const sum = new Field(1).add(3)` Note that the `3` is auto-promoted to a field type to make this cleaner. ## Built-in data types Some common data types you may use are: ```ts new Bool(x); // accepts true or false new Field(x); // accepts an integer, or a numeric string if you want to represent a number greater than JavaScript can represent but within the max value that a field can store. new UInt64(x); // accepts a Field - useful for constraining numbers to 64 bits new UInt32(x); // accepts a Field - useful for constraining numbers to 32 bits PrivateKey, PublicKey, Signature; // useful for accounts and signing new Group(x, y); // a point on our elliptic curve, accepts two Fields/numbers/strings Scalar; // the corresponding scalar field (different than Field) CircuitString.from('some string'); // string of max length 128 ``` In the case of `Field` and `Bool`, you can also call the constructor without `new`: ```ts let x = Field(10); let b = Bool(true); ``` ## Conditionals Traditional conditional statements are not supported by o1js: ```ts // this will NOT work if (foo) { x.assertEquals(y); } ``` Instead, use the o1js built-in `Circuit.if()` method, which is a ternary operator: ```ts const x = Circuit.if(new Bool(foo), a, b); // behaves like `foo ? a : b` ``` ## Functions Functions work as you would expect in TypeScript. For example: ```ts function addOneAndDouble(x: Field): Field { return x.add(1).mul(2); } ``` ## Common methods Some frequently used common methods are: ```ts let x = new Field(4); // x = 4 x = x.add(3); // x = 7 x = x.sub(1); // x = 6 x = x.mul(3); // x = 18 x = x.div(2); // x = 9 x = x.square(); // x = 81 x = x.sqrt(); // x = -9 let b = x.equals(8); // b = Bool(false) b = x.greaterThan(8); // b = Bool(true) b = b.not().or(b).and(b); // b = Bool(true) b.toBoolean(); // true let hash = Poseidon.hash([x]); // takes array of Fields, returns Field let privKey = PrivateKey.random(); // create a private key let pubKey = PublicKey.fromPrivateKey(privKey); // derive public key let msg = [hash]; let sig = Signature.create(privKey, msg); // sign a message sig.verify(pubKey, msg); // Bool(true) ``` For a full list, see the [o1js reference](../o1js-reference). --- url: /zkapps/o1js/bitwise-operations --- # Bitwise Operations Bitwise operations manipulate individual bits within a binary representation of a number. They can, at times, resemble boolean operations but apply to a sequence of bits instead of booleans. Bitwise operations are generally available in most programming languages, including TypeScript. o1js provides versions of them that operate on `Field` elements and result in the necessary circuit constraints to generate a zero knowledge proof of the computation. This is especially useful when implementing hashing algorithms such as SHA256. In o1js, bitwise operations and their attendant helper functions are implemented as [gadgets](/zkapps/o1js/gadgets). Bitwise operations: - [and()](#and) - [not()](#not) - [xor()](#xor) - [leftShift32()](#leftshift32) - [leftShift64()](#leftshift64) - [rightShift64()](#rightshift64) - [rotate32()](#rotate32) - [rotate64()](#rotate64) Helper functions: - [addMod32()](#addmod32) - [divMod32()](#divmod32) - [rangeCheck32()](#rangecheck32) - [rangeCheck64()](#rangecheck64) - [multiRangeCheck()](#multirangecheck) - [compactMultiRangeCheck()](#compactmultirangecheck) ## and() ```ts and(a: Field, b: Field, length: number) => Field ``` The bitwise `and()` gadget is a provable equivalent to the [bitwise AND (&)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND) operator in JavaScript. It receives two `Field` elements and compares the corresponding pairs of bits from the binary representation of each. The comparison returns 1 only if both bits are 1 and returns 0 if either bit is not 1. This results in a new binary number, which is returned as a `Field` element. For details about the implementation, see [AND](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#and) in the Mina book. The `length` parameter: - Specifies how many bits to compare. - Adds more constraints for larger numbers. Example: ```ts let a = Field(3); // ... 000011 let b = Field(5); // ... 000101 let c = Gadgets.and(a, b, 2); // ... 000001 c.assertEquals(1); ``` ## not() ```ts not(a: Field, length: number, checked: boolean) => Field ``` The bitwise `not()` gadget is a provable equivalent to the [Bitwise NOT (~)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT) operator in JavaScript. It receives a `Field` element and negates each bit of its binary representation, turning all the 1s into 0s and all the 0s into 1s. It essentially flips all the bits in a `Field` element. This results in a new binary number, which is returned as a `Field` element. The implementation varies depending on whether the input length is checked. Not checking the input length is more efficient. The input is subtracted from an all-ones bitmask (where all the bits in a binary sequence are set to 1). The tradeoff is that you need to know the input length up front. This is safe when the input `Field` is the result of some other proven operation with a known output length. When the input length is checked, however, the [xor()](#xor) gadget is reused. An all-ones bitmask of equal length to the input `Field` is supplied as the second argument. This results in the same operation with proven input length and more constraints. The input `Field` must be 254 bits or less. The `length` parameter: - Specifies how many bits to negate. - Adds more constraints for larger numbers. The `checked` parameter: - Specifies whether to check the length of the input. - Defaults to `false`. For details about the implementation, see [NOT](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#not) in the Mina book. Example: ```ts let a = Field(0b0101); let b = Gadgets.not(a,4,true); b.assertEquals(0b1010); ``` ## xor() ```ts xor(a: Field, b: Field, length: number) => Field ``` The `xor()` gadget is a provable equivalent to the [Bitwise XOR (^)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR) operator in JavaScript. It receives two `Field` elements and compares the corresponding pairs of bits from the binary representation of each. The comparison returns 1 if the bits differ and 0 if they are the same. This results in a new binary number, which is returned as a `Field` element. The `length` parameter: - Specifies how many bits to compare. - Adds more constraints for larger numbers. For details about the implementation, see [XOR](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#xor-1) in the Mina book. Example: ```ts let a = Field(0b0101); let b = Field(0b0011); let c = Gadgets.xor(a, b, 4); // xor-ing 4 bits c.assertEquals(0b0110); ``` ## leftShift32() ```ts leftShift32(field: Field, bits: number) => Field ``` The `leftShift32()` gadget is a provable equivalent to the [Left shift (<<)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift) operator in JavaScript. It moves the bits of a binary number to the left by the specified number of `bits`. Any bits that fall off the left side are discarded. 0s are padded in from the right. It returns a new `Field` element that is range-checked to 32 bits. The input `Field` must not exceed 32 bits in size. You can use [rangeCheck32](#rangecheck32) to ensure this. Example: ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.leftShift32(x, 2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary ``` ## leftShift64() ```ts leftShift64(field: Field, bits: number) => Field ``` The `leftShift64()` gadget is a provable equivalent to the [Left shift (<<)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift) operator in JavaScript. It moves the bits of a binary number to the left by the specified number of `bits`. Any bits that fall off the left side are discarded. 0s are padded in from the right. It returns a new `Field` element that is range-checked to 64 bits. The input `Field` must not exceed 64 bits in size. You can use [rangeCheck64](#rangecheck64) to ensure this. Example: ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.leftShift64(x, 2); // left shift by 2 bits y.assertEquals(0b110000); // 48 in binary const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.leftShift64(xLarge, 32); // throws an error since input exceeds 64 bits ``` ## rightShift64() ```ts rightShift64(field: Field, bits: number) => Field ``` The `rightShift64()` gadget is a provable equivalent to the [Right shift (>>)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift) operator in JavaScript. It moves the bits of a binary number to the right by the specified number of `bits`. Any bits that fall off the right side are discarded. 0s are padded in from the left. It returns a new `Field` element. The input `Field` must not exceed 64 bits in size. You can use [rangeCheck64](#rangecheck64) to ensure this. Example: ```ts const x = Provable.witness(Field, () => Field(0b001100)); // 12 in binary const y = Gadgets.rightShift64(x, 2); // right shift by 2 bits y.assertEquals(0b000011); // 3 in binary const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rightShift64(xLarge, 32); // throws an error since input exceeds 64 bits ``` ## rotate32() ```ts rotate32(field: Field, bits: number, direction: 'left' | 'right' = 'left') { return rotate32(field, bits, direction); }, ``` The `rotate32()` gadget performs provable bit rotation on 32-bit numbers. It is similar to left shift and right shift, except the bits that fall off the end wrap around to reappear on the opposite side instead of being discarded. It accepts a `Field` element, the number of `bits` to rotate, and a `direction` of left or right. The default direction is left. The input `Field` must not exceed 32 bits in size. You can use [rangeCheck32](#rangecheck32) to ensure this. For implementation details, see [ROTATION](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#rotation) in the Mina book. Example: ```ts const x = Provable.witness(Field, () => Field(0b001100)); const y = Gadgets.rotate32(x, 2, 'left'); // left rotation by 2 bits const z = Gadgets.rotate32(x, 2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rotate32(xLarge, 32, "left"); // throws an error since input exceeds 32 bits ``` ## rotate64() ```ts rotate64(field: Field, bits: number, direction: 'left' | 'right' = 'left') { return rotate64(field, bits, direction); }, ``` The `rotate64()` gadget performs provable bit rotation on 32-bit numbers. It is similar to left shift and right shift, except the bits that fall off the end wrap around to reappear on the opposite side instead of being discarded. It accepts a `Field` element, the number of `bits` to rotate, and a `direction` of left or right. The default direction is left. The input `Field` must not exceed 64 bits in size. You can use [rangeCheck64](#rangecheck64) to ensure this. For implementation details, see [ROTATION](https://o1-labs.github.io/proof-systems/specs/kimchi.html?highlight=gates#rotation) in the Mina book. Example: ```ts const x = Provable.witness(Field, () => Field(0b001100)); const y = Gadgets.rotate64(x, 2, 'left'); // left rotation by 2 bits const z = Gadgets.rotate64(x, 2, 'right'); // right rotation by 2 bits y.assertEquals(0b110000); z.assertEquals(0b000011); const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rotate64(xLarge, 32, "left"); // throws an error since input exceeds 64 bits ``` ## addMod32() ```ts addMod32(a: Field, b: Field) => Field ``` The `addMod32()` helper performs addition that overflows on 32-bit numbers, much like the `int32` type. It returns the result of addition modulo `2^32` in a new `Field` element. The input `Field`s must not exceed 32 bits in size. You can use [rangeCheck32](#rangecheck32) to ensure this. Example: ```ts let a = Field(8n); let b = Field(1n << 32n); Gadgets.addMod32(a, b).assertEquals(Field(8n)); ``` ## divMod32() ```ts divMod32(field: Field) => { remainder: Field, quotient: Field } ``` The `divMod32()` helper performs division modulo `2^32`, decomposing a `Field` element into two 32-bit limbs, `remainder` and `quotient`. It returns a tuple of two `Field` elements. The helper asserts that the input is no larger than 64 bits in size and that both outputs are no larger than 32 bits in size. It is, therefore, unnecessary to perform range checks. Example: ```ts let n = Field((1n << 32n) + 8n) let { remainder, quotient } = Gadgets.divMod32(n); // remainder = 8, quotient = 1 n.assertEquals(quotient.mul(1n << 32n).add(remainder)); ``` ## rangeCheck32() ```ts rangeCheck32(x: Field) => void ``` The `rangecheck32()` helper asserts that the input `Field` does not exceed 32 bits in size. Note that small, negative inputs are interpreted as large integers close to the field size and will not pass the 32-bit check. To prove that a value lies in the int32 range `[-2^31, 2^31)`, you can use `rangeCheck32(x.add(1n << 31n))`. Example: ```ts const x = Provable.witness(Field, () => Field(12345678n)); Gadgets.rangeCheck32(x); // successfully proves 32-bit range const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rangeCheck32(xLarge); // throws an error since input exceeds 32 bits ``` ## rangeCheck64() ```ts rangeCheck64(x: Field) => void ``` The `rangecheck64()` helper asserts that the input `Field` does not exceed 64 bits in size. Note that small, negative inputs are interpreted as large integers close to the field size and will not pass the 64-bit check. To prove that a value lies in the int64 range `[-2^63, 2^63)`, use `rangeCheck64(x.add(1n << 63n))`. Example: ```ts const x = Provable.witness(Field, () => Field(12345678n)); Gadgets.rangeCheck64(x); // successfully proves 64-bit range const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.rangeCheck64(xLarge); // throws an error since input exceeds 64 bits ``` ## multiRangeCheck() ```ts multiRangeCheck([x, y, z]: [Field, Field, Field]) => void ``` The `multiRangeCheck()` helper asserts that all three input `Field`s do not exceed 88 bits in size. This is done more efficiently than the standalone range check helpers. The 3x88-bit range check supports BigInts up to 264 bits, which is enough for foreign field multiplication with moduli up to 2^259. Example: ```ts const x = Provable.witness(Field, () => Field(12345678n)); const y = Provable.witness(Field, () => Field(12345678n)); const z = Provable.witness(Field, () => Field(12345678n)); const xLarge = Provable.witness(Field, () => Field(12345678901234567890123456789012345678n)); Gadgets.multiRangeCheck([x, y, z]); // succeeds Gadgets.multiRangeCheck([xLarge, y, z]); // fails ``` ## compactMultiRangeCheck() ```ts compactMultiRangeCheck(xy: Field, z: Field) => [Field, Field, Field]; ``` The `compactMultiRangeCheck()` helper is a variant of [multiRangeCheck](#multirangecheck) where the first two inputs `x` and `y` are passed in combined form `xy = x + 2^88*y`. It splits `x` and `y`, performs the range check, and returns `x`, `y`, and `z` separately. Example: ```ts let [x, y, z] = Gadgets.compactMultiRangeCheck([xy, z]); ``` --- url: /zkapps/o1js/circuit-writing-primer --- # Overview of the circuit-writing features in o1js o1js is a library for writing zk circuits in TypeScript. While many high-level features are abstracted away from the circuit level, this article will focus specifically on the tools that are specific to the unique nature of writing circuits. ## What even is a zk circuit? For our purposes, you can think of a zk circuit as a set of gates, which we can give an input and produce a deterministic output. We can prove the correct output of the circuit without revealing the inputs. o1js produces `kimchi` proofs. Kimchi is defined in detail in the [Mina Book](https://o1-labs.github.io/proof-systems/specs/kimchi.html), including specifications for each type of gate that is supported. Generally speaking, each type of gate represents a specific algebraic expression, and the values in the row represent coeffecients of that expression. ## What are the implications of writing a circuit? One of the challenges when approaching circuit-writing is understanding how the nature of a circuit differs from most common programming paradigms. There is no equivalent to `JUMP` or `GOTO` in a circuit. The implication of this for the developer is there is no way to branch or dynamically loop in o1js. There are some workarounds to these limitations that we will discuss, but it's important to understand the fundamental limitation. The tradeoff for these limitations is that circuits can be proven to be executed correctly. Practically all applications built with o1js should be designed with this tradeoff in mind. "How does proving correct execution of this program provide value?" is a question you should ask about any ZkApp design built with o1js. ## Witnesses In a circuit, a witness is kind of like a blank space that is purposefully left to be filled in by the prover. The size and shape of a witness must be known at the time of circuit creation, but the value does not need to be known until the prover generates a proof. It's like a function argument in Typescript, but much more strict. When you write provable code, you may explicitly create a witness of a certain type, and some classes in o1js will implicitly create witnesses for convenience. ## Understanding your circuit What do we mean when we say that o1js is used to "build a circuit"? Well, there is a complicated build process that combs through your TypeScript code and generates a set of constraints. But there is a _simple_ way to visualize the output. ### Provable.constraintSystem Circuits, aka contraint systems, can be summarized in o1js with a helper function from the `Provable` namespace. ```ts let boundCS = await Provable.constraintSystem(() => { const anyField = Provable.witness(Field, () => Field(1001)); const lowerBound = anyField.greaterThanOrEqual(1000); const upperBound = anyField.lessThanOrEqual(9999); lowerBound.and(upperBound).assertTrue(); }); console.log(boundCS); ``` ```sh rows: 56, digest: '4567a98430470b1709fab57843059246', gates: [ { type: 'Generic', wires: [Array], coeffs: [Array] }, { type: 'RangeCheck0', wires: [Array], coeffs: [Array] }, { type: 'RangeCheck0', wires: [Array], coeffs: [Array] }, { type: 'RangeCheck1', wires: [Array], coeffs: [] }, .... { type: 'Generic', wires: [Array], coeffs: [Array] }, { type: 'Generic', wires: [Array], coeffs: [Array] }, { type: 'Generic', wires: [Array], coeffs: [Array] } ], publicInputSize: 0, print: [Function: print], summary: [Function: summary] ``` You see, `Provable.constraintSystem` lets us visualize our entire circuit. When using `Provable.constraintSystem`, witnesses need to be explicitly created for any input data. This is easily verified by updating the code: ```ts let boundCS = await Provable.constraintSystem(() => { const anyField = Field(1001); const lowerBound = anyField.greaterThanOrEqual(1000); const upperBound = anyField.lessThanOrEqual(9999); lowerBound.and(upperBound).assertTrue(); }); console.log(boundCS); ``` ```sh rows: 0, digest: '4f5ddea76d29cfcfd8c595f14e31f21b', gates: [], publicInputSize: 0, print: [Function: print], summary: [Function: summary] ``` As you can see, there is no circuit this time because the input `const anyField = Field(1001);` is not explicitly witnessed in. One added benetit of checking your code with `Provable.constraintSystem` is that it can help you verify that your circuit is actually provable. Some of the common mistakes people make that result in non-provable circuits will show `0` rows and an empty `gates` array. ### analyzeMethods Both `SmartContract` and `ZkProgram` expose the method `analyzeMethods`. This is a convenience method that will go through each provable method on the defined class, and summarize the circuit that it creates. ```ts const MyProgram = ZkProgram({ name: 'MyProgram', publicInput: Field, publicOutput: Field, methods: { add: { privateInputs: [Field], method: async (publicValue: Field, privateValue: Field) => { privateValue.assertGreaterThan(10); return { publicOutput: publicValue.add(privateValue) }; }, }, mul: { privateInputs: [Field], method: async (publicValue: Field, privateValue: Field) => { return { publicOutput: publicValue.mul(privateValue) }; }, }, }, }); console.log(await MyProgram.analyzeMethods()); ``` ```sh { add: { rows: 20, digest: '4aa07dbc03b8ead435d938812ff79575', gates: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ], publicInputSize: 0, print: [Function: print], summary: [Function: summary] }, mul: { rows: 1, digest: '2a840c03f4e37242a8056a4aa536358c', gates: [ [Object] ], publicInputSize: 0, print: [Function: print], summary: [Function: summary] } } ``` With `analyzeMethods`, you see that the witnesses are created automatically by the declarative method syntax. ## Branching logic and loops ### Provable If Because we lack a `JUMP` or `GOTO` type of behavior in the proof system, traditional if statements won't work. In fact, we absolutely cannot skip _executing_ part of a function based on an if statement. Luckily, we can still set the value of a variable based on a condition using `Provable.if`. It works like this: ```ts const x = Provable.if(new Bool(true), Field(1), Field(2)); // x is always equal to Field(1) const y = Provable.if(a.greaterThan(b), Field(1), Field(2)); // y will be Field(1) if a > b, Field(2) otherwise let z = Field(0); // z will _always_ be Field(3) because both branches are executed!!! Provable.if(a.greaterThan(b), (z = z.add(Field(1))), (z = z.add(Field(2)))); ``` ### Provable Array Unbounded arrays are not possible in a circuit, so TypeScript arrays cannot be used. o1js provides an alternative, `Provable.Array`, which is a fixed-size array that can be used in a circuit. This is a very convenient tool because it allows for using loop syntax, instead of forcing the developer to repeat code. Be careful when using `Provable.Array` because the rules still apply. You can't use conditional logic to break out of a loop. So each and every iteration will occur in every proof. When dealing with an array size like 100 or more, the costs associated with iterating so many times can become expensive. ```ts const MyArray = Provable.Array(Field, 5); const MyArrayProgram = ZkProgram({ name: 'MyArrayProgram', publicOutput: Field, methods: { hash: { privateInputs: [MyArray], method: async (myArray: Field[]) => { return { publicOutput: Poseidon.hash(myArray) }; }, }, equivalent: { privateInputs: [Field, Field, Field, Field, Field], method: async (a: Field, b: Field, c: Field, d: Field, e: Field) => { return { publicOutput: Poseidon.hash([a, b, c, d, e]) }; }, }, }, }); const analysis = await MyArrayProgram.analyzeMethods(); console.log('hash: ', { rows: analysis.hash.rows, digest: analysis.hash.digest, }); console.log('equivalent: ', { rows: analysis.equivalent.rows, digest: analysis.equivalent.digest, }); ``` ```sh hash: { rows: 38, digest: 'ac5f1fd447da277f66bcbbe6f46a22f8' } equivalent: { rows: 38, digest: 'ac5f1fd447da277f66bcbbe6f46a22f8' } ``` ### What happens if I don't follow the rules? In the case of conditional logic, we _can_ still generate a valid circuit. But the circuit will ignore the branching. In these cases, the javascript will execute with a dummy value, and whatever conditional branches the dummy value goes down, that will be the circuit. If we edit the implementation of the hash method above to include a condition on the input length, it will appear to be valid... ```ts hash: { privateInputs: [MyArray], method: async (myArray: Field[]) => { if (myArray.length !== 5) { return { publicOutput: Field(0) }; } else { return { publicOutput: Poseidon.hash(myArray) }; } }, }, ``` ```sh hash: { rows: 38, digest: 'ac5f1fd447da277f66bcbbe6f46a22f8' } ``` Note that the circuit did not change at all, because even though we appear to have added a branch, the dummy value has a length of 5, so the other branch is simply discarded. If we try to call this method with an input of greather than or fewer than 5 elements, we will _not_ succeed in producing a valid proof. We will get an error for attempting to break the rules. ```ts await MyArrayProgram.compile(); const p = await MyArrayProgram.hash([Field(10)]); ``` ```sh Error: Error when witnessing in hash, argument 0: Expected witnessed values of length 5, got 1. at exists (o1js/src/lib/provable/core/exists.ts:32:11) at Object.witness (o1js/src/lib/provable/types/witness.ts:32:14) at main (o1js/src/lib/proof-system/zkprogram.ts:845:30) ``` The same intuition applies for looping a variable number of times. Instead of the witness being the wrong size, the circuit will have the wrong gates. The result is the same: the _javascript_ is valid, and may lull you into a sense of security, but you need to apply your circuit-writing knowledge to create valid programs. ## More Resources These sources heavily influenced the preceding article and go into more depth about circuits in o1js: - Check out [Mastermind at 5 Levels](https://github.com/o1-labs-XT/mastermind-zkApp) for a practical example of how to implement thees concepts to build a game. - Read Yunus' article ["Let's Prove"](https://docs.google.com/document/d/1JQPypqNc7nIRbY0c_5zHFI5TbvbCTe1neiSTPxfLmWA/edit?tab=t.0), a complete guide to o1js. --- url: /zkapps/o1js/custom-tokens --- # Custom Token API You can use o1js to perform common token operations, such as minting, burning, and sending tokens. ## Minting Minting generates new tokens whereby the zkApp updates the balance of an account by adding the newly created tokens to it. Minted tokens can be sent to any existing account in the ledger. To mint new tokens using a zkApp, this example of the `this.token` property on the `SmartContract` class shows how a zkApp can mint tokens to another account: ```ts class MintExample extends SmartContract { ... @method mintNewTokens(receiverAddress: PublicKey) { this.token.mint({ address: receiverAddress, amount: 100_000, }); } } ``` This example snippet defines a smart contract called `MintExample` with a method called `mintNewTokens`. Using `this.token`, the smart contract specifies the address to mint new tokens for as well as the amount. ## Burning Burning tokens is the opposite of minting. Burning tokens deducts the balance of a certain address by the specified amount. The following examples show how a zkApp can burn tokens of another account: ```ts class BurnExample extends SmartContract { ... @method burnTokens(addressToDecrease: PublicKey) { this.token.burn({ address: addressToDecrease, amount: 100_000, }); } } ``` This example snippet defines a smart contract called `BurnExample` with a method called `burnTokens`. Similar to minting, the `this.token` property calls the `burn()` method. This specifies the amount of tokens to burn for the specified address. A zkApp cannot burn more tokens than the specified account has. An error is thrown and no such transaction is made. ## Sending To send a custom token, use the `send()` method available on `this.token`. This example shows how a zkApp can approve sending tokens between two accounts: ```ts class SendExample extends SmartContract { ... @method sendTokens( senderAddress: PublicKey, receiverAddress: PublicKey, amount: UInt64 ) { this.token.send({ to: receiverAddress, from: senderAddress, amount, }); } } ``` This example snippet defines a smart contract called `SendExample` with a method called `sendTokens()`. Then, in the same fashion, as minting and burning, the `this.token` property calls the `send()` method. For a comprehensive example of how to use custom tokens with a zkApp, see the custom token example provided in [token.test.ts](https://github.com/o1-labs/o1js/blob/main/src/lib/token.test.ts). ## Proof Authorization When a zkApp interacts with a custom token that it did not originally create, the calling zkApp must get authorization from the [token owner](#token-owner). A token owner approves a transaction using a **proof**. ### Proof Authorization Proof authorization is a more flexible way for a token owner to approve a custom token transfer. If two separate accounts want to trade a specific custom token, the token owner can provide a proof that the transaction is valid. This allows the token owner to approve a transaction without signing it. To allow for proof authorization by the token owner, the child zkApp that is requesting authorization must provide a way for the token owner to inspect the changes it wants to make and verify that they are valid. Token owner contracts have the power to inspect child account updates to enforce custom token rules. For example, a token owner contract could enforce that a child zkApp can send tokens only to a specific address. Token owner contracts can inspect the updates that a child zkApp wants to make by using a combination of `Experimental.Callback` and `this.approve`. The first thing that a token contract must do is generate the account updates that a child zkApp wants to make. The child zkApp wraps a function around `Experimental.Callback` which contains the changes it wants to make. The token owner can then execute that function with `this.approve` and inspect the changes that the child zkApp wants to make. This example shows how a zkApp can approve a transaction between two accounts by calling a specified `SmartContract` method: ```ts /** * This TokenContract class is used to create a custom token * and acts as the token owner of the custom token */ class TokenContract extends SmartContract { ... /** * 'sendTokens()' sends tokens from `senderAddress` to `receiverAddress`. * * It does so by deducting the amount of tokens from `senderAddress` by * authorizing the deduction with a proof. It then creates the receiver * from `receiverAddress` and sends the amount. */ @method sendTokens( senderAddress: PublicKey, receiverAddress: PublicKey, amount: UInt64, callback: Experimental.Callback ) { // approves the callback which deductes the amount of tokens from the sender let senderAccountUpdate = this.approve(callback); // Create constraints for the sender account update and amount let negativeAmount = Int64.fromObject( senderAccountUpdate.body.balanceChange ); negativeAmount.assertEquals(Int64.from(amount).neg()); let tokenId = this.token.id; // Create receiver accountUpdate let receiverAccountUpdate = Experimental.createChildAccountUpdate( this.self, receiverAddress, tokenId ); receiverAccountUpdate.balance.addInPlace(amount); } } class ZkAppB extends SmartContract { /* * This method is used to get authorization from the token owner. Remember, * the token owner is the one who created the custom token. To debit their * balance, we must get authorization from the token owner */ @method approveSend(amount: UInt64) { this.balance.subInPlace(amount); } } let tx = await Local.transaction(feePayer, () => { let amount = UInt64.from(1_000) // Create a callback inside the transaction that calls the approveSend method. // This will be executed by the token owner to get authorization. let approveSendingCallback = Experimental.Callback.create( zkAppB, 'approveSend', [amount] ); // Here, we call the token contract with the callback tokenZkApp.sendTokens(zkAppBAddress, account1Address, amount, approveSendingCallback); }); await tx.prove(); tx.sign([zkAppBKey]); await tx.send(); ``` The result of this example is `zkAppB` sending tokens to `account1Address` and `account1Address` receiving tokens from `zkAppB`. The transaction is approved by the token owner without the token owner having to sign the transaction. For another example of how to approve a transaction with a zkApp, see this [authorization example](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/token_with_proofs.ts) provided. ## Understanding Important Terms If your zkApp interacts with custom tokens, be sure you understand the following essential terms: ### Token id Token ids are unique identifiers that are used to distinguish between different types of custom tokens. Custom token identifiers are globally unique across the entire network. Token ids are derived from a zkApp. To check the token id of a zkApp, use the `this.token.id` property. ### Token Accounts Token accounts are like regular accounts, but they hold a balance of a specific custom token instead of MINA. A token account is created from an existing account but is specified by a public key _and_ a token id. If an existing account receives a transaction that is specified by a custom token, a token account for that public key and token id is created if it does not exist. Token accounts are specific for each type of custom token, meaning that a single public key can have many different types of token accounts. A token account is automatically created for a public key whenever an existing account receives a transaction denoted with a custom token. When a token account is created for the first time, an account creation fee must be paid the same as creating a new standard account. In addition to sending custom tokens, a **token owner account** can mint and burn custom tokens. A token owner account is the governing zkApp account for a specific custom token. ### Token Owner A token owner is an account that creates, facilitates, and governs how a custom token is to be used. Concretely, the token owner is the account that created the custom token and is the only account that can mint and burn tokens. In addition to being the only account that can mint and burn tokens, the token owner is the only account that can approve sending tokens between two accounts. If two accounts want to send tokens to each other, the token owner must approve the transaction. The token owner generates the changes the two accounts want to make and can then make assertions about those changes. The token owner can approve the transaction with a proof. --- url: /zkapps/o1js/ecdsa --- # ECDSA ECDSA, or Elliptic Curve Digital Signature Algorithm, is a cryptographic algorithm used to sign and verify messages. It is used in many blockchains, including Ethereum, to sign transactions. ECDSA works with different elliptic curves. Bitcoin and Ethereum both use the [secp256k1](/glossary#secp256k1) curve. ## Why ECDSA? To interact with other blockchains and verify data from the outside world, o1js needs to be able to verify signatures. ECDSA is a widely used algorithm that is supported by many libraries and tools. For example, Ethereum transactions are signed using ECDSA over the secp256k1 curve. As a zkApp developer, when you want to verify an Ethereum transaction and make a statement about it, you must be able to verify the signature of the transaction which is why ECDSA is important for zkApps. ## Basic usage The ECDSA gadget is used to verify ECDSA signatures. The gadget takes as input the message, the signature, and the public key of the signer. It outputs a `Bool` indicating whether the signature is valid. Before you can verify a signature, you must initiate the gadget with a curve configuration. To initiate the curve: ```ts // create a secp256k1 curve class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} ``` By default, o1js exports a set of predefined curves. You can use the `createForeignCurve` function to create a curve from a `CurveParams` object. The `CurveParams` object contains the parameters of the curve, such as the modulus, the generator, and the parameters `a` and `b` of the curve equation `y^2 = x^3 + ax + b`. The namespace `Crypto.CurveParams` exports predefined curves, such as `Pallas`, `Vesta`, and `Secp256k1`. ```ts // predefined curve parameters CurveParams: { Secp256k1: CurveParams; Pallas: CurveParams; Vesta: CurveParams; } ``` This example uses `Secp256k1` as used in Ethereum. Now that you have a curve, you can create an instance of the ECDSA gadget: ```ts // create an instance of ECDSA over secp256k1, previously specified class Ecdsa extends createEcdsa(Secp256k1) {} ``` Before you can verify a signature, you must create one by signing a message. Messages are of type `Bytes`, see [Bytes - API reference](keccak#bytes---api-reference). To sign a message, use the `sign` function of the `Ecdsa` class. Note that signing is not a provable operation, only verifying is. ```ts // a private key is a random scalar of secp256k1 let privateKey = Secp256k1.Scalar.random(); let publicKey = Secp256k1.generator.scale(privateKey); // create a message, for a detailed explanation of `Bytes` take a look at the Keccak overview let message = Bytes32.fromString('cat'); // sign a message - this is not a provable method! let signature = Ecdsa.sign(message.toBytes(), privateKey.toBigInt()); ``` Finally, you can verify the signature using the `verify` method: ```ts // verify the signature, returns a Bool indicating whether the signature is valid or not let isValid: Bool = signature.verify(message, publicKey); ``` See the o1js repository for an [example](https://github.com/o1-labs/o1js/tree/main/src/examples/crypto/ecdsa) of how to use ECDSA. ### ECDSA - API reference ```ts // create a secp256k1 curve from a set of predefined parameters class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {} // create an instance of ECDSA over secp256k1 class Ecdsa extends createEcdsa(Secp256k1) {} // a private key is a random scalar of secp256k1 - not provable! let privateKey = Secp256k1.Scalar.random(); // a public key is a point on the curve let publicKey = Secp256k1.generator.scale(privateKey); // sign an array of bytes - not provable! let signature = Ecdsa.sign(bytes, privateKey.toBigInt()); // sign a hash of a message - not provable! let signature = Ecdsa.signHash(hash, privateKey.toBigInt()); // verify a signature let isValid: Bool = signature.verify(message, publicKey); // verify a hash of a message let isValid: Bool = signature.verifyHash(hash, publicKey); // create a signature from a hex string let signature = Ecdsa.fromHex('6f6d6e69627573206f6e206120636174...'); // create a signature from s and r, which can be of type `AlmostForeignField`, `Field3`, `bigint` or `number` let signature = Ecdsa.fromScalars({ r, s }); // convert a signature into a r and s of type bigint let { r, s } = signature.toBigInt(); ``` --- url: /zkapps/o1js/foreign-fields --- # Foreign Field Arithmetic A foreign field is a [finite field](https://en.wikipedia.org/wiki/Modular_arithmetic) different from the native field of the proof system. o1js exposes operations like modular addition and multiplication that work in any finite field of size less than `2^259`. Foreign fields are useful for implementing cryptographic algorithms in provable code. For example, you use them for verification of Ethereum-compatible ECDSA signatures. ## Why foreign fields? The core data type in o1js is `Field` that represents the field that is _native to the proof system_. In other words, addition and multiplication of Fields are the fundamental operations upon which all provable code is built. Because a lot of cryptography uses finite fields, o1js natively supports several cryptographic algorithms with high efficiency. See classes and modules like [Poseidon](../o1js-reference/variables/Poseidon), [PublicKey](../o1js-reference/classes/PublicKey), [PrivateKey](../o1js-reference/classes/PrivateKey), [Signature](../o1js-reference/classes/Signature), and [Encryption](../o1js-reference/namespaces/Encryption). However, these classes and modules are not compatible with the cryptography used in the wider world: `Signature.verify()` doesn't let you verify a signed JWT or email, and `Encryption.decrypt()` won't help you with your WhatsApp messages. That's because these methods use different finite fields than the native Field that was chosen primarily to enable efficient zk proofs. Here is where foreign fields come in: They let you perform algorithms that connect your zkApp with the outside world of cryptography. Foreign fields come with an efficiency hit compared to the native Field, but the heavily engineered foreign fields are efficient enough to unlock many interesting use cases. ## Basic usage This section provides a brief overview of how to use foreign fields. For more details, refer to the [API reference](../o1js-reference/classes/ForeignField) or the doc comments on each method. The entry point for using foreign fields is the `createForeignField()` function: ```ts class Field17 extends createForeignField(17n) {} ``` The only parameter that `createForeignField()` takes is the modulus or size of the field. This code example passes in `17n` so that `Field17` allows you to perform arithmetic modulo 17: ```ts let x = Field17.from(16); x.assertEquals(-1); // 16 = -1 (mod 17) x.mul(x).assertEquals(1); // 16 * 16 = 15 * 17 + 1 = 1 (mod 17) ``` As modulus, any number of up to 259 bits is supported. This means that `ForeignField` can be used for many elliptic curve algorithms (where bit sizes are often just below 256) but not for RSA with its typical bit size of 2048. Notably, the modulus does not have to be a prime number. For example, you can create a `UInt256` class where the modulus is `2^256`: ```ts class UInt256 extends createForeignField(1n << 256n) {} // and now you can do arithmetic modulo 2^256! let a = UInt256.from(1n << 255n); let b = UInt256.from((1n << 255n) + 7n); a.add(b).assertEquals(7); ``` The base type that is common to classes created by `createForeignField()` is `ForeignField`: ```ts // ... let zero: ForeignField = Field17.from(0); let alsoZero: ForeignField = UInt256.from(0); ``` `ForeignField` supports the basic arithmetic operations: ```ts x.add(x); // addition x.sub(2); // subtraction x.neg(); // negation x.mul(3); // multiplication x.div(x); // division x.inv(); // inverse ``` Note that these operations are performed modulo the field size. So, `Field17.from(1).div(2)` gives 9 because `2 * 9 = 18 = 1 (mod 17)`. `ForeignField` also comes with a few other provable methods: ```ts x.assertEquals(y); // assert x == y x.assertLessThan(2); // assert x < 2 let bits = x.toBits(); // convert to a `Bool` array of size log2(modulus); Field17.fromBits(bits); // convert back ``` And there are non-provable methods for converting to and from JS values: ```ts let y = SmallField.from(5n); // convert from bigint or number y.toBigInt() === 5n; // convert to bigint ``` As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/ForeignField). ## Three kinds of foreign fields If the basic usage examples look straightforward, here is where it gets a bit complicated. For each `ForeignField` class created with `createForeignField()`, there are actually three different variants: _unreduced_, _almost reduced_, and _canonical_. You find the variants as static properties on the class; they are themselves classes: ```ts let x = new Field17.Unreduced(0); let y = new Field17.AlmostReduced(0); let z = new Field17.Canonical(0); ``` Unreduced field elements just have the `ForeignField` type. For the other two variants, there are narrower base types that are common to each variant: ```ts y satisfies AlmostReducedField; z satisfies CanonicalField; ``` In the following section, you learn when to use the different variants, and how to convert between them. You don't need to remember all of it, though: The type system guides you to use the right variant in each situation. ### Unreduced fields Most arithmetic operations return unreduced fields: ```ts let z = x.add(x); assert(z instanceof Field17.Unreduced); ``` In short, **unreduced** means that a value can be larger than the modulus. For example, if `x` has the value 16, it is valid for `x.add(x)` to contain the value 32. The addition is correct modulo 17, but doesn't guarantee a result smaller than 17. :::note Unreduced doesn't usually mean that the underlying witness is larger than the modulus. It just means that it is not _proved_ to be smaller. A malicious prover _could_ make it larger by slightly modifying their local version of o1js and creating a proof with that version. ::: Unreduced fields can be added and subtracted, but not multiplied or divided: ```ts z.add(1).sub(x); // works assert((z as any).mul === undefined); // z.mul() is not defined assert((z as any).inv === undefined); assert((z as any).div === undefined); ``` ### Almost reduced fields To do multiplication, you need almost reduced fields. You can convert to them by using `.assertAlmostReduced()`: ```ts let zAlmost = z.assertAlmostReduced(); assert(zAlmost instanceof SmallField.AlmostReduced); ``` Now you can do multiplication and division: ```ts let zz = zAlmost.mul(zAlmost); // zAlmost.mul() is defined // but .mul() returns an unreduced field again: assert(zz instanceof SmallField.Unreduced); // zAlmost.inv() is defined, and returns an almost reduced field: assert(zAlmost.inv() instanceof SmallField.AlmostReduced); ``` It can be convenient to require almost reduced fields as inputs to your smart contract. To do that, create a class that can also serve as a type and use its `.provable` property when passing to the state decorator: ```ts class AlmostField17 extends Field17.AlmostReduced {} class MyContract extends SmartContract { @state(AlmostField17.provable) x = State(); @method async myMethod(y: AlmostField17) { let x = y.mul(2); this.x.set(x.assertAlmostReduced()); } } ``` #### What does almost reduced mean? The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way you prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that the modulus is required to be `< 2^259`.) However, you actually prove a stronger condition, which saves a few constraints in some places: `z` is **almost reduced** modulo `f`, if `z >> 176` is smaller or equal than `f >> 176`. (`>>` means a [right shift](https://en.wikipedia.org/wiki/Arithmetic_shift).) :::note Example: Assume `x` is a `UInt256` holding the value `2^130`. After computing `z = x.mul(x)`, it is valid for `z` to be `2^260`. However, by calling `z.assertAlmostReduced()`, you prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to the stronger definition, you even have `z < 2^256`. ::: Why is `AlmostReducedField` exposed as a separate type, instead of _always_ proving conditions necessary for multiplication? Because that would take up additional constraints! `ForeignField` is built to allow you to use the minimum amount of constraints in a way that is safely guided by the type system. See [minimizing constraints](#minimizing-constraints) for more details. ### Canonical fields Canonical fields are the strictest variant. They are guaranteed to be smaller than the modulus. When you create fields from constants, they always get fully reduced. The type signature of `ForeignField.from()` reflects this and returns a canonical field: ```ts let constant = Field17.from(16); assert(constant instanceof Field17.Canonical); // these also work, because `from()` takes the input mod 17: Field17.from(100000000n) satisfies CanonicalForeignField; Field17.from(-1) satisfies CanonicalForeignField; ``` You can convert any field to canonical by calling `.assertCanonical()`: ```ts let zCanonical = z.assertCanonical(); assert(zCanonical instanceof Field17.Canonical); ``` Canonical fields are a special case of almost reduced fields at the type level: ```ts constant satisfies AlmostForeignField; constant.mul(constant); // works ``` The cheapest way to prove that an existing field element is canonical is to show that it is equal to a constant: ```ts let zCanonical = z.assertEquals(3); assert(zCanonical instanceof Field17.Canonical); ``` An operation that is only possible on canonical fields is the boolean equality check: ```ts let xCanonical = x.assertCanonical(); let yCanonical = y.assertCanonical(); let isEqual = xCanonical.equals(yCanonical); ``` Inputs must be canonical for `equals()` because the operation checks for strict equality, not equality modulo the field size. Note that being strictly unequal does not imply being unequal as field elements, so `equals()` on non-canonical fields would be error-prone. ## Minimizing constraints Follow these strategies to minimize constraints. #### `assertAlmostReduced()` Here is a trick to save constraints when you need to "almost reduce" many field elements: Always reduce them in _batches of 3_. For example, do this when doing many multiplications in a row: ```ts let z1 = x.mul(7); let z2 = x.add(11); let z3 = x.sub(13); let [z1r, z2r, z3r] = Field17.assertAlmostReduced(z1, z2, z3); z1r.mul(z2r); z2r.div(z3r); ``` `assertAlmostReduced()` takes any number of inputs, but is the most efficient with multiples of 3. For example: - 1 input takes 4.5 constraints - 2 inputs take 5 constraints - 3 inputs take 5.5 constraints #### `sum()` Another opportunity to save constraints is when many additions or subtractions are performed in a row. Instead of doing something like `x.add(y).sub(z)`, use `ForeignField.sum()`: ```ts // u = x + y - z let u = Field17.sum([x, y, z], [1, -1]); ``` The second argument is a list of signs: either 1 or -1, depending on whether you want to add or subtract the corresponding value. So, the 1 in this example means "add x and y", and the -1 means "subtract z". To give a few more examples: ```ts // u = x - y - z let u = Field17.sum([x, y, z], [-1, -1]); // u = 2*x + y let u = Field17.sum([x, x, y], [1, 1]); // u = -3*z let u = Field17.sum([0, z, z, z], [-1, -1, -1]); ``` Doing small multiplications like `-3*z` like this is more efficient than using `mul()` for the task. `sum()` uses 6 constraints for the first two summands but only 1 constraint per additional summand. --- url: /zkapps/o1js/gadgets --- # Gadgets Gadgets are small, reusable low-level building blocks that simplify the process of creating new cryptographic primitives. Most gadgets build upon custom gates and act as low-level accelerators in the proof system. In o1js, you can import these provable and helper methods from the `Gadgets` namespace: - [Bitwise Operations](/zkapps/o1js/bitwise-operations) - [Foreign Field Arithmetic](/zkapps/o1js/ecdsa) See the type declaration for [Gadgets](/zkapps/o1js-reference/variables/Gadgets) in the o1js Reference documentation. --- url: /zkapps/o1js --- :::info To protect end users and ensure your zkApps are secure, consider the information at [Security and zkApps](/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps) while architecting your solution and consider a third-party security audit before deploying to Mina mainnet. ::: # Introduction to o1js o1js is a TypeScript library for: - Writing general-purpose zero knowledge (zk) programs - Writing zk smart contracts for Mina This is TypeScript code that you might write when using o1js: ```ts function knowsPreimage(preimage: Field) { let hash = Poseidon.hash([preimage]); hash.assertEquals(expectedHash); } const expectedHash = 0x1d444102d9e8da6d566467defcc446e8c1c3a3616d059facadbfd674afbc37ecn; ``` In a zkApp, this code can be used to prove that you know a secret value whose hash is publicly known without revealing the secret. The code is plain TypeScript and is executed as normal TypeScript. You might call o1js an _embedded domain-specific language (DSL)_. o1js provides data types and methods that are _provable_: You can prove their execution. In the example code, `Poseidon.hash()` and `Field.assertEquals()` are examples of provable methods. Proofs are _zero knowledge_, because they can be verified without learning their inputs and execution trace. Selected parts of the proof can be made public, if it suits your application. o1js is a general-purpose zk framework that gives you the tools to create zk proofs. It lets you write arbitrary zk programs leveraging a rich set of built-in provable operations, like basic arithmetic, hashing, signatures, boolean operations, comparisons, and more. Use the o1js framework to write zkApps on Mina, smart contracts that execute client-side and have private inputs. All of the o1js framework is packaged as a single TypeScript library that can be used in major web browsers and Node.js. The best way to get started with o1js is [using the zkApp CLI](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp). You can also install o1js from npm with `npm i o1js`. Start your o1js journey by learning about [basic zk programming concepts](/zkapps/o1js/basic-concepts). ## Audits of o1js * [**Veridise external audit (Q3 2024)**](https://github.com/o1-labs/o1js/blob/a09c5167c4df64f879684e5af14c59cf7a6fce11/audits/VAR_o1js_240318_o1js_V3.pdf). We engaged Veridise, a security auditing company, to do a full audit of o1js version 1. Veridise spent 39 person-weeks reviewing o1js in depth, and all issues of medium severity and higher were fixed. * [**Internal audit (Q1 2024)**](https://github.com/o1-labs/o1js/files/15192821/Internal.o1js.audit.Q1.2024.pdf). In March 2024, the o1js team spent roughly two person-weeks to conduct an internal audit of parts of the o1js code base. The audit focused on reviewing core provable code. A number of issues were found and fixed. Please see our page on [Security and zkApps](/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps) for more information on ensuring your zkApp is secure. --- url: /zkapps/o1js/indexed-merkle-map --- :::experimental The Indexed Merkle Map API is currently an experimental feature. ::: # Indexed Merkle Map Similar to a Merkle Tree, a Merkle Map allows referencing off-chain data by storing a single hash, also known as the root. A Merkle Map is a wrapper around a [Merkle Tree](/zkapps/o1js/merkle-tree). Both data structures are analogous, but instead of using an index to set a leaf in a tree, a Merkle Map uses a key in a map. ## Design The Indexed Merkle Map is an improved version of the [MerkleMap](/zkapps/tutorials/common-types-and-functions#merkle-map), offering enhanced efficiency and usability: - **Reduced Constraints:** Uses 4-8x fewer constraints than `MerkleMap`. - **Provable Code Integration:** Unlike `MerkleTree` and `MerkleMap`, the high-level API of `IndexedMerkleMap` is usable within provable code. :::note The `Indexed Merkle Map` can have a height of at most `52`, whereas the `Merkle Map` has a larger height fixed at `256`. ::: ## Utilizing Indexed Merkle Map ### Prerequisites The `IndexedMerkleMap` API is accessible within the `Experimental` namespace. To use the API, import `Experimental` from o1js version 1.5.0 or higher. ```ts const { IndexedMerkleMap } = Experimental; ``` ### Instantiating an Indexed Merkle Map Given a height, you can instantiate an Indexed Merkle Map by extending the base class. The height determines the capacity of the map; the maximum number of leaf nodes it can contain. ```ts const height = 31; class IndexedMerkleMap31 extends IndexedMerkleMap(height) {} ``` In this example, `IndexedMerkleMap31` is a Merkle map capable of holding up to 2(31−1) leaves; approximately 1 billion entries. ### Indexed Merkle Map - API reference For an example, see the `IndexedMerkleMap` [API reference](/zkapps/o1js-reference/namespaces/Experimental/functions/IndexedMerkleMap) in o1js. ## Additional Resources For more details and examples, please refer to the following GitHub resources: - [Indexed Merkle Tree: o1js PR#1666](https://github.com/o1-labs/o1js/pull/1666) - [IndexedMerkleMap: Support 0 and -1 Keys: o1js PR#1671](https://github.com/o1-labs/o1js/pull/1671) - [Mastermind zkApp Example Using Indexed Merkle Map](https://github.com/o1-labs-XT/mastermind-zkApp/tree/level3) --- url: /zkapps/o1js/keccak --- # Keccak (SHA-3) Keccak is a flexible cryptographic hash function that provides more security than traditional SHA hash algorithms. ## What is Keccak? Developed by a team of cryptographers from Belgium, Keccak was the winning submission for the National Institute of Standards and Technology (NIST) SHA-3 competition. Keccak was standardized as SHA-3. Keccak is used in many different applications, including Ethereum. Specifically, Keccak is used in the Ethereum ecosystem to hash addresses, transactions, and blocks. It is also used to hash the state trie, the data structure that stores the state of the Ethereum blockchain. Because of the common usage of Keccak in Ethereum, it is a key component of o1js that you can use to verify Ethereum transactions and blocks in o1js. ## Keccak and Poseidon As an o1js developer, you are likely familar with the [Poseidon](https://o1-labs.github.io/proof-systems/specs/poseidon.html) zero knowledge native hash function. Poseidon operates over the native [Pallas base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) and uses parameters generated specifically for Mina which makes Poseidon the most efficient hash function available in o1js. In contrast, Keccak is a hash function that requires binary arithmetic. It operates over binary data and is not native to most zero knowledge proofs. For this reason, Keccak is not as efficient as Poseidon, but it is still very useful for verifying Ethereum transactions and blocks. So, when you choose what hash function to use, important considerations include the use case and the data that needs to be hashed. ## Basic usage Keccak is available in the following configurations that are available under the `Hash` namespace in o1js: - `Hash.SHA3_256`: NIST SHA3 hash function with output size of 256 bits. - `Hash.SHA3_385`: NIST SHA3 hash function with output size of 384 bits. - `Hash.SHA3_512`: NIST SHA3 hash function with output size of 512 bits. - `Hash.Keccak256`: pre-NIST Keccak hash function with output size of 256 bits. _This configuration used to hash blocks, transactions, and more in Ethereum._ - `Hash.Keccak384`: pre-NIST Keccak hash function with output size of 384 bits. - `Hash.Keccak512`: pre-NIST Keccak hash function with output size of 512 bits. Because Keccak operates over binary data instead of native Field elements like Poseidon, o1js uses the `Bytes` type. `Bytes` is a fixed-length array of bytes that can be used to represent binary data. Under the hood, `Bytes` is represented as an array of `UInt8` elements. To use `Bytes`, you must extend the `Bytes` class and specify the length of bytes: ```ts // This creates a Bytes class that represents 16 bytes class Bytes16 extends Bytes(16) {} ``` To initiate your `Bytes16` class with a value, you can use `from`, `fromHex`, or `fromString`. ```ts // `.from` accepts an array of `number`, `bigint`, `UInt8` elements or a `Uint8Array` or `Bytes` let bytes = Bytes16.from(new Array(16).fill(0)); // converts a hex string to bytes bytes = Bytes16.fromHex('646f67'); // converts a string to bytes bytes = Bytes16.fromString('dog'); // print the contents of `bytes` to the console bytes.bytes.forEach((b) => console.log(b.toBigInt())); // [100n, 111n, 103n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n] ``` :::note If the input array is smaller than the length of the `Bytes` class, it will be padded with zeros. ::: You can also convert a `Bytes` object back to a hex string using `toHex`. ```ts class Bytes3 extends Bytes(3) {} let bytes = Bytes3.fromHex('646f67'); let hex = bytes.toHex(); console.log('hex', hex); // 646f67 ``` Now that you know how to use `Bytes` as input, you can use it to hash data using Keccak: ```ts // define a preimage let preimage = 'The quick brown fox jumps over the lazy dog'; // create a Bytes class that represents 43 bytes class Bytes43 extends Bytes(43) {} // convert the preimage to bytes let preimageBytes = Bytes43.fromString(preimage); // hash the preimage let hash = Hash.SHA3_256.hash(preimageBytes); console.log(hash.toHex()); //69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04 ``` See the o1js repository for a [hashing example](https://github.com/o1-labs/o1js/tree/main/src/examples/zkapps/hashing) that uses SHA-256 and Keccak. ### Bytes - API reference ```ts // creates a Bytes class that represents n bytes (n is 32 in this example) let n = 32; class BytesN extends Bytes(n) {} // initiate an instance from a hex string let bytes = BytesN.fromHex('646f67'); // initiate an instance from a string bytes = BytesN.fromString('dog'); // initiate an instance from an array of numbers bytes = BytesN.from([100, 111, 103]); // initiate an instance from an array of bigints bytes = BytesN.from([100n, 111n, 103n]); // initiate an instance from an array of UInt8 elements bytes = BytesN.from([UInt8(100), UInt8(111), UInt8(103)]); // initiate an instance from a Uint8Array bytes = BytesN.from(new Uint8Array([100, 111, 103])); // initiate an instance from another Bytes instance bytes = BytesN.from(BytesN.fromHex('646f67')); // convert the bytes to a hex string const hex = bytes.toHex(); ``` ### Keccak - API reference ```ts // https://keccak.team/keccak.html hash function, pre-NIST specification // hash bytes using Keccak256 with output size of 256 bits, mainly used in Ethereum Hash.Keccak256.hash(bytes); // hash bytes using Keccak384 with output size of 384 bits Hash.Keccak384.hash(bytes); // hash bytes using Keccak512 with output size of 512 bits Keccak.Keccak512.hash(bytes); // https://csrc.nist.gov/pubs/fips/202/final hash function, official NIST specification // hash bytes using SHA3_256 with output size of 256 bits Hash.SHA3_256.hash(bytes); // hash bytes using SHA3_384 with output size of 384 bits Hash.SHA3_384.hash(bytes); // hash bytes using SHA3_512 with output size of 512 bits Hash.SHA3_512.hash(bytes); ``` --- url: /zkapps/o1js/merkle-tree --- # Merkle Tree zkApp accounts can store only a limited amount of data on chain so that Mina's chain remains succinct and does not become bloated. But some zkApps might require you to access more than what you can store on-chain in a zkApp account. ## Referencing off-chain data But how can you achieve that? The answer is a Merkle tree! Merkle trees (or similar structures such as Verkle trees) allow you to _reference_ off-chain data by storing only a single hash on-chain. ## How does that work? Merkle trees are special binary trees in which every leaf (the nodes at the very bottom of the tree!) are cryptographic hashes of the underlying pieces of data, and the internal nodes are labeled with the cryptographic hash of the concatenated labels (hashes) of its child nodes. By following this algorithm to the very top, you end up with one single node (the root node) that stores the root hash of the tree. The root hash is a reference to all pieces of data that were included in the tree's leaves, so you can reference large amounts of data by using one small hash. Another benefit of Merkle trees is the witness, also known as a Merkle proof or Merkle path. The witness is the path from one specific leaf node to the very top of the tree (the root). Merkle witnesses are proofs of inclusion that prove that one specific piece of data (for example, an account in the ledger or the scores on a leaderboard) exists within the entire tree. #### How are Merkle trees useful for zkApps? You can reference large amounts of off-chain data and prove inclusion of very specific parts of that data with only a small hash - the root - and a witness. To use Merkle trees and reference off-chain data in your zkApps on Mina, store the root of the tree on-chain and voilà, you now have access to more data off-chain. Imagine a zkApp that manages a game with a leaderboard. The zkApp has a method to update a player's score if the player guesses a number correctly. After a player reaches a threshold score, the player can invoke another method to get a reward. Because you want many players to participate in the game, you are drastically limited by how much data can be stored on-chain. You will quickly run out of on-chain space with eight or more participants. A possible solution to that problem is to use the power of Merkle trees, store the public keys of each player and their corresponding scores off-chain, and reference the keys in the smart contract. Look at the data structure first. For example, to map a player's id to score points: ```sh 0: 5 points 1: 3 points 2: 0 points 3: 8 points ... : ... 7: 2 points ``` #### Implementing the smart contract Now it's time to look at what a leaderboard zkApp might look like. To have on-chain state that points to the off-chain Merkle tree, call this variable the `root`. :::info Sometimes the variable `root` is called commitment, because it commits to something. ::: Additionally, you want to store a variable `z` that is the hash of the value a player has to guess: `H(guess) = z` :::info Guessing a simple hash like this example can easily be brute forced, especially if the preimage is simple (like a 5-letter word or a small number with only a few digits). Ensure that your zkApps are always secure, especially when dealing with funds. ::: The first method allows a player to make a guess; if the guess is correct, the player gains one point. The method takes the player's guess and hashes it, then checks if the hash `H(guess)` equals the on-chain state `z`, and if that's the case, then the player gains one point on the scoreboard. A second method is required to take care of the reward. It checks if the player's score is over a threshold and pays out a reward if that's the case. This method must also verify the Merkle witness and check if it matches the on-chain stored Merkle root. :::note The `examples` folder in the o1js repository includes a working [Merkle tree](https://github.com/o1-labs/o1js/tree/main/src/examples/zkapps/merkle-tree) example with all of the required boilerplate code. ::: ```ts class Leaderboard extends SmartContract { // the root is the root hash of our off-chain Merkle tree @state(Field) root = State(); // z is the hashed number we want to guess! @state(Field) z = State(); init() { super.init(); // this is our hash we want to guess! its the hash of the preimage "22", but keep it a secret! this.z.set( Field( '17057234437185175411792943285768571642343179330449434169483610110583519635705' ) ); } @method async guessPreimage(guess: Field, account: Account, path: MerkleWitness) { // we fetch z from the chain const z = this.z.get(); this.z.requireEquals(z); // if our guess preimage hashes to our target, we won a point! Poseidon.hash([guess]).assertEquals(z); // we fetch the on-chain commitment/root const root = this.root.get(); this.root.requireEquals(root); // we check that the account is within the committed Merkle Tree path.calculateRoot(account.hash()).assertEquals(root); // we update the account and grant one point! let newAccount = account.addPoints(1); // we calculate the new Merkle Root, based on the account changes const newRoot = path.calculateRoot(newAccount.hash()); this.root.set(newRoot); } @method async claimReward(account: Account, path: MerkleWitness) { // we fetch the on-chain commitment const root = this.root.get(); this.root.requireEquals(root); // we check that the account is within the committed Merkle Tree path.calculateRoot(account.hash()).assertEquals(root); // we check that the account has at least 10 score points in order to claim the reward account.score.assertGte(UInt32.from(10)); // finally, we send the player a reward this.send({ to: account.address, amount: 100_000_000, }); } } ``` Merkle trees allow you to reference off-chain data easily by only adding a couple of lines of code. However, it is your responsibility as the developer of the zkApp to make sure that the Merkle tree that is referenced on-chain is always in sync with the actual off-chain data structure. You can look at the [Merkle tree example](https://github.com/o1-labs/o1js/tree/main/src/examples/zkapps/merkle-tree) in the o1js repository to get a better understanding of how you can leverage the power of Merkle trees. :::info Merkle trees are great for _referencing_ off-chain state, but you must also store this off-chain state somewhere. Where and how to store the data off-chain storage is left up to you, the developer. Tell us how you are using Merkle trees in the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel in Mina Protocol Discord. ::: ### Merkle Tree - API reference ```ts const treeHeight = 8; // creates a tree of height 8 const Tree = new MerkleTree(treeHeight); // creates the corresponding MerkleWitness class that is circuit-compatible class MyMerkleWitness extends MerkleWitness(treeHeight) {} // sets a value at position 0n Tree.setLeaf(0n, Field(123)); // gets the current root of the tree const root = Tree.getRoot(); // gets a plain witness for leaf at index 0n const witness = Tree.getWitness(0n); // creates a circuit-compatible witness const circuitWitness = new MyMerkleWitness(witness); // calculates the root of the witness const calculatedRoot = circuitWitness.calculateRoot(Field(123)); calculatedRoot.assertEquals(root); ``` --- url: /zkapps/o1js/recursion --- # Recursion Kimchi, the custom proof system that backs o1js, supports arbitrary infinite recursive proof construction of circuits through integration with the Pickles recursive system. Mina Protocol is the only blockchain that offers infinite recursion. Recursion is an incredibly powerful primitive that has a wide-array of uses. For example: 1. Mina uses linear recursive proofs to compress the blockchain, an infinitely growing structure, down to a constant size. 2. Mina also uses "rollup-like" tree-based recursive proofs to, _in parallel_, compress transactions within blocks down to a constant size. 3. An app-specific rollup like a Mastermind game that uses linear recursive proofs to progress the state machine of the application without needing to sync back to the game. 4. App-specific rollups can use recursion to communicate to each other, like app chains using Inter-Blockchain Communication protocol [(IBC)](https://cosmos.network/ibc/) (Cosmos) or parachains using Cross-Chain Virtual Machine [(XVM)](https://wiki.polkadot.network/docs/learn-xcm) to send messages. More generally, you can use recursion to verify any zero knowledge program as part of your zkApp. ## ZkProgram Overview :::note zkProgram is available as a top-level import. `Experimental.ZkProgram` is deprecated. If you are experiencing issues with zkProgram, be sure to update [o1js](https://github.com/o1-labs/o1js) to the latest version. ::: In o1js, you can use `ZkProgram()` to define the steps of a recursive program. Like `SmartContract()` methods, `ZkProgram()` methods execute off-chain. After performing the desired recursive steps, you can settle the interaction on Mina's blockchain by embedding `ZkProgram` within a `SmartContract` method that verifies the underlying proof of execution and extracts the output that can be used elsewhere in the method (like storing the output in app-state, for example). Similar to methods within the `SmartContract` class, inputs to `ZkProgram` are _private by default_ and are never seen by the Mina network. Unlike `SmartContract` methods, as the zkApp developer you choose the shape of the public input to all methods within a `ZkProgram`. ## Example: Recursively verify a simple program in a zkApp This simple example has only one method that proves the public input it received is zero: ```typescript const SimpleProgram = ZkProgram({ name: 'simple-program-example', publicInput: Field, methods: { run: { privateInputs: [], async method(publicInput: Field) { publicInput.assertEquals(Field(0)); }, }, }, }); ``` To compile this program: ```typescript const { verificationKey } = await SimpleProgram.compile(); ``` Now, you can use it to create a proof: ```typescript const { proof } = await SimpleProgram.run(Field(0)); ``` To verify this proof from within any method of your `SmartContract` class: ```typescript @method async foo(proof: SimpleProgram.Proof) { proof.verify().assertTrue(); const output: Field = proof.value; // ...the rest of our method. // For example, storing the output of the execution of the program we've // proven as on-chain state, if desired. } ``` In this example, `foo` is taking the `SimpleProgram` proof as a private argument to the method, verifying that the execution was valid, and then using the output. ## Example: Recursively verify a linear recursive program in a zkApp This example shows a recursive `ZkProgram` that you can use to create recursive zero knowledge proofs. In other proof systems, this is extremely difficult to construct (if it is even possible). In o1js, you can describe a recursive ZkProgram with a simple recursive function. This program describes a recursive operation of adding one repeatedly to a number: ```typescript const AddOne = ZkProgram({ name: 'add-one-example', publicInput: Field, methods: { baseCase: { privateInputs: [], async method(publicInput: Field) { publicInput.assertEquals(Field(0)); }, }, step: { privateInputs: [SelfProof], async method(publicInput: Field, earlierProof: SelfProof) { earlierProof.verify(); earlierProof.publicInput.add(1).assertEquals(publicInput); }, }, }, }); ``` Note that this example recursively depends on the older proof as a private argument to your method. First, compile this program and make the base proof as before: ```typescript const { verificationKey } = await AddOne.compile(); const { proof } = await AddOne.baseCase(Field(0)); ``` This time, use this proof as input to recursively add one again: ```typescript const { proof: proof1 } = await AddOne.step(Field(1), proof); ``` Repeat this as many times as you want: ```typescript const { proof: proof2 } = await AddOne.step(Field(2), proof1); ``` Finally, verify the proof from within a SmartContract like the earlier example: ```typescript @method async foo(proof: Proof) { proof.verify().assertTrue(); /* ... the rest of our method * For example using the total value as the fee for some other transaction. */ } ``` ## Example: Recursively verify a tree-based recursive program in a zkApp Tree recursion is rarely seen in other proof systems and zk toolkits. Tree recursion is used internally within Mina as part of its decentralized prover and sequencing mechanism for rollups, so it's supported very robustly by Kimchi. This example program describes a very simple rollup for adding numbers: ```typescript let RollupAdd = ZkProgram({ name: 'rollup-add-example', publicInput: Field, methods: { baseCase: { privateInputs: [], async method(publicInput: Field) {}, }, step: { privateInputs: [SelfProof, SelfProof], async method( publicInput: Field, left: SelfProof, right: SelfProof ) { left.verify(); right.verify(); // assert that the left and right equal this input left.publicInput.add(right.publicInput).assertEquals(publicInput); }, }, }, }); ``` ## Bonus: Using ZkPrograms outside of zkApps You can also use ZkProgram directly to prove and verify arbitrary zero knowledge programs (also known as circuits): ```typescript const { verificationKey } = await MyProgram.compile(); const { proof } = await MyProgram.base(Field(0)); ``` Now you can directly verify a JSON-encoded version of the proof to get back a boolean value that tells you if the proof is valid: ```typescript const ok = await verify(proof.toJSON(), verificationKey); ``` --- url: /zkapps/o1js/sha256 --- # SHA-256 SHA-2 is a set of cryptographic hash functions designed by the National Security Agency (NSA) as an improved version of SHA-1, offering enhanced security and comprising multiple variants based on hash size, such as SHA-256 and SHA-512. It is also the predecessor of [Keccak (SHA-3)](/zkapps/o1js/keccak). The SHA-2 family is available with different output lengths, including 256-bit (SHA-256) or 512-bit (SHA-512). o1js supports only SHA-2 with an output length of 256 bits. ## What is SHA-2 and SHA-256? SHA-256, a part of the SHA-2 family, is a cryptographic hash function that generates a 256-bit (32-byte) hash output, widely used for traditional Web2 applications and protocols and blockchain technology. For example, Bitcoin's block headers are hashed twice using SHA-256. ## SHA-256 and Poseidon As an o1js developer, you are likely familar with the [Poseidon](https://o1-labs.github.io/proof-systems/specs/poseidon.html) zero knowledge native hash function. Poseidon operates over the native [Pallas base field](https://electriccoin.co/blog/the-pasta-curves-for-halo-2-and-beyond/) and uses parameters generated specifically for Mina which makes Poseidon the most efficient hash function available in o1js. In contrast, SHA-2 is a hash function that requires binary arithmetic. It operates over binary data and is not native to most zero knowledge proofs. For this reason, SHA-256 is not as efficient as Poseidon. However, it is still very useful for verifying Ethereum transactions and blocks. So, when you choose what hash function to use, important considerations include the use case and the data that needs to be hashed. ## Basic usage SHA-256 is available in the following configuration under the `Hash` namespace in o1js: - `Hash.SHA2_256`: SHA2-256 hash function with output size of 256 bits. Because SHA-256 operates over binary data instead of native Field elements like Poseidon, o1js uses the `Bytes` type. `Bytes` is a fixed-length array of bytes that can be used to represent binary data. Under the hood, `Bytes` is represented as an array of `UInt8` elements. In order to use `Bytes`, you must extend the `Bytes` class and specify the length of bytes. For a detailed explanation, take a look at [How Keccak utilizes Bytes](keccak#bytes---api-reference) ```ts // define a preimage let preimage = 'The quick brown fox jumps over the lazy dog'; // create a Bytes class that represents 43 bytes class Bytes43 extends Bytes(43) {} // convert the preimage to bytes let preimageBytes = Bytes43.fromString(preimage); // hash the preimage let hash = Hash.SHA2_256.hash(preimageBytes); console.log(hash.toHex()); //d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 ``` See the o1js repository for a [hashing example](https://github.com/o1-labs/o1js/tree/main/src/examples/zkapps/hashing) that uses SHA-256 and Keccak. ### SHA-256 - API reference ```ts // hash bytes using SHA256 with output size of 256 bits Hash.SHA2_256.hash(bytes); ``` --- url: /zkapps/roadmap --- # zkApps and o1js Roadmap High-level overview of features available now, next, and later o1js banner To stay up to date with zkApps and o1js, follow the [o1Labs blog posts](https://www.o1labs.org/blog). --- url: /zkapps/standards --- # Standards for the Mina Ecosystem ## Standards Process Standards for Mina are established through an rfc/rfp process: rfcs can be opened in the [Core Grants repository](https://github.com/MinaFoundation/Core-Grants). After discussion on an rfc has concluded, development work can be performed either internally, or by community members after going through an rfp process and receiving a grant. Below, we list standards that have been established for Mina. ## Established Standards ### Fungible tokens We have released a standard implementation for fungible tokens on Mina. It allows for defining rules for minting tokens upon deployment. Tokens can be transferred, either by calling a `transfer` method of the token contract, or by manually constructing transactions from individual account updates. This enables interoperability with third party contracts. The standard implementation can be found on [Github](https://github.com/MinaFoundation/mina-fungible-token). Documentation around how to use the standard can be found [here](https://minafoundation.github.io/mina-fungible-token/introduction.html). The fungible token implementation separates out the rules for minting tokens into a separate admin contract. This is to allow custom rules without modifications to the token contract itself. Note that if you do modify the token contract, third parties such as wallets that want to integrate your token will need to integrate your modification into their own codebase. It is thus recommended to use the standard token contract when possible, and only modify the admin contract. --- url: /zkapps/tutorials/01-hello-world --- # Tutorial 1: Hello World This Hello World tutorial helps you get started with o1js, zkApps, and programming with zero knowledge proofs. In this step-by-step tutorial, you learn to code a zkApp from start to finish. You will: - Write a basic smart contract that stores a number as on-chain state. - The contract logic allows this number to be replaced only by its square; for example, 3 -> 9 -> 81, and so on. - Create a project using the [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) - Write your smart contract code - Use a simulated local Mina blockchain to interact with your smart contract. Later tutorials introduce more concepts and patterns. The full source code for this tutorial is provided in the [examples/zkapps/01-hello-world](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/01-hello-world) directory on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp! :::info To prevent copying line numbers and command prompts as shown in the examples, use the copy code to clipboard button that appears at the top right of the snippet box when you hover over it. ::: ## Prerequisites Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. In particular, make sure you have the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` ## Create a new project Now that you have the tooling installed, you can start building your application. 1. Create or change to a directory where you have write privileges. 1. Now, create a project using the `zk project` command: ```sh $ zk project 01-hello-world ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ```sh ? Create an accompanying UI project too? … next svelte nuxt empty > none ``` The expected output is: ```sh ✔ Create an accompanying UI project too? · none ✔ UI: Set up project ✔ Initialize Git repo ✔ Set up project ✔ NPM install ✔ NPM build contract ✔ Set project name ✔ Git init commit Success! Next steps: cd 01-hello-world git remote add origin git push -u origin main ``` The `zk project` command creates the `01-hello-world` directory that contains the scaffolding for your project, including tools such as the Prettier code formatting tool, the ESLint static code analysis tool, and the Jest JavaScript testing framework. 1. Change into the `01-hello-world` directory and list the contents: ```sh $ cd 01-hello-world $ ls ``` The output shows these results: ```sh LICENSE README.md babel.config.cjs build config.json jest-resolver.cjs jest.config.js keys node_modules package-lock.json package.json src tsconfig.json ``` For this tutorial, you run commands from the root of the `01-hello-world` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Prepare the project Start by deleting the default files that come with the new project. 1. To delete the old files: ```sh $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts ``` 1. Now, create the new files for your project: ```sh $ zk file src/Square $ touch src/main.ts ``` - The `zk file` command created the `src/Square.ts` and `src/Square.test.ts` test files. - This tutorial does not include writing tests, so you just use the `main.ts` file as a script to interact with the smart contract and observe how it works. In later tutorials, you learn how to interact with a smart contract from the browser, like a typical end user. 1. Now, open `src/index.ts` in a text editor and change it to look like: ```ts src/index.ts 1 import { Square } from './Square.js'; 2 3 export { Square }; ``` The `src/index.ts` file contains all of the exports you want to make available for consumption from outside your smart contract project, such as from a UI. ## Write the zkApp Smart Contract Now, the fun part! Write your smart contract in the `src/Square.ts` file. Line numbers are provided for convenience. A final version of the smart contract is provided in the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file. This part of the tutorial walks you through the `Square` smart contract code already completed in the `src/Square.ts` example file. ### Copy the example This tutorial describes each part of the completed code in the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file. 1. First, open the [Square.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/Square.ts) example file. 1. Copy the entire contents of the file into your smart contract in the `src/Square.ts` file. Now you are ready to review the imports in the smart contract. ### Imports The `import` statement brings in other packages and dependencies to use in your smart contract. :::info All functions used inside a smart contract must operate on o1js compatible data types: `Field` types and other types built on top of `Field` types. :::info ```ts src/Square.ts 1 import { 2 Field, 3 SmartContract, 4 state, 5 State, 6 method, 7 } from 'o1js'; ``` These items are: - `Field`: The native number type in o1js. You can think of field elements as unsigned integers. Field elements are the most basic type in o1js. All other o1js-compatible types are built on top of field elements. - `SmartContract`: The class that creates zkApp smart contracts. - `state`: A convenience decorator used in zkApp smart contracts to create references to state stored on-chain in a zkApp account. - `State`: A class used in zkApp smart contracts to create state stored on-chain in a zkApp account. - `method`: A convenience decorator used in zkApp smart contracts to create smart contract methods like functions. Methods that use this decorator are the end user's entry points to interacting with a smart contract. ### Smart contract class Now, review the smart contract in the `src/Square.ts` file. The smart contract called `Square` has one element of on-chain state named `num` of type `Field` as defined by following code: ```ts src/Square.ts 8 9 export class Square extends SmartContract { 10 @state(Field) num = State(); 11 12 } ``` zkApps can have up to eight fields of on-chain state. Each field stores up to 32 bytes (technically, 31.875 bytes or 255 bits) of arbitrary data. A later tutorial covers options for off-chain state. Now, this code adds the `init` method to set up the initial state of the smart contract on deployment: ```ts src/Square.ts 8 9 export class Square extends SmartContract { 10 @state(Field) num = State(); 11 12 init() { 13 super.init(); 14 this.num.set(Field(3)); 15 } ``` Since this code extends `SmartContract` that has its own initialization to perform, calling `super.init()` invokes this function on the base class. Then, `this.num.set(Field(3))` initializes the on-chain state `num` to a value of `3`. You can optionally specify permissions. See [setPermissions](/zkapps/o1js-reference/classes/SmartContract) in the o1js Reference documentation. Finally, this code adds the `update()` function: ```ts src/Square.ts 14 this.num.set(Field(3)); 15 } 16 17 @method async update(square: Field) { 18 const currentState = this.num.get(); 19 this.num.requireEquals(currentState); 20 square.assertEquals(currentState.mul(currentState)); 21 this.num.set(square); 22 } 23 } ``` The function name `update` is arbitrary, but it makes sense for this example. Notice how the `@method` decorator is used because it is intended to be invoked by end users by using a zkApp UI, or as in this case, the `main.ts` script. This method contains the logic by which end users are allowed to update the zkApp's account state on chain. A zkApp account is an account on the Mina blockchain where a zkApp smart contract is deployed. A zkApp account has a verification key associated with it. In this example, the code specifies: - If the user provides a number (for example, 9) to the `update()` method that is the square of the existing on-chain state referred to as `num` (for example, 3), then update the `num` value that is stored on-chain to the provided value (in this case, 9). - If the user provides a number that does not meet these conditions, they are unable to generate a proof or update the on-chain state. These update conditions are accomplished by using assertions within the method. When a user invokes a method on a smart contract, all assertions must be true to generate the zero knowledge proof from that smart contract. The Mina network accepts the transaction and updates the on-chain state only if the attached proof is valid. This assertion is how you can achieve predictable behavior in an off-chain execution model. Notice that `get()` and `set()` methods are used for retrieving and setting on-chain state. - A smart contract retrieves the on-chain account state when it is first invoked if at least one `get()` exists within it. - Similarly, using `set()` changes the transaction to indicate that changes to this particular on-chain state are updated only when the transaction is received by the Mina network if it contains a valid authorization (usually, a valid authorization is a proof). The logic also uses the `.mul()` method for multiplication of the values stored in `Field` types. You can view all available [methods](/zkapps/o1js-reference/classes/Field#methods) in the o1js Reference documentation. You remember that functions in your smart contract must operate on o1js compatible data types: `Field` types and other types built on top of `Field` types. Because a smart contract is really a zero knowledge circuit, functions from random npm packages work inside a smart contract only if the functions the contract provides operate on o1js-compatible data types. Importantly, data passed as an input to a smart contract method in o1js is private and never seen by the network. You can also store data publicly on-chain when needed, like `num` in this example. A later tutorial covers an example that leverages privacy. Congratulations, you have reviewed the complete smart contract code. ## Interact with a smart contract Next, write a script that interacts with your smart contract. As before, the complete [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file is provided. Follow these steps to build the `main.ts` file so you can interact with the smart contract. ### Imports For this tutorial, the `import` statement brings in items from `o1js` that you use to interact with your smart contract. 1. Copy the following lines from [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file into the `src/main.ts` file: ```ts src/main.ts 1 import { Square } from './Square.js'; 2 import { Field, Mina, PrivateKey, AccountUpdate } from 'o1js'; ``` These import items are: - `Field`: The same o1js unsigned integer type that you learned earlier. - `Mina`: A simulated local Mina blockchain to deploy the smart contract to so you can interact with it as a user would. - `PrivateKey`: A class with functions for manipulating private keys. - `AccountUpdate`: A class that generates a data structure that can update zkApp accounts. ### Simulated Local Blockchain Using a simulated local blockchain speeds up development and tests the behavior of your smart contract locally. Later tutorials cover how to use a lightweight Mina network (Lightnet) to test your zkApp before you deploy to live networks. :::info - The term _simulated local blockchain_ refers to the local testing blockchain you use in the first phase of testing as described here. - The term _Lightnet_ is used to describe the lightweight Mina network (Lightnet) that is a more accurate representation of the Mina blockchain. See [Testing zkApps with Lightnet](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet). ::: To initialize your simulated local blockchain, add the following code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to `src/main.ts`: ```ts src/main.ts 4 const useProof = false; 5 6 const Local = await Mina.LocalBlockchain({ proofsEnabled: useProof }); 7 Mina.setActiveInstance(Local); 8 9 const deployerAccount = Local.testAccounts[0]; 10 const deployerKey = deployerAccount.key; 11 const senderAccount = Local.testAccounts[1]; 12 const senderKey = senderAccount.key; ``` Tip: To preserve line numbers in your local `main.ts` file, add blank lines as needed after you copy the code snippets. This simulated local blockchain provides pre-funded accounts. Add these lines to create local test accounts with test MINA (tMINA) to use for this tutorial: ```ts src/main.ts 16 // ---------------------------------------------------- 17 18 // Create a public/private key pair. The public key is your address and where you deploy the zkApp to 19 const zkAppPrivateKey = PrivateKey.random(); 20 const zkAppAddress = zkAppPrivateKey.toPublicKey(); ``` ### Build and run the smart contract Now that the Square smart contract is complete, these commands run your project as a simulated local blockchain. To compile the TypeScript code into JavaScript: ```sh $ npm run build ``` To run the JavaScript code: ```sh $ node build/src/main.js ``` You have the option to combine these commands into one line: ``` npm run build && node build/src/main.js ``` - The `npm run build` command creates JavaScript code in the `build` directory. - The `&&` operator links two commands together. The second command runs only if the first command is successful. - The `node build/src/main.js` command runs the code in `src/main.ts`. ### Initialize your smart contract To initialize your smart contract, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file. All smart contracts that you create with the zkApp CLI use similar code: - Create a public/private key pair; the public key is an address on the Mina network where you deploy the zkApp to - Create an instance of your smart contract `Square` and deploy it to `zkAppAddress` - Get the initial state of `Square` after deployment Comments break down each stage: ```ts src/main.ts 21 22 // create an instance of Square - and deploy it to zkAppAddress 23 const zkAppInstance = new Square(zkAppAddress); 24 const deployTxn = await Mina.transaction(deployerAccount, async () => { 25 AccountUpdate.fundNewAccount(deployerAccount); 26 await zkAppInstance.deploy(); 27 }); 28 await deployTxn.sign([deployerKey, zkAppPrivateKey]).send(); 29 30 // get the initial state of Square after deployment 31 const num0 = zkAppInstance.num.get(); 32 console.log('state after init:', num0.toString()); ``` Try running this command again: ```sh $ npm run build && node build/src/main.js ``` The expected output is: ```sh > 01-hello-world@0.1.0 build > tsc state after init: 3 ``` ### Update your zkApp account with a transaction To update your local zkApp account with a transaction, add the following code to the `src/main.ts` file: ```ts src/main.ts 33 34 // ---------------------------------------------------- 35 36 const txn1 = await Mina.transaction(senderAccount, async () => { 37 await zkAppInstance.update(Field(9)); 38 }); 39 await txn1.prove(); 40 await txn1.sign([senderKey]).send(); 41 42 const num1 = zkAppInstance.num.get(); 43 console.log('state after txn1:', num1.toString()); ``` This code creates a new transaction that attempts to update the field to the value `9`. Because of the rules in the `update()` function that is called on the smart contract, this command succeeds when you run it again: ```sh $ npm run build && node build/src/main.js ``` The expected output is: ```sh > 01-hello-world@0.1.0 build > tsc state after init: 3 state after txn1: 9 ``` ### Add a transaction that fails It's time to do some testing. To add a transaction that fails, add more code from the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/01-hello-world/src/main.ts) example file to the `src/main.ts` file. The contract logic allows the number that is stored as on-chain state to be replaced only by its square. Now that `num` is in state `9`, updating is possible only with `81`. To test a failure, add these next lines of code from the `src/main.ts` file and change the state to `75` in `zkAppInstance.update(Field(75))`: ```ts src/main.ts 44 45 // ---------------------------------------------------- 46 47 try { 48 const txn2 = await Mina.transaction(senderAccount, async () => { 49 await zkAppInstance.update(Field(75)); 50 }); 51 await txn2.prove(); 52 await txn2.sign([senderKey]).send(); 53 } catch (error: any) { 54 console.log(error.message); 55 } 56 const num2 = zkAppInstance.num.get(); 57 console.log('state after txn2:', num2.toString()); ``` Try running this command again: ```sh $ npm run build && node build/src/main.js ``` The expected output is: ```sh > 01-hello-world@0.1.0 build > tsc state after init: 3 state after txn1: 9 Field.assertEquals(): 75 != 81 state after txn2: 9 ``` And finally, be sure to change your `main.ts` file to include the correct update to change the state to `81` in `zkAppInstance.update(Field(81))`. Run this command again: ```sh $ npm run build && node build/src/main.js ``` The expected output is: ```sh > 01-hello-world@0.1.0 build > tsc state after init: 3 state after txn1: 9 state after txn2: 81 ``` ## Follow along You can follow along in this video as cryptographer, David Wong, learns how to code a Hello World project. The video is provided for educational purposes and uses earlier versions of the zkApp CLI and o1js, so there are some differences. The Hello World tutorial always uses the most recent version of the zkApp CLI and o1js. ## Conclusion Congratulations! You have successfully completed all of the steps to build your first zkApp with o1js. Check out [Tutorial 2: Private Inputs and Hash Functions](private-inputs-hash-functions) to learn how to use private inputs and hash functions with o1js. Find more tutorials and resources in the [zkApps docs](/zkapps/writing-a-zkapp). --- url: /zkapps/tutorials/02-private-inputs-hash-functions --- # Tutorial 2: Private Inputs and Hash Functions In the [Hello World](hello-world) tutorial, you built a basic zkApp smart contract with o1js with a single state variable that could be updated if you knew the square of that number. In this tutorial, you learn about private inputs and hash functions. With a zkApp, a smart contract user's local device generates one or more zero knowledge proofs, which are then verified by the Mina network. Each method in a o1js smart contract corresponds to constructing a proof. All inputs to a smart contract are private by default. Inputs are never seen by the blockchain unless you store those values as on-chain state in the zkApp account. In this tutorial, you build a smart contract with a piece of private state that can be modified if a user knows the private state. ## Prerequisites This tutorial has been tested with [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.20.1`. Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. ## Create a project 1. Create or change to a directory where you have write privileges. 2. Create a project by using the `zk project` command: ```sh $ zk project 02-private-inputs-and-hash-functions ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ``` ? Create an accompanying UI project too? … next svelte nuxt empty > none ``` The expected output is: ```sh ✔ Create an accompanying UI project too? · none ✔ UI: Set up project ✔ Initialize Git repo ✔ Set up project ✔ NPM install ✔ NPM build contract ✔ Set project name ✔ Git init commit Success! Next steps: cd 02-private-inputs-and-hash-functions git remote add origin git push -u origin main ``` The `zk project` command creates the `02-private-inputs-and-hash-functions` directory that contains the scaffolding for your project, including tools such as the Prettier code formatting tool, the ESLint static code analysis tool, and the Jest Javascript testing framework. 1. Change into the `02-private-inputs-and-hash-functions` directory and list the contents: ```sh $ cd 02-private-inputs-and-hash-functions $ ls ``` The output shows these results: ```sh LICENSE README.md babel.config.cjs build config.json jest-resolver.cjs jest.config.js keys node_modules package-lock.json package.json src tsconfig.json ``` For this tutorial, you run commands from the root of the `02-private-inputs-and-hash-functions` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Prepare the project Start by deleting the default files that come with the new project. 1. To delete the default generated files: ```sh $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts ``` 1. Now, create the new files for your project: ```sh $ zk file src/IncrementSecret $ touch src/main.ts ``` - The `zk file` command created the `src/IncrementSecret.ts` file and the `src/IncrementSecret.test.ts` test file. - However, this tutorial does not include writing tests, so you just use the `main.ts` file as a script to interact with the smart contract and observe how it works. 1. Now, open `src/index.ts` in a text editor and change it to look like: ```ts import { IncrementSecret } from './IncrementSecret.js'; export { IncrementSecret }; ``` The `src/index.ts` file contains all of the exports you want to make available for consumption from outside your smart contract project, such as from a UI. ### Copy the example files This tutorial relies on the completed code in the [02-private-inputs-and-hash-functions/src/](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/02-private-inputs-and-hash-functions/src/) example files. 1. First, open the [IncrementSecret.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/02-private-inputs-and-hash-functions/src/IncrementSecret.ts) example file. 1. Copy the entire contents of the file into your smart contract in the `IncrementSecret.ts` file. 1. Next, open the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/02-private-inputs-and-hash-functions/src/main.ts) example file. 1. Copy the entire contents of the file into your smart contract in the `main.ts` file. Now you are ready to review the imports in the smart contract. ## Write the smart contract Now we'll build the smart contract for our application. ### Imports The `import` statement in the `IncrementSecret.ts` file brings in other packages and dependencies to use in your smart contract. :::info All functions used inside a smart contract must operate on o1js compatible data types: `Field` types and other types built on top of `Field` types. :::info ```ts ignore 1 import { Field, SmartContract, state, State, method, Poseidon } from 'o1js'; ``` ### Exports The smart contract called `IncrementSecret` has one element of on-chain state named `x` of type `Field` as defined by following code: ```ts ignore ... 3 export class IncrementSecret extends SmartContract { 4 @state(Field) x = State(); 5 } ``` This code adds the basic structure for the smart contract. You are familiar with the import and export code from [Tutorial 01: Hello World](hello-world). ### Initial State The `initState()` method is intended to run once to set up the initial state on the zkApp account. ```ts ignore ... 5 6 @method async initState(salt: Field, firstSecret: Field) { 7 this.x.set(Poseidon.hash([ salt, firstSecret ])); 8 } ``` The `initState()` method accepts your secret and adds a `salt` value. These inputs to the `initState()` method are private to whoever initializes the contract. The zkApp account on the chain does not reveal what the values `firstSecret` or `salt` actually are. ### Update the State This method updates the state: ```ts ignore ... 9 10 @method async incrementSecret(salt: Field, secret: Field) { 11 const x = this.x.get(); 12 this.x.requireEquals(x); 13 14 Poseidon.hash([ salt, secret ]).assertEquals(x); 15 this.x.set(Poseidon.hash([ salt, secret.add(1) ])); 16 } 17 } ``` Mina uses the Poseidon hash function that is optimized for fast performance inside zero knowledge proof systems. The Poseidon hash function takes in an array of Fields and returns a single Field as output. This smart contract uses a secret number and the second Field, `salt`. The `incrementSecret()` method checks that the hash of the salt and the secret is equal to the current state `x`: - If this is the case, add `1` to the secret and set `x` to the hash of the salt and this new secret. - o1js creates a proof of this fact and a JSON description of the state updates to be made on the zkApp account, such as to store the new hash value. - Together, this forms a transaction that can be sent to the Mina network to update the zkApp account. Because zkApp smart contracts are run off chain, your salt and secret remain private and are never transmitted anywhere. Only the result, updating `x` on-chain state to `hash([ salt, secret + 1])` is revealed. Because the salt and secret can't be deduced from their hash, they remain private. ### About the `salt` argument Cryptographic salt adds an additional layer of security to a smart contract. The extra `salt` argument prevents a possible attack on the smart contract. If you just use `secret`, the contract is vulnerable to discovery by an attacker. An attacker could try hashing likely secrets and then check if the hash matches the hash stored in the smart contract. If the hash were to match, then the attacker knows they have discovered the secret. This scenario is particularly concerning if the secret is likely to be within a particular subset of possible values, say between 1 and 10,000. In that case, with just 10,000 hashes, the attacker could discover the secret. Adding salt as a second input to the contract code makes it harder for an attacker to reverse engineer the code and gain access to the contract. Salt makes the contract more secure and helps protect the data stored within it. For optimal security, the salt is known only to you and is typically random. ## Main The `src/main.ts` file is similar to the Hello World tutorial. For a full version, see [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/02-private-inputs-and-hash-functions/src/main.ts). For this tutorial, the key parts to discuss are initializing our contract and using the poseidon hash. The smart contract initialization this time is: ```ts ignore ... 24 const salt = Field.random(); ... 28 const deployTxn = await Mina.transaction(deployerAccount, async () => { 29 AccountUpdate.fundNewAccount(deployerAccount); 30 await zkAppInstance.deploy(); 31 await zkAppInstance.initState(salt, Field(750)); 32 }); 33 await deployTxn.prove(); ... ``` Note that the `initState()` method accepts the salt and the secret. In this case, the secret is the number `750`. This code creates a user transaction to update the on-chain state: ```ts ... 42 const txn1 = await Mina.transaction(senderAccount, async () => { 43 await zkAppInstance.incrementSecret(salt, Field(750)); 44 }); ... ``` Call the zkApp smart contract with both the salt and the secret (the number `750`). Because zkApp smart contracts are executed locally, neither the secret nor the salt are part of the transaction. Instead, the transaction includes only the proof that the update was called in such a way that all assertions passed and an update to the on-chain state `x` where the hash value is stored. After the transaction is processed by the Mina network, `x` is the value of `Poseidon.hash([ salt, Field(750).add(1) ])`. The underlying salt and secret are not revealed. Try running `main`: ```sh $ npm run build && node build/src/main.js ``` The output looks something like this: ```text state after init: 3116464240601550031577632290308565252747064306168758166756574536757280262269 state after txn1: 15333363135506653312218020664441564145350761288169575380089681962972642150348 ``` The `state` strings are different because `Field.random()` generates the salt. ## Conclusion Congratulations! You built a smart contract that uses privacy and hash functions. To deploy zkApps to a live network, see [Tutorial 3: Deploy to a Live Network](deploying-to-a-network). --- url: /zkapps/tutorials/03-deploying-to-a-network --- # Tutorial 3: Deploy to a Live Network In previous tutorials, you learned how to deploy and execute transactions on a local network. In this tutorial, you will use the `zk config` command to create the deploy alias, request tMINA funds to pay for transaction fees, and deploy zkApp to a live network. This tutorial reuses the `Square` contract that you created in [Tutorial 1: Hello World](hello-world). ## Prerequisites This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.20.1` - [o1js](https://www.npmjs.com/package/o1js) version `1.1.0`. Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. If you have earlier versions of the zkApp CLI and o1js installed, be sure to [Update the zkApp CLI](/zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli#update-the-zkapp-cli) to the latest version: ```sh npm update -g zkapp-cli ``` ## Create a project 1. Create or change to a directory where you have write privileges. 2. Create a project by using the `zk project` command: ```sh $ zk project 03-deploying-to-a-live-network ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ``` ? Create an accompanying UI project too? … next svelte nuxt empty > none ``` The expected output is: ```sh ✔ Create an accompanying UI project too? · none ✔ UI: Set up project ✔ Initialize Git repo ✔ Set up project ✔ NPM install ✔ NPM build contract ✔ Set project name ✔ Git init commit Success! Next steps: cd 03-deploying-to-a-live-network git remote add origin git push -u origin main ``` The `zk project` command creates the `03-deploying-to-a-live-network` directory that contains the scaffolding for your project, including tools such as the Prettier code formatting, the ESLint static code analysis, and the Jest JavaScript testing framework. 1. Change into the `03-deploying-to-a-live-network` directory. For this tutorial, you run commands from the root of the `03-deploying-to-a-live-network` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Prepare the project Start by deleting the default files that come with the new project. 1. Delete the default generated files: ```sh $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts ``` 1. Copy the `src/Square.ts` and `src/index.ts` files from the files of the first tutorial [01-hello-world/src](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/01-hello-world/src) to your local `03-deploying-to-a-live-network/src` directory. If prompted, replace existing files. Now that your smart contract is in place, you are ready to deploy your zkApp to Devnet. ## zkApp CLI You installed the zkApp CLI as part of the [Prerequisites](/zkapps/tutorials#prerequisites), so you already have the tools to manage deployments. In some cases, you might need to create a custom account for your zkApp, programmatically parameterize a zkApp before you initialize it, or create a smart contract programmatically for users as part of an application. For details, please see [Interacting with zkApps server-side](/zkapps/tutorials/interacting-with-zkapps-server-side). ## Deploy the smart contract The `config.json` configuration file contains the configuration to deploy your zkApp. This file was automatically created during the project scaffold with the `zk project` command. However, the generated configuration file does not yet contain the deploy alias. ### Deploy alias The `zk config` command prompts guide you to create a deploy alias in your project `config.json` file. You can have one or more deploy aliases for your project. A deploy alias consists of: - A self-describing name that can be anything. Using naming patterns is helpful when you have more than one deploy alias. - The target network kind (`Testnet`, `Mainnet` or custom network kind id) - The Mina GraphQL API URL that defines the network that receives your deploy transaction and broadcasts it to the appropriate Mina network (Testnet, Devnet, Mainnet, and so on) - The transaction fee (in MINA) to use when deploying - Two key pairs: - A key pair for the zkApp account. Public and private keys to use in your application are automatically generated in `keys/.json`. - A key pair to use as a fee payer account for updates and deployments. Public and private keys are stored on your local computer and can be used across multiple projects. - Fee payer account alias - A fee payer account is required, you can choose to use an existing account or create a new fee payer account. 1. To configure your deploy alias, run the `zk config` command and respond to the prompts: ```sh $ zk config ``` For this tutorial on Devnet, use: - Deploy alias name: `devnet` This tutorial uses `devnet`, but the deploy alias name can be anything and does not have to match the network name. - Target network kind: `Testnet` - Mina GraphQL API URL: `https://api.minascan.io/node/devnet/v1/graphql` - Transaction fee to use when deploying (in MINA): `0.1` 1. When prompted to choose an account to pay transaction fees, select: ```text Use a different account (select to see options) ``` If this is the first time you are running the `zk config` command, you see these options: ```text > Recover fee payer account from an existing base58 private key Create a new fee payer key pair ``` A third option to choose another saved fee payer account is shown only if you have multiple cached fee payer accounts. 1. Select to create a new fee payer key pair: ```sh Create a new fee payer key pair NOTE: the private key will be stored in plain text on this computer. ``` Please mind the note above and **do not** use the fee payer account that holds a substantial amount of MINA. 1. When prompted, give an alias to your new fee payer key pair. For this tutorial, use `03-deploy`: ```sh ✔ Create an alias for this account · 03-deploy ``` Your key pairs and deploy alias are created: ```sh ✔ Create fee payer key pair at ${HOME}/.cache/zkapp-cli/keys/03-deploy.json ✔ Create zkApp key pair at keys/devnet.json ✔ Add deploy alias to config.json Success! Next steps: - If this is the testnet, request tMINA at: https://faucet.minaprotocol.com/?address= - To deploy zkApp, run: `zk deploy devnet` ``` 1. Request funds from the Testnet Faucet to fund your fee payer account. Follow the prompts to request tMINA. To get funds on the Devnet, use the URL that was shown in the zkApp CLI output: - Visit `https://faucet.minaprotocol.com/?address=` - Choose the corresponding network you're going to deploy your zkApp to (`Devnet` in this case) - And click the **Request** button Before proceeding to the next step, wait a few minutes for the next block to include your transaction, so that tMINA becomes available for the fee payer account. 1. To deploy your project execute the following command: ```sh $ zk deploy ``` 1. At the interactive prompt, select the `devnet` deploy alias: ```text ? Which deploy alias would you like to deploy to? … > devnet ``` A verification key for your smart contract is generated (takes 10-30 seconds). The deploy process is output: ```text ✔ Build project ✔ Generate build.json ✔ Choose smart contract Only one smart contract exists in the project: Square Your config.json was updated to always use this smart contract when deploying to this deploy alias. ✔ Generate verification key (takes 10-30 sec) ✔ Build transaction ``` 1. Review and confirm the details of the transaction: ```text ✔ Confirm to send transaction |-----------------|-------------------------------------------------| | Deploy alias | devnet | |-----------------|-------------------------------------------------| | Network kind | testnet | |-----------------|-------------------------------------------------| | URL | https://api.minascan.io/node/devnet/v1/graphql | |-----------------|-------------------------------------------------| | Fee payer | Alias : 03-deploy | | | Account : B62... | |-----------------|-------------------------------------------------| | zkApp | Smart contract: Square | | | Account : B62... | |-----------------|-------------------------------------------------| | Transaction fee | 0.1 Mina | |-----------------|-------------------------------------------------| ``` When prompted, type `yes` to confirm and send the transaction to the network. ```text ✔ Send to network Success! Deploy transaction sent. Next step: Your smart contract will be live (or updated) at B62... as soon as the transaction is included in a block: https://minascan.io/devnet/tx/?type=zk-tx ``` 1. To see the zkApp transaction and navigate to accounts involved you can follow the transaction link provided to you in zkApp CLI output. Or use the [Minascan](https://minascan.io) explorer to search for the account with deployed zkApp. ## Success After the transaction is included in a block, your smart contract is deployed! - The Mina account used to deploy the zkApp now contains the verification key associated with this smart contract. You ran the `zk config` command to: - Create a deploy alias - Create a fee payer key pair at `${HOME}/.cache/zkapp-cli/keys/03-deploy.json` - Create a zkApp key pair at `keys/devnet.json` You requested tMINA to fund your fee payer account and pay your deploy transaction fees. Use the remaining tMINA to keep building and testing. You ran the `zk deploy` command to: - Generate a verification key for your smart contract - Add send the deploy transaction to the network Congratulations! To test, configure, and deploy your zkApp on a local representation of the Mina blockchain, see [Testing zkApps with Lightnet](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet). ## About the Smart Contract Transactions Because this tutorial used the smart contract from `Tutorial 1: Hello World`, the smart contract's `editState` permissions require that the transaction must contain a valid zk proof that was created by the private key associated with this zkApp account. - When a user interacts with this smart contract by providing a proof, the proof is generated locally on the user's device and included in a transaction. - When the transaction is submitted to the network, the proof is checked to ensure it is correct and matches the on-chain verification key. - After the transaction is accepted, the proof and transaction are recursively proved and bundled into Mina's recursive zero knowledge proof. When you change the smart contract code, the associated verification key also changes. Use the same steps to redeploy your zkApp. For a typical smart contract, permissions are set to only allow proof authorization. You learn more about setting permissions in the later tutorials. ## Video Watch this tutorial for a step-by-step guide and extra explanations on how to deploy a zkApp. The video is provided for educational purposes and uses earlier versions of the zkApp CLI and o1js, so there are some differences. This tutorial is tested with a specific version of the zkApp CLI and o1js. ## Conclusion Congratulations! You have successfully deployed a smart contract to a live network. Check out [Tutorial 4: Build a zkApp UI in the Browser with React](zkapp-ui-with-react) to implement a browser UI that interacts with a smart contract. --- url: /zkapps/tutorials/04-zkapp-ui-with-react --- # Tutorial 4: Build a zkApp UI in the Browser with React You're making excellent progress in your zkApp journey: - In the [Hello World](hello-world) tutorial, you built a basic zkApp smart contract with o1js. - In [Tutorial 3: Deploy to a Live Network](deploying-to-a-network), you used the `zk` commands to deploy your zkApp. In this tutorial, you are going to implement a browser UI using `Next.js` that interacts with a smart contract. ## Prerequisites - Make sure you have the latest version of the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` - Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. - The Auro Wallet browser extension wallet that supports interactions with zkApps. See [Install a Wallet](/using-mina/install-a-wallet) and create a MINA account. This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.21.6` - [o1js](https://www.npmjs.com/package/o1js) version `1.8.0` - [Auro Wallet](https://www.aurowallet.com/) version `2.2.15` ## High-Level Overview In this tutorial, you create a new GitHub repository so you can deploy the UI to GitHub Pages. You use example code and the zkApp CLI to build an application that: 1. Loads a public key from an extension-based wallet. 1. Checks if the public key has funds and if not, directs the user to the Faucet. 1. Connects to the example zkApp `Add` smart contract that is already deployed on Devnet (or other network) at a fixed address. 1. Implements a button that sends a transaction. 1. Implements a button that requests the latest state of the smart contract. 1. Deploys the zkApp to GitHub Pages. Like previous tutorials, you use the provided [example files](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/) so you can focus on the React implementation itself. ## Create a project You can have the `zk project` command scaffold the UI for your project. 1. Create or change to the directory where you have write privileges. 1. Create a project by using the `zk project` command: ```sh $ zk project 04-zkapp-browser-ui ``` To scaffold the UI for your project with the `Next.js` React framework, select `next`: ```sh ? Create an accompanying UI project too? … > next svelte nuxt empty none ``` 1. If you are prompted to install the required Next packages, press **y** to proceed. 1. Select **yes** at the `? Do you want to set up your project for deployment to Github Pages? …` prompt. 1. If you are prompted to install the required Next packages, press **y** to proceed. 1. Select **No** at the `? Would you like to use ESLint with this project?` prompt. 1. Select **No** at the `? Would you like to use Tailwind CSS with this project?` prompt. Your UI is created in the project directory: `04-zkapp-browser-ui/ui` with two directories: - `contracts`: The smart contract code - `ui`: Where you write the UI code For this tutorial, you run commands from the root of the `04-zkapp-browser-ui/ui` directory. You work in the `ui/app` directory on TypeScript files that contain the UI code. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Install the dependencies When you ran the `zk project` command, your UI was created in the project directory: `04-zkapp-browser-ui/ui`. The project has two sub-directories: - `contracts`: The smart contract code - `ui`: The UI application code The dependencies in each sub-directory are installed automatically by the zkApp CLI. ## Create a repository To interact with a deployed zkApp UI on GitHub pages, you must create a GitHub repository. Go ahead and create your repository now. For other projects, you can name your GitHub repository anything you want. For this tutorial, use `04-zkapp-browser-ui`. 1. Go to [https://github.com/new](https://github.com/new). 1. For the **Repository name**, enter `04-zkapp-browser-ui`. 1. Optionally, add a description and a README. Your project repository is ready to use. ### Preparing the project Start by deleting the default `page.tsx` file that comes with a new project so that you have a clean project to work with. 1. In the `04-zkapp-browser-ui/ui` directory: ```sh $ rm app/page.tsx ``` ### Install UI dependencies This tutorial uses the `comlink` package to integrate web workers into the React application. Comlink simplifies communication between the main thread and web workers by abstracting the `postMessage` API, allowing you to call functions in the worker as if they were local. In the `04-zkapp-browser-ui/ui` directory, install `comlink` by running the following command: ```sh $ npm install comlink ``` To learn more about `comlink` , read the [documentation](https://www.npmjs.com/package/comlink). ### Download helper files Because o1js code is computationally intensive, it's helpful to use web workers. A web worker handles requests from users to ensure the UI thread isn't blocked during long computations like compiling a smart contract or proving a transaction. 1. Download the helper files from the `examples/zkapps/04-zkapp-browser-ui` directory on GitHub: - [zkappWorker.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/app/zkappWorker.ts) - [zkappWorkerClient.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/app/zkappWorkerClient.ts) 1. Move the files to your local `04-zkapp-browser-ui/ui/app` directory. 1. Review each helper file to see how they work and how you can extend them for your own zkApp. - `zkappWorker.ts` is the web worker code - `zkappWorkerClient.ts` is the client code that is run from React to interact with the web worker ### Download the main browser UI logic file The example project has a completed app. The `page.tsx` file is the entry file for your application and contains the main logic for the browser UI that is ready to deploy to GitHub Pages. 1. Download the [page.tsx](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/04-zkapp-browser-ui/ui/app/page.tsx) example file. 1. Move the `page.tsx` file to your local `04-zkapp-browser-ui/ui/app` directory. ## Build the default contract This tutorial uses the default contract `Add` that is always scaffolded with the `zk project` command. To build the default contract so that it can be used with UI application, run this command from the `04-zkapp-browser-ui/contracts` directory: ```sh $ npm run build ``` Outside of this tutorial, the workflow for building your own zkApp is to edit files in the `contracts` folder, rebuild the contract, and then access it from your UI application code. ## Implement the UI The UI application has several components: the React page itself and the code that uses o1js. ### Setup web workers The web worker code resides in the `04-zkapp-browser-ui/ui/app/zkappWorker.ts` file. Here, you define the functions that will be executed in the worker thread. #### Defining State The state object holds references to the zkApp Instance, Add contract instance, and the transactions. ```ts ignore const state = { AddInstance: null as null | typeof Add, zkappInstance: null as null | Add, transaction: null as null | Transaction, }; ``` ##### Defining functions that will run in the worker thread These functions perform tasks such as setting up the network instance, loading and compiling the smart contract, fetching accounts, interacting with the smart contract, and handling transactions. The functions will run in the web worker thread to ensure the UI thread is not blocked during long computations. ```ts ignore export const api = { async setActiveInstanceToDevnet() { const Network = Mina.Network('https://api.minascan.io/node/devnet/v1/graphql'); console.log('Devnet network instance configured'); Mina.setActiveInstance(Network); }, async loadContract() { const { Add } = await import('../../contracts/build/src/Add.js'); state.AddInstance = Add; }, async compileContract() { await state.AddInstance!.compile(); }, async fetchAccount(publicKey58: string) { const publicKey = PublicKey.fromBase58(publicKey58); return fetchAccount({ publicKey }); }, async initZkappInstance(publicKey58: string) { const publicKey = PublicKey.fromBase58(publicKey58); state.zkappInstance = new state.AddInstance!(publicKey); }, async getNum() { const currentNum = await state.zkappInstance!.num.get(); return JSON.stringify(currentNum.toJSON()); }, async createUpdateTransaction() { state.transaction = await Mina.transaction(async () => { await state.zkappInstance!.update(); }); }, async proveUpdateTransaction() { await state.transaction!.prove(); }, async getTransactionJSON() { return state.transaction!.toJSON(); }, }; ``` #### Expose functions to the main thread with `comlink` ```ts ignore // Expose the API to be used by the main thread Comlink.expose(api); ``` #### Creating the worker client - The web worker client code resides in the `04-zkapp-browser-ui/ui/app/zkappWorkerClient.ts` file. Here you create a client in the main thread that interacts with the web worker. - `worker` is a reference to the web worker instance and `remoteApi` is a reference to a proxy object that provides typesafe access to the worker's API methods. ```ts export default class ZkappWorkerClient { worker: Worker; // Proxy to interact with the worker's methods as if they were local remoteApi: Comlink.Remote; ``` In the constructor create a new Worker instance pointing to the `zkappWorker.ts` file. ```ts constructor() { // Initialize the worker from the zkappWorker module const worker = new Worker(new URL('./zkappWorker.ts', import.meta.url), { type: 'module' }); ``` With `Comlink.wrap`, create a proxy object `remoteApi` that provides typesafe access the worker's API methods. ```ts // Wrap the worker with Comlink to enable direct method invocation this.remoteApi = Comlink.wrap(this.worker); ``` Define methods in the ZkappWorkerClient class that call the corresponding method on `remoteApi`, effectively forwarding the calls to the worker. ```ts async setActiveInstanceToDevnet() { return this.remoteApi.setActiveInstanceToDevnet(); } async loadContract() { return this.remoteApi.loadContract(); } async compileContract() { return this.remoteApi.compileContract(); } async fetchAccount(publicKeyBase58: string) { return this.remoteApi.fetchAccount(publicKeyBase58); } async initZkappInstance(publicKeyBase58: string) { return this.remoteApi.initZkappInstance(publicKeyBase58); } async getNum(): Promise { const result = await this.remoteApi.getNum(); return Field.fromJSON(JSON.parse(result as string)); } async createUpdateTransaction() { return this.remoteApi.createUpdateTransaction(); } async proveUpdateTransaction() { return this.remoteApi.proveUpdateTransaction(); } async getTransactionJSON() { return this.remoteApi.getTransactionJSON(); } ``` ### Environment configuration - In `04-zkapp-browser-ui/ui/app/page.tsx` ```ts ignore let transactionFee = 0.1; const ZKAPP_ADDRESS = 'B62qpXPvmKDf4SaFJynPsT6DyvuxMS9H1pT4TGonDT26m599m7dS9gP'; ``` The smart contract that the UI interacts with in this tutorial has been deployed to the Devnet and the public key is stored in the `ZKAPP_ADDRESS` variable. If you experience problems with the deployed contract, you can [deploy](deploying-to-a-network) the `Add` contract included in the `contracts` folder yourself to any other network. When deployed, replace `ZKAPP_ADDRESS` variable with the public key of your own deployed zkApp. - In `04-zkapp-browser-ui/ui/app/zkappWorker.ts` ```ts ignore async setActiveInstanceToDevnet() { const Network = Mina.Network('https://api.minascan.io/node/devnet/v1/graphql'); console.log('Devnet network instance configured'); Mina.setActiveInstance(Network); }, ``` Depending on the network you are going to work with you might want to consider changing the GraphQL endpoint in the `setActiveInstanceToDevnet` function. Mind the supported networks by `Auro Wallet` though. :::info In this example, the `o1js` code is included in a client component and executed on the client side using an effect after the page loads. If you're integrating `o1js` within a server component, be aware that Next.js's caching mechanism might cause `o1js` to return outdated data. To prevent this, you can disable caching by adding `export const revalidate = 0;` to your component. For more details, refer to the [Next.js caching documentation](https://nextjs.org/docs/app/building-your-application/caching#opting-out-2). ::: ### Add state These `04-zkapp-browser-ui/ui/app/page.tsx` statements creates mutable state that you can reference in the UI. The state updates as the application runs: ```ts ignore ... const [zkappWorkerClient, setZkappWorkerClient] = useState(null); const [hasWallet, setHasWallet] = useState(null); const [hasBeenSetup, setHasBeenSetup] = useState(false); const [accountExists, setAccountExists] = useState(false); const [currentNum, setCurrentNum] = useState(null); const [publicKeyBase58, setPublicKeyBase58] = useState(''); const [creatingTransaction, setCreatingTransaction] = useState(false); const [displayText, setDisplayText] = useState(''); const [transactionlink, setTransactionLink] = useState(''); ... ``` To learn more about `useState` hooks, see [built-in React hooks](https://react.dev/reference/react/hooks#state-hooks) in the React API reference documentation. ### zkApp setting up This `04-zkapp-browser-ui/ui/app/page.tsx` code adds a functions to set up zkApp: - The Boolean `hasBeenSetup` ensures that the react feature `useEffect` is run only once. To learn more about `useEffect` hooks, see [useEffect](https://react.dev/reference/react/useEffect) in the React API reference documentation. - This code also sets up your web worker client that interacts with the web worker running o1js code to ensure the computationally heavy o1js code doesn't block the UI thread. #### Load web worker and setup Mina active instance ```ts ignore ... displayStep('Loading web worker...') const zkappWorkerClient = new ZkappWorkerClient(); setZkappWorkerClient(zkappWorkerClient); await new Promise((resolve) => setTimeout(resolve, 5000)); displayStep('Done loading web worker') await zkappWorkerClient.setActiveInstanceToDevnet(); ... ``` #### Connect Auro Wallet and setup fee payer account ```ts ignore ... const mina = (window as any).mina; if (mina == null) { setHasWallet(false); displayStep('Wallet not found.'); return; } const publicKeyBase58: string = (await mina.requestAccounts())[0]; setPublicKeyBase58(publicKeyBase58); displayStep(`Using key:${publicKeyBase58}`); displayStep('Checking if fee payer account exists...'); const res = await zkappWorkerClient.fetchAccount( publicKeyBase58, ); const accountExists = res.error === null; setAccountExists(accountExists); ... ``` #### Import the contract code, instantiate zkApp instance, compile the contract and fetch zkApp state ```ts ignore ... await zkappWorkerClient.loadContract(); displayStep('Compiling zkApp...'); await zkappWorkerClient.compileContract(); displayStep('zkApp compiled'); await zkappWorkerClient.initZkappInstance(ZKAPP_ADDRESS); displayStep('Getting zkApp state...'); await zkappWorkerClient.fetchAccount(ZKAPP_ADDRESS); const currentNum = await zkappWorkerClient.getNum(); setCurrentNum(currentNum); console.log(`Current state in zkApp: ${currentNum}`); ... ``` #### Update the state of the React application ```ts ignore ... setHasBeenSetup(true); setHasWallet(true); setDisplayText(''); ... ``` ### Run the React app Execute the following commands being within the `04-zkapp-browser-ui/ui/` directory. 1. To start the development server and serve your UI application at the URL `localhost:3000`: ```sh $ npm run dev ``` You can also change the default port by starting the dev server with the `--port` CLI argument. For example, to start the dev server on port `8001`, run: ```sh $ npm run dev -- --port 8001 ``` The zkApp UI in the web browser shows the current state of the zkApp and has buttons to send a transaction and get the latest zkApps on-chain state. Your browser refreshes automatically when you update the source code. 1. If prompted, request the funds from the Testnet Faucet service to fund your fee payer account. 1. And in the second terminal window: ```sh $ npm run ts-watch ``` This command starts the installed TypeScript compiler (`tsc`) with `--watch` parameter, with the ability to react to compilation status. ### Wait for the fee payer account to be funded Now that the UI setup is finished, a new useEffect waits for the fee payer account to be funded if it didn't before by checking the account presence in ledger. Don't forget that if the account has been newly created, it must be funded from the Faucet. ```ts ignore ... useEffect(() => { const checkAccountExists = async () => { if (hasBeenSetup && !accountExists) { try { for (;;) { displayStep('Checking if fee payer account exists...'); const res = await zkappWorkerClient!.fetchAccount(publicKeyBase58); const accountExists = res.error == null; if (accountExists) { break; } await new Promise((resolve) => setTimeout(resolve, 5000)); } } catch (error: any) { displayStep(`Error checking account: ${error.message}`); } } setAccountExists(true); }; checkAccountExists(); }, [zkappWorkerClient, hasBeenSetup, accountExists]); ... ``` ### Let UI buttons do some useful work These functions will be triggered on buttons press. ```ts ignore ... const onSendTransaction = async () => { setCreatingTransaction(true); displayStep('Creating a transaction...'); console.log('publicKeyBase58 sending to worker', publicKeyBase58); await zkappWorkerClient!.fetchAccount(publicKeyBase58); await zkappWorkerClient!.createUpdateTransaction(); displayStep('Creating proof...'); await zkappWorkerClient!.proveUpdateTransaction(); displayStep('Requesting send transaction...'); const transactionJSON = await zkappWorkerClient!.getTransactionJSON(); displayStep('Getting transaction JSON...'); const { hash } = await (window as any).mina.sendTransaction({ transaction: transactionJSON, feePayer: { fee: transactionFee, memo: '', }, }); const transactionLink = `https://minascan.io/devnet/tx/${hash}`; setTransactionLink(transactionLink); setDisplayText(transactionLink); setCreatingTransaction(true); }; const onRefreshCurrentNum = async () => { try { displayStep('Getting zkApp state...'); await zkappWorkerClient!.fetchAccount(ZKAPP_ADDRESS); const currentNum = await zkappWorkerClient!.getNum(); setCurrentNum(currentNum); console.log(`Current state in zkApp: ${currentNum}`); setDisplayText(''); } catch (error: any) { displayStep(`Error refreshing state: ${error.message}`); } }; ``` ### Take care of the page markup ```ts ignore ... let auroLinkElem; if (hasWallet === false) { const auroLink = 'https://www.aurowallet.com/'; auroLinkElem = ( ); } const stepDisplay = transactionlink ? ( View transaction ) : ( displayText ); let setup = (
    {stepDisplay} {auroLinkElem}
    ); let accountDoesNotExist; if (hasBeenSetup && !accountExists) { const faucetLink = `https://faucet.minaprotocol.com/?address='${publicKeyBase58}`; accountDoesNotExist = ( ); } let mainContent; if (hasBeenSetup && accountExists) { mainContent = (
    Current state in zkApp: {currentNum?.toString()}{' '}
    ); } return (
    {setup} {accountDoesNotExist} {mainContent}
    ); ``` The UI has three sections: - `setup` lets the user know when the zkApp has finished loading. - `accountDoesNotExist` gives the user a link to the Faucet if their account hasn't been funded. - `mainContent` shows the current zkApp on-chain state and buttons to let users interact with zkApp. The buttons allow the user to create transaction in order to update on-chain zkApp state and refresh the current on-chain zkApp state. That's it for the code review! If you've been using `npm run dev`, you can now interact with the UI application on [`localhost:3000`](http://localhost:3000). ## Deploying the application to GitHub Pages Before you can deploy your project to GitHub Pages, you must push it to a new GitHub repository that you've created at the beginning of this tutorial. - The GitHub repo must have the same name as the project name. - In this tutorial, the project name is `04-zkapp-browser-ui`. - The `zk project` command created the correct project name strings in the `next.config.js` and `src/pages/reactCOIServiceWorker.ts` files. To deploy the UI: 1. Change to the `04-zkapp-browser-ui/ui/` directory. 1. Run the `deploy` script by executing the following command: ```sh npm run deploy ``` Scripts defined in the `04-zkapp-browser-ui/ui/package.json` file do the work to build your application and publish it to the GitHub Pages. After the command completion your zkApp UI will be available at: ``` https://.github.io/04-zkapp-browser-ui/ ``` where `` is your GitHub username. ## Conclusion Congratulations! You built a React UI for your zkApp that allows users to interact with deployed smart contract. You can build UI for your zkApps using other frameworks like `SvelteKit` and `NuxtJS`. You are ready to continue with [Tutorial 5: Common Types and Functions](common-types-and-functions) to learn about different o1js types you can use in your zkApps. --- url: /zkapps/tutorials/05-common-types-and-functions --- # Tutorial 5: Common Types and Functions In previous tutorials, you learned how to deploy smart contracts to the network interact with them from a React UI and NodeJS. In this tutorial, you learn about types you can use when building with o1js. Earlier tutorials mostly use the `Field` type. o1js provides other higher-order types built from Fields that are useful for zkApp development and expand the possibilities for more applications. The [example project](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src) includes a [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts) file that shows all of the concepts presented in this tutorial, along with smart contracts showing more advanced usage of some of the concepts, particularly Merkle Trees. ## Prerequisites This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.20.1` - [o1js](https://www.npmjs.com/package/o1js) version `1.1.0`. Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. ## Basic Types Five basic types are derived from Fields: - [Bool](../o1js-reference/classes/Bool) - [UInt32](../o1js-reference/classes/UInt32) - [UInt64](../o1js-reference/classes/UInt64) - [Int64](../o1js-reference/classes/Int64) - [Character](../o1js-reference/classes/Character) Each type has the usual programming language semantics. For example, the following code: ```ts const num1 = UInt32.from(40); const num2 = UInt64.from(40); const num1EqualsNum2: Bool = num1.toUInt64().equals(num2); console.log(`num1 === num2: ${num1EqualsNum2.toString()}`); console.log(`Fields in num1: ${num1.toFields().length}`); // -------------------------------------- const signedNum1 = Int64.from(-3); const signedNum2 = Int64.from(45); const signedNumSum = signedNum1.add(signedNum2); console.log(`signedNum1 + signedNum2: ${signedNumSum}`); console.log(`Fields in signedNum1: ${signedNum1.toFields().length}`); // -------------------------------------- const char1 = Character.fromString('c'); const char2 = Character.fromString('d'); const char1EqualsChar2: Bool = char1.toField().equals(char2.toField()); console.log(`char1: ${char1}`); console.log(`char1 === char2: ${char1EqualsChar2.toString()}`); console.log(`Fields in char1: ${Character.toFields(char1).length}`); ``` This result prints to the console when the code is run: ``` num1 === num2: true Fields in num1: 1 signedNum1 + signedNum2: 42 Fields in signedNum1: 2 char1: c char1 === char2: false Fields in char1: 1 ``` ## More Advanced Types Four advanced types are: - [CircuitString](../o1js-reference/classes/CircuitString) - [PrivateKey](../o1js-reference/classes/PrivateKey) - [PublicKey](../o1js-reference/classes/PublicKey) - [Signature](../o1js-reference/classes/Signature) All arguments passed into smart contracts must be arguments o1js can consume. You cannot pass normal strings. Instead, you must pass in strings that are wrapped to be compatible with circuits. This is accomplished with `Struct`. The default `CircuitString` has a maximum length of 128 characters because o1js types must be fixed length. However, the `CircuitString` API abstracts this restriction away and can be used like a dynamic length string with the maximum length caveat. You can create custom types to build your own strings, modified to whatever length you want. A brief example of custom types: ```ts const str1 = CircuitString.fromString('abc..xyz'); console.log(`str1: ${str1}`); console.log(`Fields in str1: ${CircuitString.toFields(str1).length}`); // -------------------------------------- const zkAppPrivateKey = PrivateKey.random(); const zkAppPublicKey = zkAppPrivateKey.toPublicKey(); const data1 = Character.toFields(char2).concat(signedNumSum.toFields()); const data2 = Character.toFields(char1).concat(CircuitString.toFields(str1)); const signature = Signature.create(zkAppPrivateKey, data2); const verifiedData1 = signature.verify(zkAppPublicKey, data1).toString(); const verifiedData2 = signature.verify(zkAppPublicKey, data2).toString(); console.log(`private key: ${zkAppPrivateKey.toBase58()}`); console.log(`public key: ${zkAppPublicKey.toBase58()}`); console.log(`Fields in private key: ${zkAppPrivateKey.toFields().length}`); console.log(`Fields in public key: ${zkAppPublicKey.toFields().length}`); console.log(`signature verified for data1: ${verifiedData1}`); console.log(`signature verified for data2: ${verifiedData2}`); console.log(`Fields in signature: ${signature.toFields().length}`); ``` And the console output: ``` str1: abc..xyz Fields in str1: 128 private key: EKF714j3wgH3tuuQncL93ruQFbJGnhDzfWossAHUp15PdATKE7Ka public key: B62qrhsTdExJDAxQx76V1mc13ibzikpmNaNRShTG3MWedCXESBhQ2Ch Fields in private key: 2 Fields in public key: 2 signature verified for data1: false signature verified for data2: true Fields in signature: 3 ``` Observe and follow best practices for your key security. Make sure that you never use the private key in this example output, or any private key that's publicly accessible, in a real application. There are 255 Fields in a private key and 256 Fields in a signature. If you are curious about the reason for this, the answer is cryptographic in nature: Elliptic curve scalars are most efficiently represented in a SNARK as an array of bits, and the bit length of these scalars is 255. ## Struct You can create your own compound data types with the special [Struct](../o1js-reference/functions/Struct) type. Define a Struct as one or more data types that o1js understands. For example, Field, higher-order types built into o1js based on Field, or other Struct types defined by you. You can also define methods on your Struct to act upon this data type. The following example demonstrates how to use `Struct` to implement a `Point` structure and an array of points of length 8 structure. In o1js, programs are compiled into fixed-sized circuits. This means that data structures it consumes must also be a fixed size. To meet the fixed-size requirement, this code declares the array in `Points8` structure to be a static size of 8. ```ts class Point extends Struct({ x: Field, y: Field }) { static add(a: Point, b: Point) { return { x: a.x.add(b.x), y: a.y.add(b.y) }; } } const point1 = { x: Field(10), y: Field(4) }; const point2 = { x: Field(1), y: Field(2) }; const pointSum = Point.add(point1, point2); console.log(`pointSum Fields: ${Point.toFields(pointSum)}`); class Points8 extends Struct({ points: [Point, Point, Point, Point, Point, Point, Point, Point], }) {} const points = new Array(8) .fill(null) .map((_, i) => ({ x: Field(i), y: Field(i * 10) })); const points8: Points8 = { points }; console.log(`points8 JSON: ${JSON.stringify(points8)}`); ``` The console output: ``` pointSum Fields: 11,6 points8 Fields: {"points":[{"x":"0","y":"0"},{"x":"1","y":"10"},{"x":"2","y":"20"},{"x":"3","y":"30"},{"x":"4","y":"40"},{"x":"5","y":"50"},{"x":"6","y":"60"},{"x":"7","y":"70"}]} ``` ## Control Flow Two functions help do control flow in o1js: - Provable.if Similar to a ternary in JavaScript - Provable.switch Similar to a switch case statement in JavaScript You can write conditionals inside o1js with these functions. For example: ```ts const input1 = Int64.from(10); const input2 = Int64.from(-15); const inputSum = input1.add(input2); const inputSumAbs = Provable.if( inputSum.isPositive(), inputSum, inputSum.mul(Int64.minusOne) ); console.log(`inputSum: ${inputSum.toString()}`); console.log(`inputSumAbs: ${inputSumAbs.toString()}`); const input3 = Int64.from(22); const input1largest = input1 .sub(input2) .isPositive() .and(input1.sub(input3).isPositive()); const input2largest = input2 .sub(input1) .isPositive() .and(input2.sub(input3).isPositive()); const input3largest = input3 .sub(input1) .isPositive() .and(input3.sub(input2).isPositive()); const largest = Provable.switch( [input1largest, input2largest, input3largest], Int64, [input1, input2, input3] ); console.log(`largest: ${largest.toString()}`); ``` With output: ``` inputSum: -5 inputSumAbs: 5 largest: 22 ``` Both branches are executed when using `Provable.if`, like in a JavaScript ternary. Because o1js is creating a zk circuit, there is no primitive for `if` statements where only one branch is executed. ## Assertions and Constraints o1js functions are compiled to generate circuits. When a transaction is proven in o1js, the proof is that the program logic is computed according to the written program, and all assertions are holding true. In previous tutorials, you learned `a.assertEquals(b)`. The `.assertTrue()` is available on the Bool class. Circuits in o1js have a fixed maximum size. Each operation performed in a function counts towards this maximum size. This maximum size is equivalent to: - about 5,200 hashes on two fields - about 2,600 hashes on four fields - about `2^17` field multiplies - about `2^17` field additions If a program is too large to fit into these constraints, it can be broken up into multiple recursive proof verifications. See [Recursion](../o1js/recursion). ## Merkle Trees You can use [Merkle trees](../o1js-reference/classes/MerkleTree) to manage large amounts of data within a circuit. The power of Merkle trees is demonstrated in the [05-common-types-and-functions/src](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src) reference project for this tutorial. See the [BasicMerkleTreeContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/BasicMerkleTreeContract.ts) contract and [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/05-common-types-and-functions/src/main.ts) that demonstrates how contracts interact with Merkle trees and how to construct them. The first step is to import `MerkleTree`: ```ts ... MerkleTree, ... } from 'o1js' ``` To create Merkle trees in your application: ```ts const height = 20; const tree = new MerkleTree(height); ``` The height variable determines how many leaves are available to the application. For example, a height of 20 leads to a tree with `2^(20-1)`, or 524,288 leaves. Merkle trees in smart contracts are stored as the hash of the Merkle tree's root. Smart contract methods that update the Merkle root can take a _witness_ of the change as an argument. The [MerkleMapWitness](/zkapps/o1js-reference/classes/MerkleMapWitness) represents the Merkle path to the data for which inclusion is being proved. A contract stores the root of a Merkle tree, where each leaf stores a number, and the smart contract has an `update` function that adds a number to the leaf. For example, to put a condition on a leaf update, the `update` function checks that the number added was less than 10: ```ts ... @state(Field) treeRoot = State(); ... @method async initState(initialRoot: Field) { this.treeRoot.set(initialRoot); } @method async update( leafWitness: MerkleWitness20, numberBefore: Field, incrementAmount: Field ) { const initialRoot = this.treeRoot.get(); this.treeRoot.requireEquals(initialRoot); incrementAmount.assertLt(Field(10)); // check the initial state matches what we expect const rootBefore = leafWitness.calculateRoot(numberBefore); rootBefore.assertEquals(initialRoot); // compute the root after incrementing const rootAfter = leafWitness.calculateRoot( numberBefore.add(incrementAmount) ); // set the new root this.treeRoot.set(rootAfter); } ``` The code to interact with the smart contract: ```ts // initialize the zkapp const zkApp = new BasicMerkleTreeContract(basicTreeZkAppAddress); await BasicMerkleTreeContract.compile(); // create a new tree const height = 20; const tree = new MerkleTree(height); class MerkleWitness20 extends MerkleWitness(height) {} // deploy the smart contract const deployTxn = await Mina.transaction(deployerAccount, async () => { AccountUpdate.fundNewAccount(deployerAccount); await zkApp.deploy(); // get the root of the new tree to use as the initial tree root await zkApp.initState(tree.getRoot()); }); await deployTxn.prove(); deployTxn.sign([deployerKey, basicTreeZkAppPrivateKey]); const pendingDeployTx = await deployTxn.send(); /** * `txn.send()` returns a pending transaction with two methods - `.wait()` and `.hash` * `.hash` returns the transaction hash * `.wait()` automatically resolves once the transaction has been included in a block. this is redundant for the LocalBlockchain, but very helpful for live testnets */ await pendingDeployTx.wait(); const incrementIndex = 522n; const incrementAmount = Field(9); // get the witness for the current tree const witness = new MerkleWitness20(tree.getWitness(incrementIndex)); // update the leaf locally tree.setLeaf(incrementIndex, incrementAmount); // update the smart contract const txn1 = await Mina.transaction(senderPublicKey, async () => { await zkApp.update( witness, Field(0), // leafs in new trees start at a state of 0 incrementAmount ); }); await txn1.prove(); const pendingTx = await txn1.sign([senderPrivateKey, basicTreeZkAppPrivateKey]).send(); await pendingTx.wait(); // compare the root of the smart contract tree to our local tree console.log( `BasicMerkleTree: local tree root hash after send1: ${tree.getRoot()}` ); console.log( `BasicMerkleTree: smart contract root hash after send1: ${zkApp.treeRoot.get()}` ); ``` In this example, leaves are fields. However, you can put more variables in a leaf by hashing an array of fields and setting a leaf to that hash. This complete example is in the [project directory](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/05-common-types-and-functions/src). A more advanced example `LedgerContract` implements a basic ledger of tokens, including checks that the sender has signed their transaction and that the amount the sender has sent matches the amount the receiver receives. ## Merkle Map See the API reference documentation for the [MerkleMap](../o1js-reference/classes/MerkleMap) class you can use to implement key-value stores. The API for Merkle Maps is similar to Merkle Trees, just instead of using an index to set a leaf, one uses a key: ```ts const map = new MerkleMap(); const key = Field(100); const value = Field(50); map.set(key, value); console.log('value for key', key.toString() + ':', map.get(key)); ``` Which prints: ``` value for key 100: 50 ``` It can be used inside smart contracts with a witness, similar to merkle trees ```ts ... @state(Field) mapRoot = State(); ... @method async init(initialRoot: Field) { this.mapRoot.set(initialRoot); } @method async update( keyWitness: MerkleMapWitness, keyToChange: Field, valueBefore: Field, incrementAmount: Field, ) { const initialRoot = this.mapRoot.get(); this.mapRoot.requireEquals(initialRoot); incrementAmount.assertLt(Field(10)); // check the initial state matches what we expect const [ rootBefore, key ] = keyWitness.computeRootAndKey(valueBefore); rootBefore.assertEquals(initialRoot); key.assertEquals(keyToChange); // compute the root after incrementing const [ rootAfter, _ ] = keyWitness.computeRootAndKey(valueBefore.add(incrementAmount)); // set the new root this.treeRoot.set(rootAfter); } ``` With (abbreviated) code to interact with it, similar to the Merkle tree example above: ```ts const map = new MerkleMap(); const rootBefore = map.getRoot(); const key = Field(100); const witness = map.getWitness(key); ... // update the smart contract const txn1 = await Mina.transaction(deployerAccount, async () => { await zkapp.update( contract.update( witness, key, Field(50), Field(5) ); ); }); ... ``` You use [MerkleMaps](/zkapps/o1js-reference/classes/MerkleMap) to implement many useful patterns. For example: - A key value store from public keys to booleans, of token accounts to whether they've participated in a voted yet. - A nullifier that privately tracks if an input was used, without revealing it. ## Conclusion Congratulations! You have finished reviewing more common types and functions in o1js. With this, you should now be capable of writing many advanced smart contracts and zkApps. To use more data from your zkApp, check out [Tutorial 6](offchain-storage) to learn how to use off-chain storage. --- url: /zkapps/tutorials/06-offchain-storage --- # Tutorial 6: Off-Chain Storage In [Tutorial 5: Common Types and Functions](common-types-and-functions), you learned how to use Merkle trees to refer to large amounts of data stored off-chain. This tutorial presents a library and pattern to store Merkle trees off-chain and store only the tree's root hash on-chain. This approach is a step towards unlocking a larger set of applications that require off-chain storage. Future solutions can provide other decentralized options for zkApps that require more trustless solutions. :::experimental This proposed solution to off-chain storage is experimental and is used only for education purposes. ::: This tutorial provides a single-server solution to data storage for prototyping zkApps and building zkApps where some trust guarantees are reasonable. The solution proposed in this learning tutorial is appropriate for development, but is not recommended for zkApps that require trustlessness. The single-server solution for prototyping is intended as one of several options for data availability on Mina. Mina doesn't offer an out-of-the-box solution for off-chain storage. ## Why Off-Chain Storage? When you build an application for testing and local use, you can build and store a Merkle root locally. However, when you build a production-ready, distributed zkApp, you need more than this. All users that interact with your zkApp must be able to retrieve and modify the latest state. Any data that modifies a zkApp must be available somewhere for others users to access. ### Off-Chain Storage and Decentralization Solutions to storage span a large spectrum from inexpensive and more centralized to more expensive and more decentralized. The decentralized solutions are more expensive due to replicating and proving stored data. Your off-chain storage needs depend on the zkApp you are building and the guarantees you want that zkApp to have. Solutions under exploration: 1. A single-server storage solution, presented here. 2. A multi-server storage solution that can be run by multiple parties for stronger trust guarantees. 3. A solution that leverages storage on modular blockchains. 4. A future hard fork to add purchasable on-chain data storage to Mina. 5. A future hard fork to add data-storage committees to Mina for horizontally scalable storage. ### Single-Server Off-Chain Storage This tutorial implementation is the single-server off-chain storage solution. The library provides a REST server that anyone can run to store data for one or multiple zkApps and a zkApp library to check on-chain if changes have been backed by the server. This implementation requires a trust assumption for zkApps that use it: both developers and users must trust whoever is running the server. This trust assumption makes it useful for prototyping applications that need off-chain storage and for putting applications into production where these trust assumptions are reasonable. This implementation is not appropriate for zkApps where a trustless solution is needed. To learn more about this implementation and see how it works, see the [experimental-zkapp-offchain-storage](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/06-offchain-storage/experimental-zkapp-offchain-storage) library. ### Grant Opportunity to Develop Single-Server Off-Chain Storage Mina Foundation values contributions. You can improve this library to make it more decentralized and useful in production. This development opportunity seeks a developer to start with the library presented here, improve it, make it more decentralized, and run instances for the community. If you are interested in this grant opportunity, send an email to [build@minaprotocol.com](mailto:build@minaprotocol.com). Suggested improvements: - Eliminate DDOS vulnerability by adding a token that limits storage requests. - Do not store trees for a smart contract if that contract is misconfigured in a way to prevent cleaning up old data. - Add support to the client library for connecting to multiple storage servers, enabling correctness under a majority-honest assumption. - Switch the project to a more scalable database implementation (for example, Redis). - Write an implementation for an automatically scalable service (for example, Cloudflare). ## Implement a Project Using Off-Chain Storage The sample code for this project is provided at [examples/zkapps/06-offchain-storage/contracts](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts) with a focus on: - [src/main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts/src/main.ts) - [src/NumberTreeContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts/src/NumberTreeContract.ts) This project implements a Merkle tree where: - Each leaf is either empty or stores a number (an o1js field), which is the data. - Updates to the tree can update a leaf if the new number in the leaf is greater than the old number. - The root of the tree is stored on-chain. - The tree itself is stored on an off-chain storage server. ## Prerequisites - Make sure you have the latest version of the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` - Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.11.2` - [o1js](https://www.npmjs.com/package/o1js) version `0.12.1` ## Create the project 1. Create or change to a directory where you have write privileges. 1. Create a project by using the `zk project` command: ```sh $ zk project 06-off-chain-storage ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ``` ? Create an accompanying UI project too? … next svelte nuxt empty > none ``` ## Project structure The `zk project` command creates the `06-off-chain-storage` directory that contains the scaffolding for your project. The files in the `src` directory files contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. For all projects, you run `zk` commands from the root of your project directory. ## Prepare the project 1. Change to the project directory, delete the existing files, and create a new `src/NumberTreeContract` smart contract, and a `main.ts` file: ```sh $ cd 06-off-chain-storage $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts $ zk file src/NumberTreeContract $ touch src/main.ts ``` 1. Edit `index.ts` to import and export your new smart contract: ```ts import { NumberTreeContract } from './NumberTreeContract.js'; export { NumberTreeContract }; ``` 1. Now, add the experimental library for the off-chain storage server: ```sh $ npm install experimental-zkapp-offchain-storage --save ``` 1. Install the `xmlhttprequest-ts` TypeScript wrapper for the built-in HttpClient to emulate the browser XMLHttpRequest object: ```sh $ npm install --save xmlhttprequest-ts ``` This project uses this for network requests when running from Node.js where the browser's XMLHttpRequest is not available by default. ### Run your storage server When you start this experimental local storage server, a `database.json` file is created in the current directory to store data for this tutorial. In a new terminal window, run this command from the root directory of your project: ```sh $ node node_modules/experimental-zkapp-offchain-storage/build/src/storageServer.js ``` ## Implement the smart contract A full copy of the [NumberTreeContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts/src/NumberTreeContract.ts) example file is provided. 1. Open `NumberTreeContract.ts` in your editor. 1. Start by adding the imports: ```ts ignore SmartContract, Field, MerkleTree, state, State, method, DeployArgs, Signature, PublicKey, Permissions, Bool, } from 'o1js'; OffChainStorage, MerkleWitness8, } from 'experimental-zkapp-offchain-storage'; ... ``` Notice that you import some items from `experimental-zkapp-offchain-storage`: The `OffChainStorage` object contains the functions for interacting with off-chain storage: - `getPublicKey`: A function to get the storage server's public key. This key is also stored in smart contracts to identify what storage server is storing the smart contract's off-chain data. - `get`: A function for fetching the data for a Merkle tree from the storage server, given the root of the tree. - `requestStore`: A function to request storing a tree on the storage server. Returns a proof that the storage server has stored this tree. - `assertRootUpdateValid`: A function used in smart contracts to prove updates to the smart contract's currently stored tree root result in a tree root that is being stored by the storage server. - `mapToTree`: A storage function to convert maps to trees. Internally the storage server is using maps from tree indices to leafs. The `MerkleWitness8` is a type of Merkle tree witness required for o1js to use the same instances of the witness cross-library. Other types of Merkle trees are available for input, such as `MerkleWitness32` and `MerkleWitness256`. 3. Now, set up your smart contract: ```ts ignore ... export class NumberTreeContract extends SmartContract { @state(PublicKey) storageServerPublicKey = State(); @state(Field) storageNumber = State(); @state(Field) storageTreeRoot = State(); deploy(args: DeployArgs) { super.deploy(args); this.account.permissions.set({ ...Permissions.default(), editState: Permissions.proofOrSignature(), }); } @method async initState(storageServerPublicKey: PublicKey) { this.storageServerPublicKey.set(storageServerPublicKey); this.storageNumber.set(Field(0)); const emptyTreeRoot = new MerkleTree(8).getRoot(); this.storageTreeRoot.set(emptyTreeRoot); } ... ``` This code adds three pieces of state to the contract: - The public key of the storage server - The storageNumber used to ensure the storage server is actively storing states - The root of the Merkle tree Initialize the zkApp state for these three values by setting: - The public key of the storage server - The storage number to 0 - Storing the root of an empty tree 4. Continuing, add the code for the `update` function on the smart contract: ```ts ignore ... @method async update( leafIsEmpty: Bool, oldNum: Field, num: Field, path: MerkleWitness8, storedNewRootNumber: Field, storedNewRootSignature: Signature ) { const storedRoot = this.storageTreeRoot.get(); this.storageTreeRoot.assertEquals(storedRoot); let storedNumber = this.storageNumber.get(); this.storageNumber.assertEquals(storedNumber); let storageServerPublicKey = this.storageServerPublicKey.get(); this.storageServerPublicKey.assertEquals(storageServerPublicKey); let leaf = [oldNum]; let newLeaf = [num]; // newLeaf can be a function of the existing leaf newLeaf[0].assertGreaterThan(leaf[0]); const updates = [ { leaf, leafIsEmpty, newLeaf, newLeafIsEmpty: Bool(false), leafWitness: path, }, ]; const storedNewRoot = OffChainStorage.assertRootUpdateValid( storageServerPublicKey, storedNumber, storedRoot, updates, storedNewRootNumber, storedNewRootSignature ); this.storageTreeRoot.set(storedNewRoot); this.storageNumber.set(storedNewRootNumber); } } ``` This code gets and asserts the current state of the contract, and then performs the update. First, check that the new leaf is greater than the old leaf. Then, check the update itself. In this example, perform a single update to the tree. However, you can chain updates together with multiple witnesses to change the tree more than once in a single call to the storage server. To assert the update is valid, use a `assertRootUpdateValid` call from the `OffChainStorage` library. This checks that when the update is applied to the tree represented by the existing on-chain tree root, the data for the new tree is being stored by the storage server. That completes the smart contract! ## Implementing `main.ts` Since much of the logic in the `main.ts` file is repeated from earlier tutorials, this tutorial reviews just the relevant parts. 1. Download the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts/src/main.ts) example file. 1. Move it to the local `/06-off-chain-storage/src` folder. 1. Open it in your editor. The `main.ts` file contains logic for running the contract locally and for deploying and interacting with it on Devnet. This is a useful pattern when developing a new contract. ### Connect to the off-chain storage server To try your contract on Devnet, deploy the contract as usual with `zk deploy`. In `main.ts`, set `useLocal` to false. Add the name of your config to the end of your call to `node main.js`. This code connects to the storage server on port 3001 and get its public key: ```ts ... const storageServerAddress = 'http://localhost:3001'; const serverPublicKey = await OffChainStorage.getPublicKey( storageServerAddress, NodeXMLHttpRequest ); ... ``` In a real application, you would run the storage server on an externally exposed machine, and change this address from `localhost` to match the storage server. ### updateTree function Now, review the `updateTree` function in [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/06-offchain-storage/offchain-storage-zkapp/contracts/src/main.ts). The goal in this function is to: 1. Get the currently stored tree from the storage server 2. Select a random leaf 3. Change the value at that leaf to a bigger number 4. Create a transaction that performs this update. To start, get the existing tree: ```ts ... async function updateTree() { const index = BigInt(Math.floor(Math.random() * 4)); // get the existing tree const treeRoot = await zkapp.storageTreeRoot.get(); const idx2fields = await OffChainStorage.get( storageServerAddress, zkappPublicKey, treeHeight, treeRoot, NodeXMLHttpRequest ); const tree = OffChainStorage.mapToTree(treeHeight, idx2fields); const leafWitness = new MerkleWitness8(tree.getWitness(BigInt(index))); ... ``` Next, get the current root stored in the contract and request the data for that root from the storage server. Then, convert that data from a map to a Merkle tree and get a witness for a random index of the Merkle tree. Continuing: ```ts ... // get the prior leaf const priorLeafIsEmpty = !idx2fields.has(index); let priorLeafNumber: Field; let newLeafNumber: Field; if (!priorLeafIsEmpty) { priorLeafNumber = idx2fields.get(index)![0]; newLeafNumber = priorLeafNumber.add(3); } else { priorLeafNumber = Field(0); newLeafNumber = Field(1); } ... ``` This code checks if the leaf is empty and shapes the update accordingly. If the leaf was empty, set it to one. Otherwise, set the leaf to whatever used to be there, plus 3. ```ts ... const [storedNewStorageNumber, storedNewStorageSignature] = await OffChainStorage.requestStore( storageServerAddress, zkappPublicKey, treeHeight, idx2fields, NodeXMLHttpRequest ); ... ``` Finally, request that the storage server stores the data. If successful, a new storage number and a signature is returned and can be used for updating the smart contract. ### Call the smart contract To call the smart contract: ```ts ... const doUpdate = () => { zkapp.update( Bool(priorLeafIsEmpty), priorLeafNumber, newLeafNumber, leafWitness, storedNewStorageNumber, storedNewStorageSignature ); }; if (useLocal) { const updateTransaction = await Mina.transaction( { sender: feePayerKey.toPublicKey(), fee: transactionFee }, () => { doUpdate(); } ); updateTransaction.sign([zkappPrivateKey, feePayerKey]); await updateTransaction.prove(); await updateTransaction.send(); ``` That completes the review of the code to interact with the experimental off-chain storage server. ## Conclusion This tutorial introduced an experimental solution that builds a smart contract that leverages off-chain storage. Next, check out [Tutorial 7: Oracles](/zkapps/tutorials/oracle) to learn how to use Oracles to pull in data from the outside world into your zkApp. --- url: /zkapps/tutorials/07-oracle --- # Tutorial 7: Oracles You can use an oracle when your smart contract needs to consume data from the outside world. Learn about zkOracles in this 5-minute video: ## Prerequisites - Make sure you have the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` - Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.20.1` - [o1js](https://www.npmjs.com/package/o1js) version `1.1.0`. ## High-Level Overview In this tutorial, you are going to build an oracle that retrieves data from the REST API and you also are going to write the smart contract that consumes information from this oracle. 1. Retrieve data from the REST API that provides mock credit score information for two users: one with a high credit score (user with `id=1`) and one with a low credit score (users with `id > 1`). 1. The smart contract consumes this information and allows users to prove their credit score is above a certain threshold (for example, higher than 700). Using the smart contract, users can generate an attestation that their credit score is above a certain value. To maintain their privacy, users can prove this fact to a third party without sharing the exact credit score or other personal information. This tutorial uses a mock credit score API as the data source and provides a foundation to create an oracle for any type of data. Just alter the code to query data from whatever source you need, any other REST API, for example. ## How Oracles Work Oracles connect blockchain smart contracts with the outside world to get data on chain. Mina smart contract computation run off-chain and make it possible to prove that the expected computation was run on private data without revealing the data itself. When the smart contract consumes data from a third-party source, you want to verify that this data is authentic and was provided by the expected source. The [Mina roadmap](https://minaprotocol.com/mina-roadmap) includes `zkOracles` to allow a zkApp to consume data trustlessly from any HTTPS data source. The oracle design described in this tutorial is typically operated by the zkApp developer. The oracle fetches and signs the desired data, and then a zkApp can consume this data and verify the signature to ensure that the data was provided by the expected source. Data providers can also operate as response signers like the one described to provide users with an oracle that does not require them to trust an intermediary. In other words, if a credit score or other data provider chooses to sign response data themselves, users can consume data from that source without trusting anybody besides the data provider they already trust to provide correct data. ### Design This simple oracle design: - Fetches data from the desired REST API source - Signs it using a Mina-compatible private key - Returns the data, signature, and public key associated with the private key - Allows the signature to be verified by the zkApp ### Code You can view the complete [oracle logic code](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/07-oracles/oracle/app/api/credit-score/route.ts) and the corresponding `Next.js` project [here](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/07-oracles/oracle). This oracle uses the [Vercel Functions](https://vercel.com/docs/functions). You don't have to dive into the code now, since the code is commented to explain each step so you can build something similar for yourself! You can adapt this code to create oracles for other API sources. For example, if you want your smart contract to ingest price feed data from an exchange, query the exchange API, sign the results, and return a response in the following response format. ### Response Format The oracle returns a JSON-formatted response with these top-level properties: - `data`: An object of the information you are interested in and can have any form. - `signature`: A signature for the `data` object created using the oracle operator's private key. Smart contracts use this signature to verify that data was provided by the expected source. - `publicKey`: The public key of the oracle is the same for all requests to this oracle. The following example is a response from the oracle for the user with the `id` of `1`. In the real world, this `id` might be a social security number or a similar identifier. Notice that the data property contains their credit score and user id. The demo oracle for user with id `1` is available at https://07-oracles.vercel.app/api/credit-score?user=1 and shows this response: ```json { "data": { "id": 1, "creditScore": 787 }, "signature": "7mXGPCbSJUiYgZnGioezZm7GCy46CEUbgcCH9nrJYXQQiwwVrA5wemBX4T1XFHUw62oR2324QNnkUVXW6yYQLsPsqxZ3nsYR", "publicKey": "B62qoAE4rBRuTgC42vqvEyUqCGhaZsW58SKVW4Ht8aYqP9UTvxFWBgy" } ``` The user with an `id` of `2` has a credit score that is below the threshold specified in the smart contract. The demo oracle for user with id `2` with a lower credit score is available at https://07-oracles.vercel.app/api/credit-score?user=2 and shows this response: ```json { "data": { "id": 2, "creditScore": 536 }, "signature": "7mXXnqMx6YodEkySD3yQ5WK7CCqRL1MBRTASNhrm48oR4EPmenD2NjJqWpFNZnityFTZX5mWuHS1WhRnbdxSTPzytuCgMGuL", "publicKey": "B62qoAE4rBRuTgC42vqvEyUqCGhaZsW58SKVW4Ht8aYqP9UTvxFWBgy" } ``` While the first user has a credit score of `787`, the second user has a credit score of `536`. The `signature` is also changed. This makes sense because the payload is different from what is received in the first response. Finally, notice that the `publicKey` is the same because in each case we are querying data from the same provider. ## Generate a key pair for your oracle You can generate the Mina-compatible public/private key pair for your oracle by executing the following command: ```sh npm run keygen ``` This command runs the code in the [keygen.js](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/07-oracles/oracle/scripts/keygen.js) file. This file is the part of the oracle `Next.js` application, source code of which is available [here](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/07-oracles/oracle). ## Smart Contract Now that you have an oracle that returns signed data, you can write a smart contract that uses this data. ### Create a project 1. Create or change to a directory where you have write privileges. 1. Create a project by using the `zk project` command: ```sh $ zk project --ui none 07-oracles ``` This command will scaffold the zkApp project skipping the UI part since we don't need it. 1. Change into the `07-oracles` directory. For this tutorial, you run commands from the root of the `07-oracles` directory. Each time you make changes, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Prepare the project The files in the `src` directory contain the TypeScript code for the smart contract. 1. Delete the default generated files by running: ```sh $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts ``` 1. Create the `OracleExample.ts` file and generate the corresponding test file: ```sh $ zk file OracleExample ``` 1. Change `src/index.ts` to: ```ts import { OracleExample } from './OracleExample.js'; export { OracleExample }; ``` ### Write the smart contract You can find the complete code for this smart contract [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/07-oracles/contracts/src/OracleExample.ts). Paste the following content into the `src/OracleExample.ts` file: ```ts Field, SmartContract, state, State, method, PublicKey, Signature, } from 'o1js'; // The public key of our trusted data provider const ORACLE_PUBLIC_KEY = 'B62qoAE4rBRuTgC42vqvEyUqCGhaZsW58SKVW4Ht8aYqP9UTvxFWBgy'; export class OracleExample extends SmartContract { // Define zkApp state // Define zkApp events init() { // Initialize zkApp state super.init(); // Specify that caller should include signature with tx instead of proof this.requireSignature(); } @method async verify(id: Field, creditScore: Field, signature: Signature) { // Get the oracle public key from the zkApp state // Evaluate whether the signature is valid for the provided data // Check that the signature is valid // Check that the provided credit score is 700 or higher // Emit an event containing the verified user's id } } ``` This completes the basic setup for the smart contract. For details on the `init()` method, see [Tutorial 1: Hello World](hello-world). ### On-Chain State The smart contract stores the public key for the oracle that you retrieve data from as the on-chain state. This makes the public key available when end users run the smart contract. The smart contract then uses this public key to verify the signature of the data to confirm it came from the expected source. In the `src/OracleExample.ts` file: ```ts // Define zkApp state @state(PublicKey) oraclePublicKey = State(); ``` Use the `init` method to initialize the `oraclePublicKey` to the credit score oracle's public key. ```ts init() { // Initialize zkApp state super.init(); // Set the oracle public key as zkApp on-chain state this.oraclePublicKey.set(PublicKey.fromBase58(ORACLE_PUBLIC_KEY)); // Specify that caller should include signature with tx instead of proof this.requireSignature(); } ``` ### Emit Events The smart contract checks that a user has a credit score above a certain threshold. But, how can the user prove it? To expose the result to the outside world, you can emit events. Events allow smart contracts to publish arbitrary messages that anybody can verify without requiring them to be stored in the state of a zkApp account. This property makes events ideal for communication with other parties of your application that don't live on-chain, like the UI or even an external service. This code adds an `events` object to the smart contract class to define the names and types of the events it can emit: ```ts // Define zkApp events events = { verified: Field, }; ``` ### Define the verify() method Next you would like to verify that user's credit score is above `700`. The `verify()` method is defined like any other TypeScript method, except that it must have the `@method` decorator in front of it that tells o1js that this method can be invoked by users when they interact with the smart contract. ```ts @method async verify(id: Field, creditScore: Field, signature: Signature) { ... } ``` Pass in these arguments: - `id`: The id of the user whose credit score is requested to prevent bad actors from querying somebody else's data and claiming it as their own. - `creditScore`: The credit score of the user that is a number between 350 and 800 (this tutorial uses mock credit scores). - `signature`: A cryptographic signature of oracle's `data` object (`id` and `creditScore`). This is what the smart contract uses to verify that the data was provided by the expected source. The `verify()` method does not return any values or change any contract state. It only emits a `verified` event with the user's id if their credit score is above 700. ### Fetch the oracle's public key To get the oracle's public key from the on-chain state, verify the signature of data from the oracle: ```ts // Get the oracle public key from the zkApp state const oraclePublicKey = this.oraclePublicKey.get(); this.oraclePublicKey.requireEquals(oraclePublicKey); ``` The `requireEquals()` method invocation ensures that the public key that is retrieved at execution time is the same as the public key that exists within the zkApp account on the Mina network when the transaction is processed by the network. ### Verify the signature To ensure that the signature was from our expected source, verify that the signature on the oracle's `data` object (`id` and `creditScore`) is valid for the expected public key. This code returns true if the signature is valid, and false if it is not. ```ts // Evaluate whether the signature is valid for the provided data const validSignature = signature.verify(oraclePublicKey, [id, creditScore]); ``` You always want to make it impossible to generate a valid zero knowledge proof if `validSignature` is false. You can do this with `assertTrue()`. If the signature is invalid, this throws an exception and makes it impossible to generate a valid zero knowledge proof and proceed with transaction creation. ```ts // Check that the signature is valid validSignature.assertTrue(); ``` ### Verify the credit score is 700 or higher You want the `verify()` method to emit an event only if the user's credit score is 700 or higher. To ensure that this condition is met, call `assertGreaterThanOrEqual()` (assert greater than or equal to) on `creditScore`. ```ts // Check that the provided credit score is 700 or higher creditScore.assertGreaterThanOrEqual(Field(700)); ``` These assert methods create a constraint that makes it impossible for users to generate a valid zero knowledge proof unless their condition is met. Without a valid zero knowledge proof (or a signature) it's impossible to generate a valid Mina transaction. Users can call the smart contract method and send a valid transaction only if they have a valid signature from the expected oracle and a credit score 700 or above. ### Emit a verified event With this foundation, you can emit a verified event. - The first argument to `emitEvent()` is an arbitrary string name, because a smart contract could emit more than one type of event. - The second argument can be any value, as long as it matches the type defined for the event. In this case, the event has the `Field` type, but it could be a more complicated type built on `Fields`, if the situation called for it. Emitted events can be fetched using the [Archive-Node-API](/zkapps/writing-a-zkapp/feature-overview/fetch-events-and-actions). ```ts // Emit an event containing the verified user's id this.emitEvent('verified', id); ``` ## Test your smart contract You can find the complete code for the smart contract tests [here](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/07-oracles/contracts/src/OracleExample.test.ts). When you ran the `zk file OracleExample` command, the zkApp CLI automatically generated a test file `src/OracleExample.test.ts`. To add tests, paste the following code in the `OracleExample.test.ts` file: ```ts Field, Mina, PrivateKey, PublicKey, AccountUpdate, Signature, } from 'o1js'; let proofsEnabled = false; // The public key of our trusted data provider const ORACLE_PUBLIC_KEY = 'B62qoAE4rBRuTgC42vqvEyUqCGhaZsW58SKVW4Ht8aYqP9UTvxFWBgy'; describe('OracleExample', () => { let deployerAccount: Mina.TestPublicKey, deployerKey: PrivateKey, senderAccount: Mina.TestPublicKey, senderKey: PrivateKey, zkAppAddress: PublicKey, zkAppPrivateKey: PrivateKey, zkApp: OracleExample; beforeAll(async () => { if (proofsEnabled) await OracleExample.compile(); }); beforeEach(async () => { const Local = await Mina.LocalBlockchain({ proofsEnabled }); Mina.setActiveInstance(Local); deployerAccount = Local.testAccounts[0]; deployerKey = deployerAccount.key; senderAccount = Local.testAccounts[1]; senderKey = senderAccount.key; zkAppPrivateKey = PrivateKey.random(); zkAppAddress = zkAppPrivateKey.toPublicKey(); zkApp = new OracleExample(zkAppAddress); }); async function localDeploy() { const txn = await Mina.transaction(deployerAccount, async () => { AccountUpdate.fundNewAccount(deployerAccount); await zkApp.deploy(); }); await txn.prove(); // this tx needs .sign(), because `deploy()` adds an account update that requires signature authorization await txn.sign([deployerKey, zkAppPrivateKey]).send(); } it('generates and deploys the `OracleExample` smart contract', async () => { await localDeploy(); const oraclePublicKey = zkApp.oraclePublicKey.get(); expect(oraclePublicKey).toEqual(PublicKey.fromBase58(ORACLE_PUBLIC_KEY)); }); describe('hardcoded values', () => { it('emits an `id` event containing the users id if their credit score is above 700 and the provided signature is valid', async () => { await localDeploy(); const id = Field(1); const creditScore = Field(787); const signature = Signature.fromBase58( '7mXGPCbSJUiYgZnGioezZm7GCy46CEUbgcCH9nrJYXQQiwwVrA5wemBX4T1XFHUw62oR2324QNnkUVXW6yYQLsPsqxZ3nsYR' ); const txn = await Mina.transaction(senderAccount, async () => { await zkApp.verify(id, creditScore, signature); }); await txn.prove(); await txn.sign([senderKey]).send(); const events = await zkApp.fetchEvents(); const verifiedEventValue = events[0].event.data.toFields(null)[0]; expect(verifiedEventValue).toEqual(id); }); it('throws an error if the credit score is below 700 even if the provided signature is valid', async () => { await localDeploy(); const id = Field(1); const creditScore = Field(536); const signature = Signature.fromBase58( '7mXXnqMx6YodEkySD3yQ5WK7CCqRL1MBRTASNhrm48oR4EPmenD2NjJqWpFNZnityFTZX5mWuHS1WhRnbdxSTPzytuCgMGuL' ); expect(async () => { const txn = await Mina.transaction(senderAccount, async () => { await zkApp.verify(id, creditScore, signature); }); }).rejects; }); it('throws an error if the credit score is above 700 and the provided signature is invalid', async () => { await localDeploy(); const id = Field(1); const creditScore = Field(787); const signature = Signature.fromBase58( '7mXPv97hRN7AiUxBjuHgeWjzoSgL3z61a5QZacVgd1PEGain6FmyxQ8pbAYd5oycwLcAbqJLdezY7PRAUVtokFaQP8AJDEGX' ); expect(async () => { const txn = await Mina.transaction(senderAccount, async () => { await zkApp.verify(id, creditScore, signature); }); }).rejects; }); }); describe('actual API requests', () => { it('emits an `id` event containing the users id if their credit score is above 700 and the provided signature is valid', async () => { await localDeploy(); const response = await fetch( 'https://07-oracles.vercel.app/api/credit-score?user=1' ); const data = await response.json(); const id = Field(data.data.id); const creditScore = Field(data.data.creditScore); const signature = Signature.fromBase58(data.signature); const txn = await Mina.transaction(senderAccount, async () => { await zkApp.verify(id, creditScore, signature); }); await txn.prove(); await txn.sign([senderKey]).send(); const events = await zkApp.fetchEvents(); const verifiedEventValue = events[0].event.data.toFields(null)[0]; expect(verifiedEventValue).toEqual(id); }); it('throws an error if the credit score is below 700 even if the provided signature is valid', async () => { await localDeploy(); const response = await fetch( 'https://07-oracles.vercel.app/api/credit-score?user=2' ); const data = await response.json(); const id = Field(data.data.id); const creditScore = Field(data.data.creditScore); const signature = Signature.fromBase58(data.signature); expect(async () => { const txn = await Mina.transaction(senderAccount, async () => { await zkApp.verify(id, creditScore, signature); }); }).rejects; }); }); }); ``` To run the tests: 1. Save the `OracleExample.test.ts` file. 1. Run `npm i`. 1. Run `npm run test`. Note that writing a test that calls an API is generally not a best practice, but it's convenient for the sake of this tutorial. You can also mock your HTTP requests. Congratulations! You have just built a simple oracle using o1js and the Mina blockchain. You can find the complete code for this example [here](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/07-oracles). --- url: /zkapps/tutorials/08-custom-tokens --- # Tutorial 8: Custom Tokens In this tutorial, you learn to create custom tokens. Mina comes with native support for custom tokens. Each account on Mina can also have tokens associated with it. To create a new token, one creates a smart contract, which becomes the manager for the token, and uses that contract to set the rules around how the token can be mint, burned, and sent. The manager account may also set a token symbol for its token, such as in this example, `MYTKN`. Uniqueness is not enforced for token names. Instead the public key of the manager account is used to identify tokens. In this tutorial, you review smart contract code that creates and manages new tokens. The full example code is provided in the [08-custom-tokens/src/](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/08-custom-tokens/src) example files. For reference, a more extensive example, including all the ways to interact with token smart contracts, is provided in [token.test.ts](https://github.com/o1-labs/o1js/blob/main/src/lib/token.test.ts). ## Prerequisites - Make sure you have the latest version of the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` - Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.16.0` - [o1js](https://www.npmjs.com/package/o1js) version `0.15.3` ## Create the project 1. Create or change to a directory where you have write privileges. 1. Create a project by using the `zk project` command: ```sh $ zk project 08-custom-tokens ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ``` ? Create an accompanying UI project too? … next svelte nuxt empty > none ``` ## Prepare the project 1. Change to the project directory, delete the existing files, and create a new `src/BasicTokenContract` smart contract, and a `index.ts` file: ```sh $ cd 08-custom-tokens $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts $ zk file src/BasicTokenContract $ touch src/index.ts ``` 1. Edit `index.ts` to import and export your new smart contract: ```ts import { BasicTokenContract } from './BasicTokenContract.js'; export { BasicTokenContract }; ``` ## Create the project 1. Create or change to a directory where you have write privileges. 1. Create a project by using the `zk project` command: ```sh $ zk project 08-custom-tokens ``` The `zk project` command has the ability to scaffold the UI for your project. For this tutorial, select `none`: ``` ? Create an accompanying UI project too? … next svelte nuxt empty ❯ none ``` ## Prepare the project 1. Change to the project directory, delete the existing files, and create a new `src/BasicTokenContract` smart contract, and a `index.ts` file: ```sh $ cd 08-custom-tokens $ rm src/Add.ts $ rm src/Add.test.ts $ rm src/interact.ts $ zk file src/BasicTokenContract $ touch src/index.ts ``` 1. Edit `index.ts` to import and export your new smart contract: ```ts import { BasicTokenContract } from './BasicTokenContract.js'; export { BasicTokenContract }; ``` ## Basic Token Example To create a token manager smart contract, create a normal smart contract whose methods call special functions that manipulate tokens. A full copy of the [BasicTokenContract.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/08-custom-tokens/src/BasicTokenContract.ts) is provided. ### Imports and smart contract structure First, bring in imports and set up the structure for the smart contract. The single state variable `totalAmountInCirculation` tracks how many tokens exist. ```ts SmartContract, state, State, method, DeployArgs, Permissions, UInt64, PublicKey, Signature, } from 'o1js'; const tokenSymbol = 'MYTKN'; export class BasicTokenContract extends SmartContract { @state(UInt64) totalAmountInCirculation = State(); deploy(args: DeployArgs) { super.deploy(args); const permissionToEdit = Permissions.proof(); this.account.permissions.set({ ...Permissions.default(), editState: permissionToEdit, setTokenSymbol: permissionToEdit, send: permissionToEdit, receive: permissionToEdit, }); } ``` ### init() and mint() methods Next, add an init method and a method that mints tokens. - Set the token symbol (MYTKN) in the `init()` method. - To start tracking the amount in circulation, set it to zero. - Write a function to mint new tokens and send them to a recipient. This function checks that a signature has been provided by the zkApp account, so that only the zkApp account can call the `mint()` method. - In the `mint()` method, track how many tokens are in existence. ```ts @method async init() { super.init(); this.account.tokenSymbol.set(tokenSymbol); this.totalAmountInCirculation.set(UInt64.zero); } @method async mint( receiverAddress: PublicKey, amount: UInt64, adminSignature: Signature ) { let totalAmountInCirculation = this.totalAmountInCirculation.get(); this.totalAmountInCirculation.requireEquals(totalAmountInCirculation); let newTotalAmountInCirculation = totalAmountInCirculation.add(amount); adminSignature .verify( this.address, amount.toFields().concat(receiverAddress.toFields()) ) .assertTrue(); this.token.mint({ address: receiverAddress, amount, }); this.totalAmountInCirculation.set(newTotalAmountInCirculation); } ``` ### Send function Finally, write a send function. - Holders of the MYTKN token call the `sendTokens()` method to send tokens to other Mina accounts. ```ts @method async sendTokens( senderAddress: PublicKey, receiverAddress: PublicKey, amount: UInt64 ) { this.token.send({ from: senderAddress, to: receiverAddress, amount, }); } } ``` That completes a review of a basic token. ## Examples To see an example of interacting with this contract, see [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/08-custom-tokens/src/main.ts). To see an example of putting rules around a token, see this [example](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/08-custom-tokens/src/WhitelistedTokenContract.ts) of a token with whitelist gating so that public keys can interact with it. ## Building zkApps that interact with Tokens With zkApps, you can also build smart contracts that interact with tokens. For example, swapping one token for another or taking deposits of Mina tokens. For now, see this [example](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/dex/dex.ts) of a zkApp implementing an AMM-based DEX. ## Conclusion You have finished reviewing the steps to build a smart contract to manage a token. You learned how to build a smart contract that places custom rules over tokens. To learn more, see [Custom Token API](/zkapps/writing-a-zkapp/feature-overview/custom-tokens). Check out [Tutorial 9: Recursion](/zkapps/tutorials/recursion) to learn how to use recursive ZKPs with o1js, to implement zkRollups, large computations, and more. --- url: /zkapps/tutorials/09-recursion --- # Tutorial 9: Recursion One of the most powerful features of zkApps is [recursion](/zkapps/o1js/recursion). With recursion, you can realize composability between zero knowledge proofs. Recursion unlocks many powerful technical abilities, such as creating high-throughput applications, creating proofs of large computations, and constructing multi-party proofs. ### Scaling Throughput with zkRollups and App Chains Verifying large amounts of information is usually challenging for blockchains. With zero knowledge proofs (ZKPs), and particularly recursive ZKPs, this becomes far easier. By leveraging recursive verification, it is possible to easily construct zkRollups and app chains. This tutorial provides an example of a simple zkRollup. Recursive composition gives you the flexibility to handle live demand by letting you choose between a high tree height (higher throughput, but logarithmically slower latency) and a lower tree height (lower throughput, but faster latency). You can modify the depth of the tree to handle whatever traffic is present on the network while still offering optimal latency to commit transactions back to the chain. For an example of an app chain, one could imagine an on-chain trading pair that uses an order book. Rolling up the transactions for the application with zero knowledge proofs lets the app handle the expensive computations of keeping buy and sell orders sorted while still posting complete verification to the chain. This tutorial guides you through a review of a simple zkRollup example that can be used to implement a zkRollup or an app chain. ### Scaling Proof Size Recursive ZKPs allow you to construct very large transactions that wouldn't otherwise be possible. For example, recursive ZKPs can be used to prove the output of a machine learning (ML) model to prove an inference is genuinely generated by a model or, for a more computationally intensive case, to verify that a model has been trained on a particular dataset. ### Off-chain, multi-party proof construction Recursive ZKPs also make it easy to allow multiple parties to construct transactions. One or more parties can recursively update a ZKP and its associated public state to accomplish off-chain proof construction. When the multi-party stage is completed, that state and its proof can then be sent as part of an on-chain transaction or used as part of an off-chain application leveraging ZKPs. ## ZkProgram Example You build recursive zkApps with [ZkProgram](/zkapps/o1js-reference/functions/ZkProgram), the o1js general purpose API for creating zero knowledge proofs. A ZkProgram is similar to zkApp smart contracts but isn't tied to an on-chain account. Proofs generated using a ZkProgram can be passed into zkApp smart contracts for them to verify recursively. They can even be passed recursively into their own functions for off-chain recursive composition. The following example code for the ZkProgram tutorial is provided in the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/main.ts) file on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp! ## Prerequisites Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. In particular, make sure you have the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` ## Create a new project Now that you have the tooling installed, you can start building your application. 1. Create or change to a directory where you have write privileges. 1. Now, create a project using the `zk project` command: ```sh $ zk project 09-recursion ``` As you learned in earlier tutorials, the `zk project` command creates the `09-recursion` directory that contains the scaffolding for your project. 1. Change into the `09-recursion` directory. Like all projects, you run `zk` commands from the root of the `09-recursion` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Prepare the project Like earlier tutorials, you can prepare your project by deleting the default files that come with the new project and creating a smart contract called `Add`. Open `src/index.ts` in a text editor and import the `Add` smart contract, like: ```ts src/index.ts export { Add }; ``` ## Write the ZkProgram Now, the fun part! Write your smart contract in the `src/Add.ts` file. A final version of the smart contract is provided in the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/Add.ts) example file. ### Copy the example Use the existing code in the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/Add.ts) example file. 1. First, open the [Add.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/Add.ts) example file. 1. Copy the file's entire contents into your project `src/Add.ts` file. ### Imports The `import` statement brings in other packages and dependencies to use in your ZkProgram. :::info All functions used inside a ZkProgram must operate on o1js compatible data types: `Field` types and other types built on top of `Field` types. :::info ```ts src/Add.ts ``` These items are: - `Field`: The native number type in o1js. You can think of `Field` elements as unsigned integers. Field elements are the most basic type in o1js. All other o1js-compatible types are built on top of `Field` elements. - `SelfProof`: The class in o1js that extends the `Proof` class and allows you to pass in a proof of a circuit in one of its own methods. - `ZkProgram`: The o1js general purpose API for creating zero knowledge proofs. A ZkProgram is similar to zkApp smart contracts but isn't tied to an on-chain account. - `verify`: Verifies the signature using a message and the corresponding `PublicKey`. ### ZkProgram To create a ZkProgram, start with the `init()` method. - For each method, declare the inputs it will receive. - The first argument of a ZkProgram method is always the state of the ZkProgram, named `publicInput` since it is public. ```ts export const Add = ZkProgram({ name: 'add-example', publicInput: Field, methods: { init: { privateInputs: [], async method(state: Field) { state.assertEquals(Field(0)); }, }, }, }); ``` Add another method that takes an existing proof, adds a new number to it, and produces a new proof: ```ts addNumber: { privateInputs: [SelfProof, Field], async method( newState: Field, earlierProof: SelfProof, numberToAdd: Field ) { earlierProof.verify(); newState.assertEquals(earlierProof.publicInput.add(numberToAdd)); }, }, ``` Use recursion to combine two proofs: ```ts add: { privateInputs: [SelfProof, SelfProof], async method( newState: Field, earlierProof1: SelfProof, earlierProof2: SelfProof ) { earlierProof1.verify(); earlierProof2.verify(); newState.assertEquals( earlierProof1.publicInput.add(earlierProof2.publicInput) ); }, }, ``` To use ZkProgram, compile it and then call methods on it: ```ts async function main() { console.log('compiling...'); const { verificationKey } = await Add.compile(); console.log('making proof 0'); const { proof: proof0 } = await Add.init(Field(0)); console.log('making proof 1'); const { proof: proof1 } = await Add.addNumber(Field(4), proof0, Field(4)); console.log('making proof 2'); const { proof: proof2 } = await Add.add(Field(4), proof1, proof0); console.log('verifying proof 2'); console.log('proof 2 data', proof2.publicInput.toString()); const ok = await verify(proof2.toJSON(), verificationKey); console.log('ok', ok); } main(); ``` Verification of the proof can occur off-chain using the `verify()` method. This is useful for applications where you want to prove something to an off-chain entity. ## Voting Example Another example of off-chain multi-party proof construction with recursive ZKPs is provided in the [vote.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/vote.ts) example file. ## Using ZkProgram in Smart Contracts After you build a recursive ZKP, use a method on a smart contract to settle the proof to the Mina blockchain. Build a zkRollup to use ZkProgram from a smart contract. This example code builds a zkRollup to operate over a MerkleMap of accounts that each store a number. The update rule increments the value stored at an account - though you could imagine using more substantial rules to implement a particular application. The zkApp will store the Merkle root of this MerkleMap of accounts on chain. Updates occur only when authorized by a recursive zero knowledge proof generated by the ZkProgram. This zkRollup design is flexible to how much compute is being demanded of it (for latency) and allows it to scale to arbitrary numbers of proofs (for throughput). On a single machine, the example code does not offer a high throughput. However, you can achieve very high throughputs by switching the mapreduce here for a mapreduce that runs over tens or hundreds of machines. In fact, you can achieve any level of throughput as long as you're willing to incur `log(N)` latency when constructing the proof of N transactions. The following code for the ZkProgram part of a rollup is provided in the [rollup.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/09-recursion/src/rollup.ts) example file. A community-contributed implementation distributes compute over AWS instances in this [proof_aggregator](https://github.com/Trivo25/proof_aggregator) example. ### Set up ZkProgram ```ts class RollupState extends Struct({ initialRoot: Field, latestRoot: Field, }) { static createOneStep( initialRoot: Field, latestRoot: Field, key: Field, currentValue: Field, incrementAmount: Field, merkleMapWitness: MerkleMapWitness ) { const [witnessRootBefore, witnessKey] = merkleMapWitness.computeRootAndKey(currentValue); initialRoot.assertEquals(witnessRootBefore); witnessKey.assertEquals(key); const [witnessRootAfter] = merkleMapWitness.computeRootAndKey( currentValue.add(incrementAmount) ); latestRoot.assertEquals(witnessRootAfter); return new RollupState({ initialRoot, latestRoot, }); } ``` A proof generated by the `merge()` method indicates there is a valid sequence of transactions (for example, the applications of `oneStep`): - Get from an `initialRoot`, the root of a MerkleMap - To a `latestRoot` root of the Merkle map after transactions are applied ### Consume the proofs To consume these proofs in a smart contract (`SmartContract`) that uses the recursive proof to update its internal state: ```ts class RollupContract extends SmartContract { @state(Field) state = State(); deploy(args: DeployArgs) { super.deploy(args); this.setPermissions({ ...Permissions.default(), editState: Permissions.proofOrSignature(), }); } @method async initStateRoot(stateRoot: Field) { this.state.set(stateRoot); } @method async update(rollupStateProof: RollupProof) { const currentState = this.state.get(); this.state.requireEquals(currentState); rollupStateProof.publicInput.initialRoot.assertEquals(currentState); rollupStateProof.verify(); this.state.set(rollupStateProof.publicInput.latestRoot); } } ``` ### Verify the value at account is incremented Fill in the previous methods, particularly `oneStep()` and `createOneStep()`. This step of the rollup checks that the value at an account was incremented by a particular amount. - The code computes an updated state inside the recursive SNARK by calling `RollupState.createOneStep()`. - Then, asserting that the new state of the recursive SNARK is equivalent to the computed state. - Inside `createOneStep()`, a single step of the rollup is created. ```ts class RollupState extends Struct({ ... }) { static createOneStep( initialRoot: Field, latestRoot: Field, key: Field, currentValue: Field, incrementAmount: Field, merkleMapWitness: MerkleMapWitness, ) { const [ witnessRootBefore, witnessKey ] = merkleMapWitness.computeRootAndKey(currentValue); initialRoot.assertEquals(witnessRootBefore); witnessKey.assertEquals(key); const [ witnessRootAfter, _ ] = merkleMapWitness.computeRootAndKey(currentValue.add(incrementAmount)); latestRoot.assertEquals(witnessRootAfter); return new RollupState({ initialRoot, latestRoot }); } ... } const Rollup = ZkProgram({ name: "rollup-example", publicInput: Field, methods: { oneStep: { privateInputs: [ Field, Field, Field, Field, Field, MerkleMapWitness ], method( state: RollupState, initialRoot: Field, latestRoot: Field, key: Field, currentValue: Field, incrementAmount: Field, merkleMapWitness: MerkleMapWitness ) { const computedState = RollupState.createOneStep( initialRoot, latestRoot, key, currentValue, incrementAmount, merkleMapWitness ); RollupState.assertEquals(computedState, state); } }, ``` The `createOneStep()` method returns a proof that acts as the leaf in a tree of recursive proofs. To use this rollup, first you construct all of the leafs in parallel then recursively merge these leafs until you get a proof for the entire sequence. This parallel merging gives the high throughput properties for the rollup. You can reimplement the example code for more substantial functionality, just by changing `createOneStep()`. For example, to implement a DEX zkRollup that uses an orderbook change the code to: - Update buy/sell orders on an order book - Execute those buy/sell orders - Add a queue of tokens to move to the app chain in the smart contract - Add a queue of tokens to move out of the app chain in the ZkProgram ## Conclusion You learned about: - Recursion with zkApps, both on-chain and off-chain - Potential use cases to create high-throughput applications - Larger proof sizes - Create multi-party proof constructions Recursive zero knowledge proofs can help you build powerful zkApps. Check out [Tutorial 10: Account Updates](/zkapps/tutorials/account-updates) to learn about account updates, the underlying structure of zkApps, and how they enable permissions, preconditions, and composability. --- url: /zkapps/tutorials/10-account-updates --- # Tutorial 10: Account Updates The fundamental data structure that Mina transactions are built from is called an _account update_. Account updates are a flexible and powerful data structure that can express all kinds of updates, events, and preconditions you use to develop smart contracts. Each zkApp transaction constructed by o1js is composed of one or more [AccountUpdate](../o1js-reference/classes/AccountUpdate) classes, which are a set of instructions for the Mina network to perform, such as altering on-chain state, emitting an event, and so on. Each `AccountUpdate` can make assertions about its account, apply updates to its account, and make assertions about its child `AccountUpdates`. Transactions are structured as a list of trees of `AccountUpdates` applied with a [pre-order traversal](https://en.wikipedia.org/wiki/Tree_traversal). ## Permissions, Preconditions, and Composability Permissions, preconditions, composability, and tokens are the core features of zkApps that are implemented using `AccountUpdates`. To learn more, see these o1js docs: - [Permissions](/zkapps/writing-a-zkapp/feature-overview/permissions) - [On-Chain Values](/zkapps/writing-a-zkapp/feature-overview/on-chain-values) In this tutorial, you learn the essential account update features. ## AccountUpdate contents The `AccountUpdate` class is a set of instructions for the Mina network. It includes preconditions (conditions that must be true for the account update to be applied) and a list of state updates that need to be authorized by a signature or proof. Each [AccountUpdate](/zkapps/o1js-reference/classes/AccountUpdate) class has these components: - `PublicKey`: The account address for the account update - `TokenId`: A unique hash representing the custom token. Defaults to the MINA TokenId (`1`). Together, `PublicKey` and `TokenId` uniquely identify an account on the Mina network. - `Preconditions`: Conditions that must be true for the account update to be applied. Corresponds to assertions in an o1js method. - `Updates`: Things changed by the account update, such as including the zkApp state, permissions, and verification key. - `BalanceChange`: Any changes to the balance - `Authorization`: How the zkApp is authorized; must be a proof (corresponding to the verification key on the account), a signature, or none. See [Interacting With Mina](/zkapps/writing-a-zkapp/introduction-to-zkapps/interact-with-mina). Other `AccountUpdate` components are available to use, but are not covered in this tutorial: - `MayUseToken`: Whether the zkApp has permissions to manipulate its token. - `Layout`: Allows for assertions about the structure of an `AccountUpdate`. ## Account updates for a non-upgradable zkApp If the verification key cannot be changed, the zkApp smart contract is considered non-upgradeable. The `setVerificationKey` permission sets the ability to change the verification key of the account. Now, you can start building an example zkApp to explore permissions, preconditions, and composability with `AccountUpdates`. ### Visualize transactions To visualize transactions, use the `mina-transaction-visualizer` library. Install this library to use in your own zkApp: ```sh npm install mina-transaction-visualizer --save ``` ## Smart Contracts In this tutorial, you build two smart contracts: - `ProofsOnlyZkApp`: Non-upgradeable proof only - `SecondaryZkApp`: the other zkApp The full source code for this tutorial is provided in the [examples/zkapps/10-account-updates](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/10-account-updates) directory on GitHub. ### Non-upgradeable proof only The full example code is provided in the [examples/zkapps/10-account-updates/src/ProofsOnlyZkApp.ts](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/10-account-updates/src/ProofsOnlyZkApp.ts) file. Goal: Configure this zkApp to be modifiable only by using proofs. For this example, the zkApp is not upgradable after it is deployed. This means that while the zkApp developer owns the private key to initially deploy the zkApp, after its first deployment, the zkApp requires proof authorization and consequently can be updated only transactions that fulfill the zkApp smart contract logic. The private key is no longer useful for anything. This zkApp has methods that call other methods to let you explore the impacts to a transaction's account updates. 1. Start by adding the main contents of the zkApp: ```ts export class ProofsOnlyZkApp extends SmartContract { @state(Field) num = State(); @state(Field) calls = State(); 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)); } ... ``` This code configures the zkApp as described and initializes the zkApp with the values you want. By asserting that `provedState` is `false` in `init()`, you ensure that `init()` cannot be called again after the zkApp is set up during the initial deployment. Without this assertion, your zkApp could be reset by anyone calling the `init()` method on your zkApp. :::tip This assertion is a recommended best practice for most zkApps. ::: 1. Next, add two functions: ```ts ... @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))); } ... ``` These methods also assert `provedState` is `true` to ensure the zkApp was initialized as expected because `provedState` becomes true after `init()` is invoked. :::tip This assertion is a recommended best practice for most zkApps. ::: The `add()` method calls the `incrementCalls()` method. You can see how this is reflected in the `add()` transaction's `AccountUpdate` structure. 1. Finally, add one more function, `callSecondary()`, that calls a different zkApp: ```ts ... @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(); } } ``` The `callSecondary()` method takes the address of the other zkApp, `SecondaryZkApp`, and calls a method on it. Note that the impact of calling that method occurs after this set of AccountUpdates—so when you call `secondaryContract.num.get()`, it gets the value before this transaction is applied. Finally, look briefly at [SecondaryZkApp.ts](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/10-account-updates/src/SecondaryZkApp.ts) that contains: ```ts export class SecondaryZkApp extends SmartContract { @state(Field) num = State(); async deploy() { await super.deploy(); this.account.permissions.set({ ...Permissions.default(), }); } @method async init() { this.account.provedState.getAndRequireEquals(); this.account.provedState.get().assertFalse(); super.init(); this.num.set(Field(12)); } @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)); } } ``` You declare functions for initializing the account and the `add()` method that is called from the earlier `ProofOnlyZkApp`. ### Running Your Smart Contracts and Visualizing the AccountUpdates Now it's time to learn about the [main.ts](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/10-account-updates/src/main.ts) file that creates transactions with the earlier smart contracts and the account update visualizations it creates. 1. Import the transaction visualizer: ```ts ... import { showTxn, saveTxn, printTxn } from 'mina-transaction-visualizer'; ... ``` This provides three functions: ```ts // creates a png file of a transaction, and opens it in a local image viewer async showTxn(txn: Mina.Transaction, name: string, legend: Legend) // creates a png file of a transaction, and saves it to a path saveTxn(txn: Mina.Transaction, name: string, legend: Legend, path: string) // prints a nicely formatted view of a transaction printTxn(txn: Mina.Transaction, name: string, legend: Legend) // with legend type, to replace public keys with human readable strings: type Legend = { [pk: string]: string }; ``` 1. Next, define the legend as follows: ```ts const legend = { [proofsOnlyAddr.toBase58()]: 'proofsOnlyZkApp', [secondaryAddr.toBase58()]: 'secondaryZkApp', [deployerAccount.toBase58()]: 'deployer', }; ``` 1. Create and send a deploy transaction, then visualize it: ```ts const deployTxn = await Mina.transaction(deployerAccount, async () => { AccountUpdate.fundNewAccount(deployerAccount, 2); await proofsOnlyInstance.deploy(); await secondaryInstance.deploy(); }); await deployTxn.prove(); deployTxn.sign([deployerKey, proofsOnlySk, secondarySk]); await showTxn(deployTxn, 'deploy_txn', legend); await deployTxn.send(); ``` This yields the following visualization of `deployTxn`. This [visualization](/img/tutorial-10-deploy_txn.png) is best viewed in a new tab. The deploy transaction includes 5 accountUpdates represented as ovals. Described from left to right; 1. Takes the new account fee from the deployer for deploying the zkApps. Note the `-2` on the `balanceChange` field. 2. Deploys the `proofsOnlyZkApp` instance. Note the permissions are all set to the values in the zkApp's `deploy` field, and the `preconditions` asserting the nonce, so the transaction can't be applied more than once. 3. Initializes the `proofsOnlyZkApp`. Note the precondition that it can't already be in a proved state. 4. Deploys an instance of `secondaryZkApp`. Note the permissions here are set to default values, in contrast to the deployment in the `proofsOnlyZkApp` example. 5. Initializes the `secondaryZkApp` instance. When the transaction is run on chain, these account updates are checked by the Mina network and applied if valid. Each `AccountUpdate` class includes either a proof corresponding to the verification key in the zkApp account on-chain or a signature corresponding to the zkApp address. In this case, only proof authorization is allowed. ### Call `add()` on `proofsOnlyZkApp` 1. Call `add()` on your instance of `proofsOnlyZkApp`: ```ts const txn1 = await Mina.transaction(deployerAccount, async () => { await proofsOnlyInstance.add(Field(4)); }); await txn1.prove(); await showTxn(txn1, 'txn1', legend); await txn1.send(); ``` This returns the following visualization of `txn1`: See download link [here](/img/tutorial-10-txn1.png). ### Two AccountUpdates Now there are two AccountUpdates: - The parent corresponds to the `add()` method call - The child corresponds to the `this.incrementCalls()` call that the parent makes. One update is the child because it was called from the parent, which also implies that the parent has the child included as part of its proof. To learn more about parent/child account updates, see [Signing transactions and explicit account updates](/zkapps/writing-a-zkapp/introduction-to-zkapps/interact-with-mina#signing-transactions-and-explicit-account-updates) in the Payment to zkApp example. As a reminder, this update corresponds to code: ```ts ... @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))); } ... ``` View the [account updates visualization](/img/tutorial-10-deploy_txn.png) again. - The first AccountUpdate sets the state of `appState[0]` to `5` — corresponding to the value passed to `this.num.set()` in the `add()` method. - In the second AccountUpdate, `appState[1]` is set to `1`—corresponding to the value passed to `this.calls.set()` in the `incrementCalls()` contract. Finally, call `callSecondary` on your instance of `proofsOnlyZkApp`: ```ts const txn2 = await Mina.transaction(deployerAccount, async () => { await proofsOnlyInstance.callSecondary(secondaryAddr); }); await txn2.prove(); await showTxn(txn2, 'txn2', legend); await saveTxn(deploy_txn, 'deploy_txn', legend, './txn2.png'); await txn2.send(); ``` This returns the following visualization of `txn2`: This [txn2 visualization](/img/tutorial-10-txn2.png) is best viewed in a new tab. And a quick reminder of the code for `callSecondary()`: ```ts @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(); } ``` This call produces three accountUpdates: - `callSecondary()` (the parent) - `secondaryZkApp.add()` (the left child) - `incrementCalls()` (the right child) As described in the code comment, `callSecondary` sets `this.num` to `12` which is the value of `secondaryContract` at the "start" of the transaction. ## Conclusion Congratulations! You have explored the core features of AccountUpdates and learned about visualizing the AccountUpdates for a set of transactions. You can build more complicated transactions that involve multiple zkApps. This tutorial builds a foundational understanding of how o1js and zkApps work to enable permissions, preconditions, and composability. --- url: /zkapps/tutorials/anonymous-message-board --- # Anonymous Message Board Tutorial This example shows you how to put building zkApp ideas into practice as you walk through designing and implementing of a semi-anonymous messaging protocol. In this tutorial, you build a smart contract that allows users to publish messages semi-anonymously. - The contract allows a specific set of users to create new messages but does not disclose which user creates the message. - This semi-anonymous messaging leverages one aspect of a person's identity without revealing exactly who they are. An example use case for this semi-anonymous contract is to enable a DAO member to make credible statements on behalf of their DAO without revealing their specific individual identity. ## Prerequisites Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. In particular, make sure you have the zkApp CLI installed: ```sh $ npm install -g zkapp-cli ``` This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.20.1` - [o1js](https://www.npmjs.com/package/o1js) version `1.1.0` ## Create the message-board project 1. Create or change to a directory where you have write privileges. 1. Create a project using the `zk project` command: ```sh $ zk project --ui none message-board ``` The `zk project` command creates a directory with a new project template that is fully set up and ready for local development. Like all zk projects, a git repository is initialized in the project directory. By convention, the `main` branch is the default branch. 1. Change to the project directory: ```sh cd message-board ``` For this tutorial, you run commands from the root of the `message-board` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. See the included [README](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/anonymous-message-board/README.md) file with usage instructions. ### Prepare the project Example smart contract files come with the new project, you can delete them if you want. 1. Optional: Delete the example files not used in this tutorial: ```sh $ rm -rf src/* ``` 1. To create the `src/message.ts` file: ```sh $ zk file message ``` 1. Copy the entire contents of the [message.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/anonymous-message-board/src/message.ts) example file into your local `message-board/src/message.ts` file. ```ts import { Field, SmartContract, state, State, method, PrivateKey, PublicKey, Poseidon, } from 'o1js'; // These private keys are exported so that experimenting with the contract is // easy. Three of them (the Bobs) are used when the contract is deployed to // generate the public keys that are allowed to post new messages. Jack's key // is never added to the contract. So he won't be able to add new messages. In // real life, we would only use the Bobs' public keys to configure the contract, // and only they would know their private keys. export const users = { Bob: PrivateKey.fromBase58( 'EKFAdBGSSXrBbaCVqy4YjwWHoGEnsqYRQTqz227Eb5bzMx2bWu3F' ), SuperBob: PrivateKey.fromBase58( 'EKEitxmNYYMCyumtKr8xi1yPpY3Bq6RZTEQsozu2gGf44cNxowmg' ), MegaBob: PrivateKey.fromBase58( 'EKE9qUDcfqf6Gx9z6CNuuDYPe4XQQPzFBCfduck2X4PeFQJkhXtt' ), // This one says duck in it :) Jack: PrivateKey.fromBase58( 'EKFS9v8wxyrrEGfec4HXycCC2nH7xf79PtQorLXXsut9WUrav4Nw' ), }; export class Message extends SmartContract { // On-chain state definitions @state(Field) message = State(); @state(Field) messageHistoryHash = State(); @state(PublicKey) user1 = State(); @state(PublicKey) user2 = State(); @state(PublicKey) user3 = State(); init() { // Define initial values of on-chain state this.user1.set(users['Bob'].toPublicKey()); this.user2.set(users['SuperBob'].toPublicKey()); this.user3.set(users['MegaBob'].toPublicKey()); this.message.set(Field(0)); this.messageHistoryHash.set(Field(0)); } @method async publishMessage(message: Field, signerPrivateKey: PrivateKey) { // Compute signerPublicKey from signerPrivateKey argument const signerPublicKey = signerPrivateKey.toPublicKey(); // Get approved public keys const user1 = this.user1.get(); const user2 = this.user2.get(); const user3 = this.user3.get(); // Assert that signerPublicKey is one of the approved public keys signerPublicKey .equals(user1) .or(signerPublicKey.equals(user2)) .or(signerPublicKey.equals(user3)) .assertEquals(true); // Update on-chain message state this.message.set(message); // Compute new messageHistoryHash const oldHash = this.messageHistoryHash.get(); const newHash = Poseidon.hash([message, oldHash]); // Update on-chain messageHistoryHash this.messageHistoryHash.set(newHash); } } ``` This code serves as the scaffolding for the rest of the tutorial and contains a smart contract called `message` with two methods: - `init()` - Similar to the `constructor` in Solidity, it's where you define any set up that needs to happen before users begin interacting with the contract. - `publishMessage()` - The method that users invoke when they want to create a new message. The `@method` decorator tells o1js to: - Allow users to call this method - Generate a zero knowledge proof (ZKP) of its execution ### Define on-chain state Every Mina smart contract includes eight on-chain state variables that each store almost 256 bits of information. In more complex smart contracts, these state variables can store commitments to off-chain storage (for example, commitments for the hash of a file, the root of a Merkle tree, and so on). For simplicity, this tutorial stores everything on-chain. :::note General purpose off-chain storage libraries are appropriate only for development. See [Tutorial 6: Off-Chain Storage](/zkapps/tutorials/offchain-storage). ::: In this smart contract, one state variable stores the last message. Another stores the hash of all the previous messages so a frontend can validate message history. Three more state variables can store user public keys. It's possible to store additional public keys by Merkelizing them, but for simplicity this tutorial uses only three keys: ```ts export class Message extends SmartContract { // On-chain state definitions @state(Field) message = State(); @state(Field) messageHistoryHash = State(); @state(PublicKey) user1 = State(); @state(PublicKey) user2 = State(); @state(PublicKey) user3 = State(); ``` The `@state(Field)` decorator tells o1js that the variable is stored on-chain as a `Field` type. For practical purposes, the `Field` type is similar to the `uint256` type in Solidity. It can store large integers and addition, subtraction, and multiplication all work as expected. The only caveats are division and what happens in the event of an overflow. To learn more about finite fields, see [Finite field arithmetic](https://en.wikipedia.org/wiki/Finite_field_arithmetic). It is not required to understand exactly how field arithmetic works for this tutorial. o1js also provides `UInt32`, `UInt64`, and `Int64` types. All o1js types are composed of the `Field` type, including `PublicKey` as shown in the previous example. ### Define the `init()` method The `init` method is similar to the `constructor` in Solidity. It's where you define any setup that needs to happen before users begin interacting with the contract. In this case, set the public keys of users who can post and initialize `message` and `messageHistoryHash` as zero. The front end interprets the zero value to mean that no messages have been posted yet. ```ts init() { // Define initial values of on-chain state this.user1.set(users['Bob'].toPublicKey()); this.user2.set(users['SuperBob'].toPublicKey()); this.user3.set(users['MegaBob'].toPublicKey()); this.message.set(Field(0)); this.messageHistoryHash.set(Field(0)); } ``` ### Define `publishMessage()` The `publishMessage` method allows an approved user to publish a message. The `@method` decorator makes this method callable by users so that they can interact with the smart contract. For this example, pass in `message` and `signerPrivateKey` arguments to check that the user holds a private key associated with one of the three on-chain public keys before allowing them to update the message: ```ts @method async publishMessage(message: Field, signerPrivateKey: PrivateKey) { ``` Note that all inputs are private by default and exist only on the user's local machine when the smart contract runs. The Mina network never sees private inputs. The smart contract sends only values that are stored as state to the Mina blockchain. This means that even though the value of the `message` argument is eventually public, the value of `signerPrivateKey` never leaves the user's machine as a result of interacting with the smart contract. ### Compute `signerPublicKey` from `signerPrivateKey` Now that you have the user's private key, you need to derive the associated public key to check it against the list of approved publishers. The `PrivateKey` type in o1js includes a `toPublicKey()` method: ```ts // Compute signerPublicKey from signerPrivateKey argument const signerPublicKey = signerPrivateKey.toPublicKey(); ``` To check if this public key matches one of the keys stored on-chain:. ```ts // Get approved public keys const user1 = this.user1.get(); const user2 = this.user2.get(); const user3 = this.user3.get(); ``` Calling the `get()` method retrieves these values from the zkApp account on-chain state. :::note o1js uses a single network request to retrieve all on-chain state values simultaneously. ::: Finally, check if `signerPublicKey` is equal to one of the allowed public keys contained in the `user` variables: ```ts // Assert that signerPublicKey is one of the approved public keys signerPublicKey .equals(user1) .or(signerPublicKey.equals(user2)) .or(signerPublicKey.equals(user3)) .assertEquals(true); ``` Notice the `equals()` and `or()` methods are used instead of the JavaScript operators (`===`, and `||`). The built-in o1js methods have the same effect, but they work with o1js types and their execution can be verified using a zero knowledge proof. `assertEquals(true)` at the end means that a valid proof is not generated unless `signerPublicKey` is equal to one of the pre-approved users. The Mina network rejects any transaction sent to a zkApp account that doesn't include a valid zero knowledge proof for that account. So it is impossible for users to post new messages unless they have a private key associated with one of the three pre-approved public keys. ### Update `message` Up to this point, the contract ensures that only approved users can call `publishMessage()`. When they do, the contract updates the on-chain `message` variable to their new message: ```ts // Update on-chain message state this.message.set(message); ``` The `set()` method asks the Mina nodes to update the value of their on-chain state, but only if the associated proof is valid. ### Update `messageHistoryHash` There's one more thing to do. If you want users to be able to keep track of what has been said, then you need to store a commitment to the message history on-chain. There are a few ways to do this, but the simplest way is to store a hash of your new `message` and your old `messageHistoryHash` every time you call `publishMessage`: ```ts // Compute new messageHistoryHash const oldHash = this.messageHistoryHash.get(); const newHash = Poseidon.hash([message, oldHash]); // Update on-chain state this.messageHistoryHash.set(newHash); ``` That's it! Save the file. Now, to make sure everything compiles: ```sh $ npm run build ``` If everything is correct, you see a new `./build` directory where the compiled version of your project lives that you can import into a user interface. ## Wrapping up This tutorial gives you a sense of what's possible with o1js. The messaging protocol you built is quite simple but also very powerful. You can use this basic pattern to create a whistleblower system, an anonymous NFT project, or even anonymous DAO voting. The main point is that o1js makes it easy for you to build things that don't intuitively seem possible. Zero knowledge proofs open the door to an entirely different way of thinking about the internet. We are so excited to see what people like you will build. Make sure to join the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel on Mina Protocol Discord. ## Keep going The logical next steps to extend this project include: - Allow users to pass signers into the `publishMessage()` method directly so that many different organizations can use a single contract. Hint: You'll have to store a commitment to the signers on-chain. - Allow users to pass an arbitrarily large number of signers into the `publishMessage()` method. - Store the message history in a Merkle tree so a user interface can quickly check a subset of the messages without evaluating the entire history. - Build a shiny front end! --- url: /zkapps/tutorials --- # zkApp Developer Tutorials zkApp developer tutorials are a hands-on walk-through of use cases that guide you to achieve a defined goal. o1js, fka. SnarkyJS, is a TypeScript (TS) library for writing general-purpose zk programs and writing zk smart contracts for Mina. To meet other developers building zkApps with o1js, participate in the [#zkapps-developers](https://discord.com/login?redirect_to=%2Fchannels%2F484437221055922177%2F915745847692636181) channel on Mina Protocol Discord. ## Prerequisites Each tutorial has been tested with the latest versions: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) - [o1js](https://www.npmjs.com/package/o1js) o1js is automatically included when you create a project using the zkApp CLI. - Other dependencies as noted. ### Install the zkApp CLI To install the zkApp CLI: ```sh $ npm install -g zkapp-cli ``` To confirm successful installation: ```sh $ zk --version ``` ## Dependencies To use the zkApp CLI and o1js, your environment requires: - NodeJS v18 and later - NPM v10 and later - git v2 and later Use a package manager to install the required versions and upgrade older versions if needed. Package managers for the supported environments are: - MacOS [Homebrew](https://brew.sh/) - Windows [Chocolatey](https://chocolatey.org/) - Linux - apt, yum, and others On Linux, you might need to install a recent Node.js version by using NodeSource. Use [deb](https://github.com/nodesource/distributions#debinstall) or [rpm](https://github.com/nodesource/distributions#rpminstall) as recommended by the Node.js project. To verify your installed versions, use `npm -v`, `node -v`, and `git -v`. ## Tips The full source code for tutorials is provided in the [examples/zkapps/](https://github.com/o1-labs/docs2/tree/main/examples/zkapps/) directory on GitHub. While you're there, give the `/docs2` repository a star so that other zk developers can learn to build a zkApp! Line numbers are provided for convenience. To prevent copying line numbers and command prompts as shown in the tutorials, use the copy code to clipboard button that appears at the top right of the snippet box when you hover over it. ## Useful Resources The API Reference docs are a detailed resource that is useful after you have familiarized yourself with the basics. See the [o1js Reference](/zkapps/o1js-reference) docs for an in-depth explanation of all the methods, properties, and interfaces available in o1js. See the o1Labs blog at https://www.o1labs.org/blog/. For updates about o1js, see https://www.o1labs.org/blog?topics=o1js. If you're just getting started, watch these step-by-step [zkApp Explainer Videos](https://www.youtube.com/playlist?list=PLItixFkgfjYFw6GPqu6vk4NmclOJpT9lE) that go over how to get started building zkApps. Each tutorial includes a link to the corresponding video. While you're on the Mina Foundation YouTube channel, select **Subscribe** so that new videos will show in your Subscriptions feed. --- url: /zkapps/tutorials/interacting-with-zkapps-server-side --- # Interacting with zkApps server-side While user-facing zkApps can be written for the browser, sometimes it is useful to interact with a zkApp server-side or on your own machine. For example, when initializing a zkApp using programmatically generated information, deploying a zkApp in custom ways, or writing scripts that create transactions depending on real-world (periodically updating an on-chain value with signed data, like a keeper for an oracle) or on-chain events. Interacting with zkApps server-side is useful for some use cases. For example, if you need to create a custom account for your zkApp to deploy a zkApp to a different key than the fee payer key. You can programmatically parameterize a zkApp before you initialize it. You can even create a smart contract programmatically for users as part of an application. ## Prerequisites Ensure your environment meets the [Prerequisites](/zkapps/tutorials#prerequisites) for zkApp Developer Tutorials. Before you start this tutorial, you must deploy a smart contract. To do this, read and complete [Tutorial 3: Deploy to a Live Network](deploying-to-a-network) that reuses the smart contract `Square` from [Tutorial 1: Hello World](hello-world). This tutorial has been tested with: - [zkApp CLI](https://www.npmjs.com/package/zkapp-cli) version `0.17.2` - [o1js](https://www.npmjs.com/package/o1js) version `0.16.2` ## Interact with the deployed Smart Contract Now that you successfully created and deployed your project following [Tutorial 3: Deploy to a Live Network](deploying-to-a-network), you can write a script to interact with the smart contract. ### Building on Tutorial 3 For this tutorial, you update the smart contract that you already built for [Tutorial 3: Deploy to a Live Network](/zkapps/tutorials/deploying-to-a-network). You run commands from the root of the `03-deploying-to-a-live-network` directory as you work in the `src` directory on files that contain the TypeScript code for the smart contract. Each time you make updates, then build or deploy, the TypeScript code is compiled into JavaScript in the `build` directory. ### Helper functions in utils.ts To make this more script convenient to write, use the provided helper functions. 1. Download the [utils.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/interacting-with-zkApps-server-side/src/utils.ts) file. 1. Place the file in the project `03-deploying-to-a-live-network/src` folder. 1. Read through the code to understand what it is doing to implement its functionality. The `utils.ts` file contains two functions: - `loopUntilAccountExists()` waits until an account exists on Devnet - `deploy()` programmatically deploys your zkApp ### Connect to a remote network 1. Download the [main.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/interacting-with-zkApps-server-side/src/main.ts) example file. 1. Because you are building on your earlier work, place the `main.ts` file in the project `03-deploying-to-a-live-network/src` folder. 1. Review the code that adds the imports and o1js setup: ```ts import { Square } from './Square.js'; import { Mina, PrivateKey } from 'o1js'; ``` 1. Now, set the active instance to the remote Devnet network. Earlier tutorials set the active instance to a simulated local blockchain, which is fast for development but only available on your local machine and is not decentralized. The connection is made through the GraphQL endpoint exposed by the Mina node connected to the Devnet network. By connecting to the remote Devnet network, you can provide smart contracts that are globally accessible and provide strong guarantees around state due to both Mina's decentralization and its succinct state proof. Review the code that connects to Devnet: ```ts ... const Network = Mina.Network( 'https://api.minascan.io/node/devnet/v1/graphql' ); Mina.setActiveInstance(Network); ... ``` 1. Set a transaction fee that you use to pay for access to sending transactions and deploying smart contracts on Mina. Transaction fees in code are declared as nanomina. Review the code that sets the default transaction fee to 0.1 MINA (100,000,000 nanomina): ```ts ... const transactionFee = 100_000_000; ... ``` This example connects to a remote RPC served by `minascan.io`. You could also run a Mina node locally and instead use its GraphQL endpoint. In other blockchains a local Mina node would be very heavyweight, but because Mina is succinct this is actually a reasonable option. See the Node Operator [Getting Started](/node-operators/block-producer-node/getting-started) docs. ### Public/private key pair You already generated a public/private key pair when you ran the `zk config` command to configure the deployment in [Tutorial 3: Deploy to a Live Network](/zkapps/tutorials/deploying-to-a-network#deploy-alias) the `zk config` command. The public/private key pair was created in `keys/devnet.json`. Public and private keys in Mina are commonly stored in Base58 for easily readability. In Mina, public keys start with `B62` and private keys start with `EK` for easy differentiability. 1. Still in the `main.ts` file, review the code that specifies that the name of the key file must be provided through an argument on the command line: (`process.argv[2]`): ```ts ... const transactionFee = 100_000_000; const deployAlias = process.argv[2]; const deployerKeysFileContents = fs.readFileSync( 'keys/' + deployAlias + '.json', 'utf8' ); const deployerPrivateKeyBase58 = JSON.parse( deployerKeysFileContents ).privateKey; const deployerPrivateKey = PrivateKey.fromBase58(deployerPrivateKeyBase58); const deployerPublicKey = deployerPrivateKey.toPublicKey(); const zkAppPrivateKey = PrivateKey.fromBase58( 'EKFTMuvTirzrwpeHP8RKe7bGufBGiKs27nTMzD5XyMV8NcK3upt2' ); ... ``` You can run this code now with: ```sh $ npm run build && node build/src/main.js devnet ``` The expected output is: ```text > 03-deploying-to-a-live-network@0.1.0 build > tsc state after init: 3 state after txn1: 9 Field.assertEquals(): 75 != 81 state after txn2: 9 state after txn3: 81 ``` - The `npm run build` command creates JavaScript code in the `build` directory. - The `&&` operator links two commands together. - The `node build/src/main.js` command runs the code in `src/main.ts`. - The keys are read from `keys/devnet.json`. The SmartContract is also deployed to the same account you deployed from, set with `zkAppPrivateKey = deployerPrivateKey`. Depending on the application, it can also be useful to have separate keys for the zkApp and deployer accounts. ### Wait for accounts to be ready Next, review the code that waits for the deployer account to be ready. In `main.ts`, the import to use the `loopUntilAccountExists()` function from `utils.ts` goes here: ```ts ... ``` Wait until the new deployment account exists. If the key created from the `zk deploy` command earlier in this tutorial has already been funded, then find the account and move on. If that transaction hasn't finished yet, then wait until that has completed. After the account is found, print out its nonce and its balance. This code compiles the smart contract and waits for it to be deployed: ```ts ... // ---------------------------------------------------- console.log('Compiling smart contract...'); let { verificationKey } = await Square.compile(); const zkAppPublicKey = zkAppPrivateKey.toPublicKey(); let zkapp = new Square(zkAppPublicKey); // Programmatic deploy: // Besides the CLI, you can also create accounts programmatically. This is useful if you need // more custom account creation - say deploying a zkApp to a different key than the fee payer // key, programmatically parameterizing a zkApp before initializing it, or creating Smart // Contracts programmatically for users as part of an application. await deploy(deployerPrivateKey, zkAppPrivateKey, zkapp, verificationKey); await loopUntilAccountExists({ account: zkAppPublicKey, eachTimeNotExist: () => console.log('waiting for zkApp account to be deployed...'), isZkAppAccount: true, }); let num = (await zkapp.num.fetch())!; console.log(`current value of num is ${num}`); // ---------------------------------------------------- ... ``` To do this, reuse the helper function `loopUntilAccountExists()` from `utils.js`. This time, pass in `isZkappAccount: true` checks if the account exists and that there is a verification key on the account. An existing verification key indicates that the zkApp has been successfully deployed. The smart contract was already deployed with `zk deploy` so a programmatic deploy is not required and is commented out here. If you want to see how this works, or it's useful for your application, see the code in [utils.ts](https://github.com/o1-labs/docs2/blob/main/examples/zkapps/interacting-with-zkApps-server-side/src/utils.ts). After the zkApp has been deployed, fetch the current value of `zkapp.num` (the on-chain defined on the `SmartContract`) and log it. If this is the first time you have run this script, the value is `3` because that's how it is set in the smart contract's `init()` function. The `init()` function is called automatically during the first deploy (not during re-deploys). ### Send an update transaction Finally, here is code that sends an update to the transaction. If the zkApp was just initialized, this calls an update on the newly initialized account. Otherwise, it calls an update on whatever the current account state happens to be. ```ts ... // ---------------------------------------------------- let transaction = await Mina.transaction( { sender: deployerPublicKey, fee: transactionFee }, async () => { await zkapp.update(num.mul(num)); } ); // fill in the proof - this can take a while... console.log('Creating an execution proof...'); let time0 = performance.now(); await transaction.prove(); let time1 = performance.now(); console.log(`creating proof took ${(time1 - time0) / 1e3} seconds`); // sign transaction with the deployer account transaction.sign([deployerPrivateKey]); console.log('Sending the transaction...'); let pendingTransaction = await transaction.send(); // ---------------------------------------------------- ... ``` To send an update transaction, perform the following steps: 1. Construct the transaction with `Mina.transaction`. This is where you call `zkapp.update()`, the custom method defined on the smart contract. 2. Create a proof of the transaction. This can take up to a minute. 3. Sign the transaction and send it to the network. When sending the transaction using `transaction.send()`, an object called `pendingTransaction` is returned and provides information about how the transaction went and waits for inclusion in a block: ```ts if (pendingTransaction.status === "rejected") { console.log('error sending transaction (see above)'); process.exit(0); } console.log( `See transaction at https://minascan.io/devnet/tx/${pendingTransaction.hash} Waiting for transaction to be included...` ); await pendingTransaction.wait(); console.log(`updated state! ${await zkapp.num.fetch()}`); ``` This code uses several functionalities of the pending transaction: - `pendingTransaction.status indicates the initial processing status of the transaction, with pending signifying that the transaction has been accepted for processing by the network, and rejected indicating that the transaction was immediately deemed invalid and rejected by the GraphQL endpoint. - `pendingTransaction.hash` is the transaction hash that you can use to look up the transaction in a block explorer. If the transaction failed, it returns `undefined`. - `pendingTransaction.wait()` is especially useful as it returns a promise that resolves whether a transaction is included into a block or rejected. This takes several minutes, so you might not want to block the main thread on this in a real application. Finally, after the transaction was successfully applied on the Mina blockchain, you can double-check that your state was updated by fetching it again with `zkapp.num.fetch()`. ## Conclusion You have finished writing a script to initialize the state and interact with it! You can also run this script multiple times to update `x` to its square. Check out other tutorials and documentation to keep going! --- url: /zkapps/writing-a-zkapp/feature-overview/actions-and-reducer --- :::caution Warning The reducer API in o1js is currently not safe to use in production applications. The `reduce()` method breaks if more than the hard-coded number (default: 32) of actions are pending. Work is actively in progress to mitigate this limitation. When creating updates to unknown accounts in a reducer function, care should be taken to avoid introducing security vulnerabilities. Please follow the guidelines [**here**](/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps#best-practices-for-zkapp-security). ::: # Actions & Reducer Like events, **actions** are _public_ arbitrary information that are passed along with a zkApp transaction. However, actions give you additional power: you can process previous actions in a smart contract! Under the hood, this is possible because a commitment is stored to the history of dispatched actions on every account -- the **actionState**. It allows you to prove that the actions you process are, in fact, the actions that were dispatched to the same smart contract. Using actions and a "lagging state" pattern, you can write zkApps that can _process concurrent state updates by multiple users_. With this capability, you can imagine all kinds of use cases where actions act as a built-in, "append-only" off-chain storage layer. To use actions, you first have to declare their type on the smart contract. The object to declare is called a **reducer** -- because it can take a list of actions and reduce them: ```ts class MyContract extends SmartContract { reducer = Reducer({ actionType: Field }); } ``` Contrary to events, actions have only one type per smart contract. This type doesn't have a name. The `actionType` in this example is `Field`. On a `reducer`, you have two functions: `reducer.dispatch()` and `reducer.reduce()`. - "Dispatch" is simple -- like emitting events, it pushes one additional action to your account's action history: ```ts this.reducer.dispatch(Field(1000)); ``` - "Reduce" is more involved, but it gives you full power to process actions however it suits your application. It might be easiest to grasp from an example where you have a list of actions and want to find out if one of actions is equal to `1000`. In JavaScript, a built-in function on `Array` does this: ```ts let has1000 = array.some((x) => x === 1000); ``` However, you can also implement this with `Array.reduce`: ```ts let has1000 = array.reduce((acc, x) => acc || x === 1000, false); ``` In fact, `Array.reduce` is powerful enough to let you do pretty much all of the array processing you can think of. With `Reducer.reduce`, an in-SNARK operation is just as powerful: ```ts // type for the "accumulated output" of reduce -- the `stateType` let stateType = Bool; // example actions data let actions = [[Field(1000)], [Field(2)], [Field(100)]]; // state before applying actions let initial = { state: Bool(false), }; let newState = this.reducer.reduce( actions, stateType, (state: Bool, action: Field) => state.or(action.equals(1000)), initial ); ``` The `acc` shown earlier is now `state`; you must pass in the state's type as a parameter and pass in an `actionState` which refers to one particular point in the action's history. Like `Array.reduce`, `Reducer.reduce` takes a callback that has the signature `(state: State, action: Action) => State`, where `State` is the `stateType` and `Action` is the `actionType`. It returns the result of applying all the actions, in order, to the initial `state`. In this example, the returned `state` is `Bool(true)` because one of the actions in the list is `Field(1000)`. One last difference to JavaScript `reduce` is that it takes a _list of lists_ of actions, instead of a flat list. Each of the sublists are the actions that were dispatched in one account update (for example, while running one smart contract method). As an astute reader, you might have noticed that this use of `state` is eerily similar to a standard "Elm architecture" that scans over an implicit infinite stream of actions (though here they are aggregated in chunks). This problem is familiar to web developers through its instantiation by using the Redux library or by using the `useReducer` hook in React. There is one interesting nuance here when compared to traditional Elm Architecture/Redux/useReducer instantiations: Because multiple actions are handled concurrently in an undefined order, it is important that actions [commute](https://en.wikipedia.org/wiki/Commutative_property) against any possible state to prevent race conditions in your zkApp. Given any two actions a1 and a2 applying to some state s, `s * a1 * a2` means the same as `s * a2 * a1`. A zkApp can retrieve events and actions from one or more Mina archive nodes. If your smart contract needs to fetch events and actions from an archive node, see [How to Fetch Events and Actions](fetch-events-and-actions). ### Reducer - API reference ```ts reducer = Reducer({ actionType: FlexibleProvablePure }); this.reducer.dispatch(action: Action): void; this.reducer.reduce( actions: MerkleList>, stateType: Provable, reduce: (state: State, action: Action) => State, initial: State, options?: { maxUpdatesWithActions?: number; maxActionsPerUpdate?: number; skipActionStatePrecondition?: boolean; } ): State; ``` The `getActions` function retrieves a list of previously emitted actions: ```ts let pendingActions = this.reducer.getActions({ fromActionState?: Field, endActionState?: Field }): MerkleList>; ``` The final action state can be accessed on `pendingActions.hash`. ```ts let endActionState = pendingActions.hash; ``` If the optional `endActionState` parameter is provided, the list of actions will be fetched up to that state. In that case, `pendingActions.hash` is guaranteed to equal `endActionState`. Use `getActions` for testing with a simulated `LocalBlockchain`. See [Testing zkApps Locally](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally). ### Actions for concurrent state updates One of the most important use cases for actions is to enable concurrent state updates. This enablement is also why actions were originally added to the protocol. You can see a full code example in [reducer-composite.ts](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/reducer/reducer-composite.ts) that demonstrates this pattern. Leveraging `Reducer.reduce()`, it takes only about 30 lines of code to build a zkApp that handles concurrent state updates. --- url: /zkapps/writing-a-zkapp/feature-overview/custom-tokens --- :::info If you want to create a fungible token you can use the [fungible token standard](https://github.com/MinaFoundation/mina-fungible-token/blob/main/documentation/SUMMARY.md) which is built on top of the `TokenContract` class. :::info # Custom Tokens Blockchain applications have various use cases for custom tokens, including a real-world financial asset, stake in an on-chain protocol, or even skill points in a game. Most blockchains, like Ethereum, do not natively support custom tokens. You implement custom tokens as smart contracts on top of the execution layer of the underlying protocol. Token standards ensure the interoperability of applications on Etherum, these standardisations are agree upon in ERCs, Ethereum Request for customElements, such as the fungible token standard [ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/). The Ethereum community has created and agreed upon other reference implementations and standardisation that are audited and easy to configure, such as [ERC-721](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) for NFTs. Mina supports custom token functionality at a low level in the tech stack. Mina treats custom tokens almost the same way as the native MINA token. This approach offers the following benefits: - As a developer, you do not have to manage as many boilerplate contracts. - Developers don't need to keep track of accounts and balances themselves. - It is more secure because fewer vulnerabilities can result from incorrect configuration and deployment. Each account on Mina can have tokens associated with it. With zkApps, you build smart contracts that interact with tokens, such as swapping one token for another or depositing MINA tokens. A token manager smart contract is a standard smart contract with the `TokenContract` class that manipulates tokens. ## Token manager account The token manager account can set a token symbol (also called token name) for its token. For example, `MYTKN`. Uniqueness is not enforced for token names because the public key of the manager account is used to derive a unique identifier for each token. A token manager smart contract sets the rules around minting, burning, and sending the custom token: - Minting generates new tokens. The zkApp updates an account's balance by adding the newly created tokens to it. You can send minted tokens to any existing account in the network. - Burning tokens is the opposite of minting. Burning tokens deducts the balance of a certain address by the specified amount. A zkApp cannot burn more tokens than the specified account has. - Sending tokens between two accounts must be approved by a zkApp. ## TokenContract class Use the `TokenContract` class to perform common token operations, such as minting, burning, and sending tokens. In o1js, the `TokenContract` class is your blueprint for custom token implementations. As shown in this [example code](https://github.com/o1-labs/o1js/blob/main/src/lib/mina/token/token-contract.unit-test.ts#L13), you inherit from the `TokenContract` class: ```ts class ExampleTokenContract extends TokenContract { // your custom token implementation } ``` ## TokenContract API The `TokenContract` comes with a set of prebuilt methods and helpers to get you started in your token journey. The base token smart contract implements the following two APIs: - `Approvable` leaves the `approveBase()` method to be defined by the subclass - `Transferable` a wrapper around `Approvable` that deals with transfers of token Additionally, the token smart contract also comes with an `internal` namespace which contains helper methods that can be used from within a token contract only. ```ts TokenContract.internal: { /** * Mints token balance to `address`. Returns the mint account update. */ mint( address: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; ): AccountUpdate; /** * Burn token balance on `address`. Returns the burn account update. */ burn( address: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; ): AccountUpdate; /** * Move token balance from `from` to `to`. Returns the `to` account update. */ send( from: PublicKey | AccountUpdate | SmartContract; to: PublicKey | AccountUpdate | SmartContract; amount: number | bigint | UInt64; ): AccountUpdate; } ``` ### The Approvable API Each subclass token contract that inherits the default `TokenContract` must implement the core `approveBase()` method. It has the following signature: ```ts approveBase(forest: AccountUpdateForest): void; ``` The `TokenContract` also containts helper methods that make it easy to iterate through and approve a forest of child account updates. The usual implementation is as easy as this: ```ts @method async approveBase(forest: AccountUpdateForest) { this.checkZeroBalanceChange(forest); } ``` However, if you want to do a custom implementation for every child account update, you can utilize the `forEachUpdate()` method. ```ts @method async approveBase(updates: AccountUpdateForest) { let totalBalanceChange = Int64.zero; this.forEachUpdate(updates, (accountUpdate, usesToken) => { totalBalanceChange = totalBalanceChange.add( Provable.if(usesToken, accountUpdate.balanceChange, Int64.zero) ); // additional logic }); // prove that the total balance change is zero totalBalanceChange.assertEquals(0); } ``` The `Approvable` API also provides easy to use wrappers around `approveBase()`, such as the following: ```ts abstract class TokenContract extends SmartContract { /** * Approve a single account update (with arbitrarily many children). */ approveAccountUpdate(accountUpdate: AccountUpdate): Promise;; /** * Approve a list of account updates (with arbitrarily many children). */ approveAccountUpdates(accountUpdates: AccountUpdate[]): Promise;; /** * Transfer `amount` of tokens from `from` to `to`. */ transfer(from: PublicKey | AccountUpdate, to: PublicKey | AccountUpdate, amount: UInt64): Promise;; } ``` ### The Transferable API The `Transferable` API is a simple wrapper around the `Approvable` API. It implements the following method: ```ts abstract class TokenContract extends SmartContract { /** * Transfer `amount` of tokens from `from` to `to`. */ transfer( from: PublicKey | AccountUpdate, to: PublicKey | AccountUpdate, amount: UInt64 | number | bigint ): Promise; } ``` Which utlizses the `Approvable` API to send token from an account to another one. ## Custom Token Terminology If your zkApp interacts with custom tokens, here are the essential terms. ### Token id Token ids are unique identifiers that distinguish between different types of custom tokens. Custom token identifiers are globally unique across the entire network. Token ids are derived from a zkApp. To check the token id of a zkApp, use the `this.token.id` property. ### Token Accounts Token accounts are like regular accounts, but they hold a balance of a specific custom token instead of MINA. A token account is created from an existing account and is specified by a public key _and_ a token id. Token accounts are specific for each type of custom token, so a single public key can have many different token accounts. A token account is automatically created for a public key whenever an existing account receives a transaction denoted with a custom token. When a token account is created for the first time, an account creation fee must be paid the same as creating a new standard account. In addition to sending custom tokens, a **token owner account** can mint and burn custom tokens. A token owner account is the governing zkApp account for a specific custom token. ### Token Owner A token owner is an zkApp account that creates, facilitates, and governs how a custom token can be used. The token owner is the account that created the custom token and is the only account that can: - Mint tokens - Burn tokens - Approve sending tokens between two accounts --- url: /zkapps/writing-a-zkapp/feature-overview/events --- # Events Events are _public_ arbitrary information that can be passed along with a transaction. If your zkApp allows users to publish a message, for example, those messages could be events. Another use case for events are zkApps that keep some large internal state and only store a commitment to that internal state on-chain. For example, a Merkle tree where only the root is stored in on-chain state. Events could be used to attach state changes to the transactions in full. In the Merkle tree example, this could mean sending any Merkle leaves that are changed by the transaction as events. An observer of these transactions can follow along and keep track of the full Merkle tree on their side. To use events, you must declare an `events` field at the top level of your smart contract. The `events` field contains the _names_ and _types_ of your events. Here's an example: ```ts class MyContract extends SmartContract { events = { 'add-merkle-leaf': Field, 'update-merkle-leaf': Field, }; } ``` This example declares events called `"add-merkle-leaf"` and `"update-merkle-leaf"`, both with a type of `Field`. Instead of `Field`, you can also use other built-in o1js types as well as any `Struct`. In fact, a custom `Struct` is probably better-suited to encode leaves of a Merkle tree -- we just use `Field` for simplicity here. After declaring your events, you can use `this.emitEvent(name, event)` in any smart contract method, where `event` has to have the type you declared for that `name`. Example: ```ts class MyContract extends SmartContract { events = { "add-merkle-leaf": Field, "update-merkle-leaf": Field, } @method async updateMerkleTree(leaf: Field, ...) { this.emitEvent("update-merkle-leaf", leaf); // ... } } ``` Some important facts about events: - Events are not stored on-chain. Only events from the most recent couple of transactions are retained by consensus nodes. After that, the events are discarded, but are still accessible on archive nodes. - You can't refer to previously emitted events in a smart contract, because there is no way of proving that the events you refer to are actually the events emitted by that contract. :::tip A zkApp can retrieve events and actions from one or more Mina archive nodes. If your smart contract needs to fetch events and actions from an archive node, see [How to Fetch Events and Actions](fetch-events-and-actions). ::: This is all you need to know about events! Think of them as a convenience feature -- a lightweight way of attaching information about your smart contract execution to expose the event to the outside world, such as your UI. Don't treat events as fully-fledged storage that can be safely accessed in smart contracts. ### Events: API reference ```ts class SmartContract { static events?: Record; emitEvent(name: string, event: any): void; } ``` --- url: /zkapps/writing-a-zkapp/feature-overview/fetch-events-and-actions --- # How to Fetch Events and Actions Events and Actions are two distinct mechanisms for logging information alongside a transaction: - Events are not meant for use within proofs directly, as they can't be predicated on inside proofs. Events are used to signal to UIs. You can also use events for reconstructing Merkle trees. - Actions can be accessed within provable code by using reducers. :::info Events and actions are not stored in the ledger and exist only on the transaction. :::info Since Mina nodes do not store historical network information and events and actions are not kept on-chain, emitted events and actions are preserved only in the archive node. Consequently, a zkApp can retrieve previously emitted events and actions from one or more Mina archive nodes. The Mina archive node offers the ability for node operators to store historical blockchain data using `PostgreSQL`. However, archive nodes do not expose a built-in API to query this data publicly. ## Using the Archive Node API with o1js There are two parts to using the archive node with o1js: - Archive node operators run the [Archive-Node-API](https://github.com/o1-labs/archive-node-api) to provide a GraphQL API from which zkApp smart contracts can retrieve events and actions. - o1js developers specify the archive node API endpoint during the network configuration to allow access to historical events and actions. The `Archive-Node-API` enables o1js to fetch events and actions. ## o1js network configuration If your smart contract needs to fetch events and/or actions from an archive node, provide an `archive` property in the configuration object passed to the `Mina.Network({mina: '...', archive: '...'})` where the `archive` property value is the URL for the `Archive-Node-API` service that you want to use. If this property does not exist, an error will occurs at the time of the events/actions fetching. For example: ```ts const Network = Mina.Network({ mina: 'https://api.minascan.io/node/devnet/v1/graphql', archive: 'https://api.minascan.io/archive/devnet/v1/graphql', }); Mina.setActiveInstance(Network); ``` ## Fetching Actions from an Archive Node Within your smart contract, you can use `getActions()` to retrieve actions emitted by your smart contract as part of previous transactions. ```ts class MyContract extends SmartContract { ... @method async getActionsExample() { // Get all actions for this zkApp let pendingActions = this.reducer.getActions({ fromActionState: actionsState, }); this.reducer.reduce( pendingActions, Field, (state: Field, action: Field) => { ... }, { state: counter, actionsState } ); } } ``` By default, `getActions()` retrieves all actions from the very first action emitted for that zkApp account. However, you can provide an object that contains an optional property named `fromActionState`, where the value is an `actionsState` to indicate the starting point of the actions to be retrieved and processed by your smart contract. For an end-to-end example of zkApp fetching actions from a running network and storing the action state within your zkApp account, see the voting app [example](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/voting/voting.ts) file that is provided in the o1js repo. ### Fetching Events from an Archive Node Outside of smart contracts, you can use `fetchEvents()` to retrieve events emitted by your smart contract as part of previous transactions. ```ts const zkapp = new MyContract(address); // Fetch all events from zkapp starting at block 0 const events = await zkapp.fetchEvents(UInt32.from(0)); // Fetch all events starting at block 560 and ending at block 600 const events = await zkapp.fetchEvents(UInt32.from(560), UInt32.from(600)); // Fetch all events for a given address const fetchedEvents = await fetchEvents({ publicKey: 'B62qrfn5xxChtPGJne9HuDJZ4ziWVgWxeL3hntGBqMmf45p4hudo3tw', }); ``` By default, `fetchEvents()` retrieves all events from the very first event ever emitted for that zkApp account. Additionally, you can provide a starting block height and an ending block height as optional parameters to limit the range of events fetched. - If the ending block is not provided, `fetchEvents()` fetches all events up to the latest block. - If the starting block is not provided, it fetches all events from the beginning of the zkApp's history. To see an end-to-end example of zkApp fetching events from a running network, see the [example](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/voting/run-berkeley.ts) file that is provided in the codebase repo. --- url: /zkapps/writing-a-zkapp/feature-overview/offchain-storage --- :::experimental Offchain storage is currently an experimental feature and is subject to change in the future. ::: # Offchain Storage One of Mina's unique features is its succinctness, both in computation and storage. To prevent state bloat and maintain Mina's efficiency and verifiability, we use offchain storage solutions for handling large volumes of data. In a previous section, we introduced the concept of on-chain Values. Since Mina currently only supports a total of 8 on-chain Field elements, we need to leverage offchain storage to extend that capacity. This approach maintains a provably secure connection between the on-chain smart contract and the off-chain data, such as that stored in an archive node. ## Design Presently, Offchain storage offers support for two types of state: `OffchainState.Field`, representing a single field of state, and `OffchainState.Map`, akin to the key-value maps found in JavaScript, like `let myMap = new Map();`. All offchain state resides within a single Merkle Map, which is essentially a wrapper around a [Merkle Tree](/zkapps/o1js/merkle-tree.mdx). Practically speaking, there are no constraints on the number of state fields and maps that a developer can store in a smart contract using Offchain storage. Under this framework, [Actions and Reducer](/zkapps/writing-a-zkapp/feature-overview/actions-and-reducer.mdx) are utilized to manage state changes, with actions dispatching state updates and reducers settling them. Additionally, a Merkle Tree is employed to maintain a provably secure commitment to the data, with the root stored on-chain. Prior to users accessing published state, it must first undergo settlement. Thanks to the design of Offchain storage, all state is recoverable from actions alone, eliminating the need for additional events or external data storage. ## Utilizing Offchain Storage ### Prerequisites The `OffchainState` API is accessible within the `Experimental` namespace. To use `OffchainState`, import `Experimental` from o1js version 1.9.1 or higher. ```ts const { OffchainState, OffchainStateCommitments } = Experimental; ``` ### Setting up Offchain Storage To integrate Offchain storage, developers must initially define an Offchain state configuration and a state proof type, then prepare the smart contract. The `OffchainState` configuration allows specification of the desired Offchain state type, including key-value pairs in a map and any additional required state. The `StateProof` type will subsequently be used to finalize published state changes using a recursive reducer and the `OffchainStateInstance` stores internal data such as which contract instance it is associated with and the Merkle trees of data. ```ts const offchainState = OffchainState({ players: OffchainState.Map(PublicKey, UInt64), totalScore: OffchainState.Field(UInt64), }); class StateProof extends offchainState.Proof {} const offchainStateInstance = offchainState.init(); ``` Developers also need to set the smart contract instance and assign it to the offchain storage. This also compiles the recursive Offchain zkProgram in the background and assigns the Offchain state to the smart contract instance property. ```ts let contract = new MyContract(contractAddress); contract.offchainState.setContractInstance(contract); // compile Offchain state program await offchainState.compile(); // compile smart contract await ExampleContract.compile(); ``` To settle the offchain state, an Offchain storage proof must be generated and provided to the smart contract's `settle()` method. This method automatically retrieves all pending actions (state changes) and resolves them using a recursive reducer. Finally, the proof is passed to the `settle()` method. ```ts let proof = await offchainState.createSettlementProof(); await Mina.transaction(sender, () => { // settle all outstanding state changes contract.settle(proof); }) .sign([sender.key]) .prove() .send(); ``` ### Configuring Your Smart Contract The smart contract requires a field containing a commitment to the offchain state. This field is used internally by the `OffchainState` methods and should not be written to by your smart contract logic. It is also required that an `offchainStateInstance` be assigned to the smart contract’s instance property to ensure correct offchain state management. ```ts class MyContract extends SmartContract { @state(OffchainState.Commitments) offchainStateCommitments = offchainState.emptyCommitments(); offchainState = offchainStateInstance; } ``` The contract also needs a `settle()` method to resolve all pending state updates. This method verifies a recursive proof to finalize all pending state changes, with the proof being generated before invoking the `settle()` method. ```ts class MyContract extends SmartContract { // ... @method async settle(proof: StateProof) { await offchainState.settle(proof); } } ``` :::note State is only available after it was settled via `settle()`! ::: ### Utilizing Offchain Storage Now developers can utilize Offchain storage in any of their smart contract methods, as demonstrated below: ```ts class MyContract extends SmartContract { // ... @method async useOffchainStorage(playerA: PublicKey) { // retrieve totalScore, returning an Option let totalScoreOption = await this.offchainState.fields.totalScore.get(); // unwrap the Option and return a default value if the entry if empty let totalScore = totalScoreOption.orElse(0n); // increment totalScore, set a precondition on the state // (if `from` is undefined, the precondition is that the field is empty) this.offchainState.fields.totalScore.update({ from: totalScoreOption, to: totalScore.add(1), }); // retrieve an entry from the map, returning an Option let playerOption = await this.offchainState.fields.players.get(playerA); // unwrap the player's score Option and return a default value if the entry is empty let score = playerOption.orElse(0n); // increment the player's score, set a precondition on the previous score this.offchainState.fields.players.update(playerA, { from: playerOption, to: score.add(1), }); } } ``` Currently, Offchain states of type Field support `field.get()` and `field.overwrite(newValue)`, while maps support `map.get(key)` and `map.overwrite(key, newValue)`. The `.overwrite()` method sets the value without taking into account the previous value. If the value is modified by multiple zkkApps concurrently, interactions that were applied earlier will simply be overwritten! All Offchain storage types also provide an `.update()` method which is a safe version of `.overwrite()`. The `.update()` method lets you define a precondition on the state that you want to update. If the precondition of the previous value does not match, the update will not be applied: ```ts field.update(config: { // `from` is the precondition on the previous state from: Option, // `to` is the new state to set to: T, }); ``` Note that the precondition is an `Option` type: setting it to `None` means that you require the field to not exist, while `Some(value)` requires that it exists and contains the `value`. The return value of `get()` is an `Option` with the same semantics, and can be passed to `update()` directly. Important: When `update()` fails due a mismatching precondition, _none_ of the state updates made in the same method call will be applied. This lets you safely write logic where multiple fields are linked and have to be updated in a consistent way, like in the example above where the total score has to be the sum of all player's scores. ## Additional Resources This feature remains experimental, indicating that it is currently under active development. For further insight into its implementation, please refer to the following pull requests and examples on GitHub: - [Experimental Offchain Storage part 1](https://github.com/o1-labs/o1js/pull/1630) - [Experimental Offchain Storage part 2](https://github.com/o1-labs/o1js/pull/1652) - [An end-to-end example utilizing Offchain storage](https://github.com/o1-labs/o1js/blob/main/src/lib/mina/v1/actions/offchain-contract-tests/ExampleContract.ts) --- url: /zkapps/writing-a-zkapp/feature-overview/on-chain-values --- # On-Chain Values In a zkApp, you can access the current [on-chain state](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp) and many other on-chain values of the account. The zkApp account's on-chain state can be updated by account updates included in a transaction (see [Tutorial 10: Account Updates](/zkapps/tutorials/account-updates)). On the Mina blockchain, each zkApp account provides eight fields of ~32 bytes each of arbitrary storage for the on-chain state. Two possible use cases: - You want to let users vote on a proposal, but only within a specific timespan. To restrict the dates, your zkApp can require that the current timestamp lies in a certain range. - In DeFi, you want to compute amounts relative to a balance. For example, paying a yield of `0.001` times the account balance requires the current on-chain balance. There are two categories of on-chain values: - **Network**: includes the current timestamp, block height, total Mina in circulation, and other network state - **Account**: includes fields and properties of the zkApp account, such as balance, nonce, and delegate In a smart contract, the subfields are accessible on `this.network` and `this.account`. For example, the timestamp on `this.network.timestamp` has four methods: ```ts this.network.timestamp.get(); this.network.timestamp.requireEquals(timestamp); this.network.timestamp.requireBetween(lower, upper); ``` - The familiar on-chain state has the same `get()` and `requireEquals()` methods. - The `requireBetween()` method has even more power: it allows you to make assertions that the timestamp is between `lower` and `upper` (inclusive). ### Example: Restricting timestamps To use the `requireBetween()` method in a voting example, you can allow voting throughout September 2024. Timestamps are represented as a `UInt64` in milliseconds since the [UNIX epoch](https://en.wikipedia.org/wiki/Unix_time). You can use the JS `Date` object to easily convert to this representation. In the simplest case, a zkApp could just hard-code the dates: ```ts const startDate = UInt64.from(Date.UTC(2024, 9, 1)); const endDate = UInt64.from(Date.UTC(2024, 10, 1)); class VotingApp extends SmartContract { // ... @method async vote(...) { this.network.timestamp.requireBetween(startDate, endDate); // ... } } ``` A more refined example could store the current start date in an on-chain state variable, which can then be reset by some process that is also encoded by the zkApp. ### Network reference For completeness, here is the list of network states you can use and make assertions about in your zkApp. All of these fields have a `get()` and an `requireEquals()` method. The subset that represents "ordered values" (those that are `UInt32` or `UInt64`) also have `requireBetween()`. ```ts // current UNIX time in milliseconds, as measured by the block producer this.network.timestamp.get(): UInt64; // length of the blockchain, also known as block height this.network.blockchainLength.get(): UInt32; // total minted currency measured in units of 1e-9 MINA this.network.totalCurrency.get(): UInt64; // slots since genesis / hardfork -- a "slot" is the Mina-native time unit of 3 minutes this.network.globalSlotSinceGenesis.get(): UInt32; this.network.globalSlotSinceHardFork.get(): UInt32; // hash of the snarked ledger -- i.e., the state of Mina included in the blockchain proof this.network.snarkedLedgerHash.get(): Field; // minimum window density in our consensus algorithm this.network.minWindowDensity.get(): UInt32; // consensus data relevant to the current staking epoch this.network.stakingEpochData.ledger.hash.get(): Field; this.network.stakingEpochData.ledger.totalCurrency.get(): UInt64; this.network.stakingEpochData.epochLength.get(): UInt32; this.network.stakingEpochData.seed.get(): Field; this.network.stakingEpochData.lockCheckpoint.get(): Field; this.network.stakingEpochData.startCheckpoint.get(): Field; // consensus data relevant to the next, upcoming staking epoch this.network.nextEpochData.ledger.hash.get(): Field; this.network.nextEpochData.ledger.totalCurrency.get(): UInt64; this.network.nextEpochData.epochLength.get(): UInt32; this.network.nextEpochData.seed.get(): Field; this.network.nextEpochData.lockCheckpoint.get(): Field; this.network.nextEpochData.startCheckpoint.get(): Field; ``` You don't have to remember this, just type `this.network.` and let the intelligent code complete guide you. ### Account reference Here's the full list of values you can access on the zkApp account. Like the network states, these values have `get()` and `requireEquals()`. Balance and nonce also have `requireBetween()`. ```ts // the account balance; this might be nanoMINA or a custom token this.account.balance.get(): UInt64; // account nonce -- increases by 0 or 1 in every transaction this.account.nonce.get(): UInt32; // the account the zkApp delegates its stake to (default: its own address) this.account.delegate.get(): PublicKey; // boolean indicating whether an account is new (= didn't exist before the transaction) this.account.isNew.get(): Bool; // boolean indicating whether all 8 on-chain state fields were last changed by a transaction // authorized by a zkApp proof (as opposed to a signature) this.account.provedState.get(): Bool; // hash receipt which includes all prior transaction to an account this.account.receiptChainHash.get(): Field; ``` ### Bailing out In some rare cases, you might, for whatever reason, want to `get()` an on-chain value _without_ constraining it to any value. However, if you try this, o1js throws a helpful error reminding you to use `requireEquals()` and `requireBetween()`. As an escape hatch, if you want to `get()` a value and are really sure you do not want to constrain the on-chain value in any way, you can use `requireNothing()` on all of these fields (including on-chain state). **Use `requireNothing()` at your own risk.** :::danger `requireNothing()` should be rarely used and could cause security issues through unexpected behavior if used improperly. Be certain you know what you're doing before using this. ::: ### Setting account fields Just like on-chain state, some account fields can be written to. Again, the API is consistent with state: `this.account..set(newValue)`. For example, here's how to change permissions on an account: ```ts this.account.permissions.set({ ...Permissions.default(), setVerificationKey: { auth: Permissions.proof(), txnVersion: TransactionVersion.current(), }, }); ``` To set the delegate (the account that your smart contract delegates its stake to): ```ts this.account.delegate.set(delegatePublicKey); ``` The fields that you can set are not the same as the fields that you can make assertions about. Here is the full list of fields that have a `.set()`: ```ts // the account that this account delegates its MINA stake to this.account.delegate.set(value: PublicKey); // the verification key this.account.verificationKey.set(value: VerificationKey); // account permissions, to control authorization for performing actions on the account this.account.permissions.set(value: Permissions); // currently unused - could become URL holding zkApp metadata this.account.zkappUri.set(value: string); // token symbol of the token owned by this account — only relevant for token contracts! this.account.tokenSymbol.set(value: string); // parameters to control a vesting schedule, used in time-locked accounts this.account.timing.set(value: Timing); ``` ### Accessing accounts other than the zkApp's account The API described in this section (get / set / assertEquals / ...) can be used to access the zkApp account itself, but also any other account. Account updates are a flexible and powerful data structure that can express all kinds of updates, events, and preconditions you use to develop smart contracts. See [Tutorial 10: Account Updates](/zkapps/tutorials/account-updates). To create an account update to find the same `account` and `network` fields: ```ts let accountUpdate = AccountUpdate.create(address); // use the balance of this account let balance = accountUpdate.account.balance.get(); accountUpdate.account.balance.assertEquals(balance); // assert that this account is new accountUpdate.account.isNew.assertEquals(Bool(true)); // set permissions this account accountUpdate.account.permissions.set(permissions); ``` When setting fields on an account update, you must ensure that this _same_ account update has the correct authorization to perform those actions. For example, to initially set the verification key, the update requires a signature from the account owner: ```ts // use createSigned to require a signature let accountUpdate = AccountUpdate.createSigned(address); // set the verification key on the account; could be used to deploy a zkApp from a zkApp accountUpdate.account.verificationKey.set(vk); ``` --- url: /zkapps/writing-a-zkapp/feature-overview/permissions --- # Permissions Permissions are an integral part of zkApp development because they determine who has the authority to interact and make changes to a specific part of a smart contract. Naturally, every smart contract must have proper permissions to prevent attacks or security holes. Permissions live on-chain, which means they are a part of the account representation on the network. Permissions are checked every time an account update tries to interact with an account. ## Types of Permissions There are 13 different types of permissions that you can access and adjust to guard a zkApp account: - `editState`: The permission describing how the zkApp account's eight on-chain state fields are allowed to be manipulated. - `send`: The permission corresponding to the ability to send transactions from this account. For example, this permission determines whether someone can send a transaction to transfer MINA from this particular account. - `receive`: Similar to `send`, the `receive` permission determines whether a particular account can receive transactions, for example, depositing MINA. - `setDelegate`: The permission corresponding to the ability to set the delegate field of the account. The delegate field is the address of another account that this account is delegating its MINA for staking. - `setPermissions`: The permission corresponding to the ability to change the permissions of the account. As the name suggests, this type of permission describes how already set permissions can be changed. - `setVerificationKey`: The permission corresponding to the ability to change the verification key of the account. Every smart contract has a verification key stored on-chain. The verification key is used to verify off-chain proofs. This permission essentially describes if the verification key can be changed; you can also think of it as the "upgradeability" of smart contracts. - `setZkappUri`: The permission corresponding to the ability to change the `zkappUri` field of the account that stores metadata about the smart contract, for example, link to the source code. - `editActionsState`: The permission that corresponds to the ability to change the actions state of the associated account. Every smart contract can dispatch actions that are committed on-chain. This type of permission describes who can change the actions state. - `setTokenSymbol`: The permission corresponding to the ability to set the token symbol for this account. The `tokenSymbol` field stores the symbol of a token. - `incrementNonce`: The permission that determines whether to increment the nonce with an account update and who can increment the nonce on this account with a transaction. - `setVotingFor`: The permission corresponding to the ability to set the chain hash for this account. The `votingFor` field is an on-chain mechanism to set the chain hash of the hard fork this account is voting for. - `access`: This permission is more restrictive than all the other permissions combined! It corresponds to the ability to include any account update for this account in a transaction, even no-op account updates. Usually, the access permission is set to require no authorization. However, for token manager contracts [(custom tokens)](custom-tokens), `access` requires at least proof authorization so that token interactions are approved by calling one of the token manager's methods. - `setTiming`: The permission corresponding to the ability to control the vesting schedule of time-locked accounts. ## Authorization Authorization determines what resources can be accessed, while permissions just describe who has the ability to execute an action. A transaction consists of multiple account updates (sort of like instructions to the network) - and each account update must be authorized in one way or another. When you inspect an account update directly in o1js or using an explorer, you see the `authorization` field. - If the `authorization` field has a proof attached, it means the transaction is authorized by a proof that is checked against the verification key of the account. - If the `authorization` field has a signature, it means the account update is authorized by a signature. ### Types of Authorizations The types of authorizations are: - `none`: Everyone has access to fields with permission set to `none` - and therefore can manipulate the fields as they please. - `impossible`: If a field permission is set to `impossible`, nothing can ever change this field! - `signature`: Fields that have their permission set to `signature` can only be manipulated by account updates that are accompanied and authorized by a valid signature. - `proof`: Fields that have their permission set to `proof` can be manipulated only by account updates that are accompanied and authorized by a valid proof. Proofs are generated by proving the execution of a smart contract method. A proof is checked against the verification key of the account to ensure that state is changed only if the user generated a valid proof by executing a smart contract method correctly. - `proofOrSignature`: As the name might suggest, permissions with authorization set to `proofOrSignature` accept either a valid signature or a valid proof. This example account update is authorized by a signature: ```json { "authorization": { "proof": null, "signature": "7mXAcTFeybdZkFmYmfoRYRzVeMxQsGU5Uxq1RpRpGSkHEa5ZEraTRJ4cNKMnAS1n3NCmVqDnHUyraJs131dcdFi3sZH1Qzos" }, // ... "body": { // ... "update": { "appState": ["1", "0", "0", "0", "0", "0", "0", "0"] // ... } // ... } } ``` This example account update has an authorization with a `signature` provided. You can also see it's trying to update the app state of the smart contract. However, imagine if a smart contract had the the permission `editState` set to the authorization `none`. When authorization is `none`, everyone can freely change the state of the smart contract as they please! Obviously, this is not a safe practice. To allow state changes only when a valid proof accompanies the account update that wants to access the state, set your authorization to `proof` so that the transaction is authorized by a proof that is checked against the verification key of the account. Using a `proof` authorization ensures that state is changed only if the user generated a valid proof by executing a smart contract method correctly. ## Default Permissions Smart contracts, when first deployed, always start with this default set of permissions: `editState`: `proof` `send`: `proof` `receive`: `none` `setDelegate`: `signature` `setPermissions`: `signature` `setVerificationKey`: `signature` `setZkappUri`: `signature` `editActionsState`: `proof` `setTokenSymbol`: `signature` To better understand how to leverage permissions to make your smart contract more secure, look at these examples. ## Example: UnsecureContract Some smart contracts manage state and token, such as the native MINA token. To prevent malicious actors from withdrawing all funds, use permissions to secure them. Consider the following `UnsecureContract` smart contract. A similar [simple-zkapp-payment.ts](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/simple-zkapp-payment.ts) contract is also provided in the `examples` folder: ```ts class UnsecureContract extends SmartContract { init() { super.init(); this.account.permissions.set({ ...Permissions.default(), send: Permissions.none(), }); } @method async withdraw(amount: UInt64) { this.send({ to: this.sender, amount }); } } ``` This `UnsecureContract` has only the `withdraw()` method for withdrawing funds from the smart contract account. But first, notice that the permissions specified in the `init()` method have set the `send` permission to `Permissions.none()`. Because `none` means you don't have to provide _any_ form of authorization, a malicious actor can easily drain all funds from the smart contract. Take a look at the following malicious transaction that abuses this permission: ```ts tx = await Mina.transaction(account1Address, async () => { let withdrawal = AccountUpdate.create(zkappAddress); await withdrawal.send({ to: account1Address, amount: 1e9 }); }); await tx.sign([account1Key]).send(); ``` This transaction creates a new account update for the smart contract address. Right after that, the new account update sends 1 MINA to the address of the fee payer (`account1Address`). At the end of the transaction block, the transaction is signed only with the private key of the fee payer -- not the private key of the smart contract. Because the permissions for sending funds away from a smart contract are set to `none`, this transaction succeeds and drains 1 MINA from the smart contract. Now, change the `send` permission to `signature` instead: ```diff - send: Permissions.none(), + send: Permissions.signature(), ``` If you try to run the same transaction as before, the manual account update fails with `Update_not_permitted_balance`. This check prevents withdrawing funds from the smart contract, since the authorization does not fit the permission for `send` that now requires a valid signature. You can slightly modify the withdraw transaction to include a valid signature by adding `.requireSignature()` on the withdrawal account update and providing the private key of the smart contract account to `tx.send([zkappKey])`: ```ts tx = await Mina.transaction(account1Address, async () => { let withdrawal = AccountUpdate.create(zkappAddress); await withdrawal.send({ to: account1Address, amount: 1e9 }); withdrawal.requireSignature(); }); await tx.sign([account1Key, zkappKey]).send(); ``` Now that you have provided a valid signature, the transaction succeeds. However, this way of authorizing a transaction is not what you expect from a smart contract. If you set a permission to `signature`, only the owner of the zkApp's private key (`zkappKey`) is able to perform the interaction. However, the point of a smart contract is to let anyone interact by trustlessly executing the smart contract code. For enabling a trustless execution, use `Permissions.proof()`. Now, to make `UnsecureContract` a proper smart contract, set the `send` permission to `proof`: ```diff - send: Permissions.signature(), + send: Permissions.proof(), ``` Alternatively, you can just delete the entire `init()` method, since a `send` permission of `proof` is already the default: ```diff - init() { - super.init(); - this.account.permissions.set({ - ...Permissions.default(), - send: Permissions.signature(), - }); - } - ``` If you try running one of the two transactions from before, which created account updates manually, you'll find that they both fail with `Update_not_permitted_balance`. Setting the `send` permission to `proof` means that, to send MINA from this account, you need to execute one of the contract's `@method`. The contract already has an `@method` that you can use: `withdraw()`. To create a withdrawal transaction that contains a valid proof: ```ts tx = await Mina.transaction(account1Address, async () => { let zkapp = new UnsecureContract(zkappAddress); await zkapp.withdraw(UInt64.from(1e9)); }); await tx.prove(); await tx.sign([account1Key, zkappKey]).send(); ``` In contrast to the other examples, you don't explicitly create an `AccountUpdate`. Instead, you instantiate `UnsecureContract` and call its `withdraw()` method. Each method call is automatically associated with an account update, for which it creates a valid proof. You can access and modify this account update by using `this` inside the method. In this example, use `this.send(...)` to send MINA. By calling the method and doing `tx.prove()`, you satisfy the `proof` authorization requirement for sending MINA. You might have noticed that the contract is still not very secure: Anyone can call the `withdraw()` method to drain any amount of MINA from the contract. That's why the example is called `UnsecureContract`. In a real contract, you would add some conditions to the `withdraw()` code to restrict which users can successfully call the method. ## Upgradeability of smart contracts Another important part of smart contract development is upgradeability. By using permissions, you can make a smart contract upgradeable or not upgradeable. On Mina, when you deploy a smart contract you generate a verification key from the contract source code. The verification key and the smart contract are stored on-chain and used to verify proofs that belong to that smart contract. Remember the permission called `setVerificationKey`? Modify the authorization for this permission to set the upgradability of the smart contract. ### Upgrading after an update to the Mina Protocol At some point, Mina Protocol will undergo an update that is not backwards compatible. When this happens, existing zkApps will need to upgrade their verification key to be compatible with the new protocol. If the zkApp does not upgrade, the existing verification key will not be able to verify proofs and the zkApp will be unable to interact with the network, effectively rendering it useless. To ensure that zkApps can upgrade their verification key after a protocol update, there are special rules in place for the `Impossible` and `Proof` permissions on a verification key. Recall that the `Impossible` permission prevents the verification key from being changed, while the `Proof` permission requires a valid proof to do so. Internally, verification key permissions are represented as a tuple of two fields: the mechanism that controls verification key changes (e.g. `Impossible`, `Signature`, `Proof`), and a transaction version field (denoted by an integer). The transaction version field specifies the version of a transaction that was supported by the protocol when the zkApp's verification key was deployed. This allows the protocol to appropriately enforce permissions when a zkApps was deployed on an earlier version that may no longer be supported. To allow zkApps to upgrade their verification key after a protocol upgrade, the `Impossible` and `Proof` verification key permissions are automatically treated as `Signature` permissions when the zkApp's transaction version is lower than the current one on Mina Protocol. This allows zkApps to upgrade their verification key after a protocol upgrade, even if the permission was originally set to `Impossible` or `Proof`. Thus, `setVerificationKey` field behaves slightly different and requires two properties. ```ts setVerificationKey: { auth: Permission, txnVersion: TransactionVersion }, ``` The first property, `auth`, is one of the previously introduced authentication types - `none`, `impossible`, `proof`, `signature` or `signatureOrProof`. The `txnVersion` property on the other hand is the newly introduce transction version, which specifies the version of a transaction that was supported by the protocol when the zkApp verification key was last changed. o1js exposes a function `TransactionVersion.current()` which returns the current transaction version of the protocol. For example, consider a zkApp that was deployed with the following permissions: ```ts this.account.permissions.set({ ...Permissions.default(), setVerificationKey: { auth: Permissions.impossible(), txnVersion: TransactionVersion.current() }, }); ``` After a protocol upgrade, the zkApp will still be able to upgrade its verification key by providing a valid signature. This allows the zkApp to upgrade its verification key to be compatible with the new protocol. Once the verification key is upgraded, the permission will revert back to `Impossible`. When it comes to upgrading your zkApp after a protocol upgrade, you can simply provide a valid signature to upgrade the verification key. Most of the time, you will not have to manually specify the transaction version because o1js exposes a set of predefined authentication types for `setVerificationKey` under the `Permission.VerificationKey` namespace. Mainly, this special set of permissions replaces normal permissions such as `Permission.proof` or `Permission.impossible` by less restrictive permissions - `impossibleDuringCurrentVersion` and `proofDuringCurrentVersion`. Here's a detailed overview of the new permissions: ```ts VerificationKey: { /* * Modification is impossible, as long as the network accepts the current {@link TransactionVersion}. * * After a hardfork that increments the transaction version, the permission is treated as `signature`. */ impossibleDuringCurrentVersion: () => VerificationKeyPermission, /* * Modification is always permitted */ none: () => VerificationKeyPermission, /* * Modification is permitted by zkapp proofs only; as long as the network accepts the current {@link TransactionVersion}. * * After a hardfork that increments the transaction version, the permission is treated as `signature`. */ proofDuringCurrentVersion: () => VerificationKeyPermission, /* * Modification is permitted by signatures only, using the private key of the zkapp account */ signature: () => VerificationKeyPermission, /* * Modification is permitted by zkapp proofs or signatures */ proofOrSignature: () => VerificationKeyPermission, }, ``` For more information on how this mechanism works, see the [Verification Key Permissions RFC](https://github.com/MinaProtocol/mina/blob/9577ad689a8e4d4f97e1d0fc3d26e20219f4abd1/rfcs/0051-verification-key-permissions.md). ### Example: Impossible to upgrade This simple example ensures that the smart contract is not upgradeable during the current transaction version of the protocol. After a verification key is deployed, it cannot be changed until the next backwards incompatible hardfork. ```ts class UpgradeabilityImpossible extends SmartContract { init() { super.init(); this.account.permissions.set({ ...Permissions.default(), setVerificationKey: Permissions.VerificationKey.impossibleDuringCurrentVersion(), }); } @method async updateVerificationKey(vk: VerificationKey) { this.account.verificationKey.set(vk); } } ``` The `UpgradeabilityImpossible` smart contract has only one method: `updateVerificationKey`. By invoking this method and providing a new verification key, the verification key on-chain is expected to change. But since `setVerificationKey` permission is specified to be `impossibleDuringCurrentVersion`, invoking that method fails - essentially making the smart contract not upgradeable. ```ts console.log('try upgrading vk'); tx = await Mina.transaction(feePayer, async () => { await zkapp.updateVerificationKey(newVerificationKey); }); await tx.prove(); await tx.sign([feePayerKey, zkappKey]).send(); ``` This transaction tries to replace the existing verification key with a new one, `newVerificationKey`. To can prevent that, set the permissions for a verification key change to `impossible` so the transaction fails. Using the `LocalBlockchain`, you get the following (expected) error: `Error: Transaction verification failed: Cannot update field 'verificationKey' because permission for this field is 'Impossible'` For the sake of security, it is important to note that you must also set the `setPermissions` permission to `impossible` to make the smart contract truly impossible to upgrade. This permission prevents a zkApp developer from changing the permission `setVerificationKey` to, for example, `signature` - which allows them to manipulate the verification key again. ### Example: Upgradeable with a proof There are situations where you might want the smart contract to be upgradeable. Modify the method `updateVerificationKey` to do some checks before you can update the verification key. For example, as the result of a vote or other conditions. For now, just check that you can provide an `x` that is greater than or equal to 5. If this check succeeds, then update the verification key. ```ts @method async updateVerificationKey(vk: VerificationKey, x: Field) { let y = Field(5); x.gte(y).assertTrue(); this.account.verificationKey.set(vk); } ``` You must update the permissions from `setVerificationKey`: `impossibleDuringCurrentVersion` to `proofDuringCurrentVersion` because you want to change the verification key only if a valid proof is provided. ```ts this.account.permissions.set({ ...Permissions.default(), setVerificationKey: Permissions.VerificationKey.proofDuringCurrentVersion(), }); ``` Now when you invoke the `updateVerificationKey` method, the transaction generates a valid smart contract execution proof to succeed and upgrade the verification key to a new one. ```ts console.log('try upgrading vk'); tx = await Mina.transaction(feePayer, async () => { await zkapp.updateVerificationKey(newVerificationKey); }); await tx.prove(); await tx.sign([feePayerKey, zkappKey]).send(); ``` ## Where to learn more Integration tests exercise the behavior of different permissions, including upgradeability. Check out the [voting integration test](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/voting/test.ts#L50) and the [DEX integration test](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/dex/upgradability.ts) examples. --- url: /zkapps/writing-a-zkapp/feature-overview/time-locked-accounts --- # Time-Locked Accounts Time-locking allows you to pay someone in MINA or other custom tokens subject to a vesting schedule. Tokens are initially locked and become available for withdrawal only after a certain time or gradually according to a specific schedule. By default, accounts are not time-locked. The zkApp feature that enables time-locking is the `timing` field that is present on every account: ```ts type Account = { // ... timing: { isTimed: Bool; initialMinimumBalance: UInt64; cliffTime: UInt32; cliffAmount: UInt64; vestingPeriod: UInt32; vestingIncrement: UInt64; }; }; ``` - The `isTimed` field indicates whether this account is time-locked. The default value of `isTimed` is `false`. - The other fields are parameters with default values that allow you to define a vesting schedule in a very flexible manner. This graph shows how each of the timing properties affect the vesting schedule:
    Timing parameters
    - The red cross on the left marks the point in time where the `timing` field is set. - `isTimed` switches from `false` to `true`. - The orange line shows how the amount of unlocked tokens increases over time until it finally reaches its maximum value and stays flat. - At this point, `isTimed` flips from `true` back to `false` because no tokens remain locked. As shown, the maximum amount of unlocked tokens is defined by the `initialMinimumBalance`. The property is called `initialMinimumBalance` because, even though the tokens show up in the balance, they can't be withdrawn. The account has a a non-zero _minimum balance_. Initially, that minimum balance is equal to the amount of tokens locked -- so, that amount is the "initial minimum balance". Over time, the minimum balance decreases until it hits zero, which is the condition that makes `isTimed` false again. The other timing-related properties are: - `cliffTime`: The initial time period during which all tokens are locked (should be from the current slot onwards). Note that 'time' is measured in Mina by 'slots', where 1 slot is 3min. - `cliffAmount`: The quantity of tokens to be unlocked when the cliff time has elapsed. If this amount is greater or equal the 'initial minimum balance', all tokens are unlocked after the cliff time elapses. - `vestingPeriod`: After the cliff time elapses, tokens can be set to unlock periodically at a fixed interval, by a fixed quantity. The vesting period is the length of that interval. - `vestingIncrement`: The quantity of tokens that are unlocked after each vesting period elapses. :::note Only one vesting schedule can be specified per account. The vesting schedule cannot be changed during the vesting period. Because of this restriction, the values of the timing fields cannot be changed when `isTimed` is set to `true`. After all tokens are unlocked and `isTimed` flips back to `false`, the account timing becomes mutable again. ::: ### Setting timing in o1js In o1js, `timing` is one of the account fields that can be updated by using an account update: ```ts accountUpdate.account.timing.set({ initialMinimumBalance, cliffTime, ...etc }); ``` When setting timing, all timing-related properties are required, except for `isTimed` which is automatically set by the protocol. ### Examples These examples show how to correctly implement several example use cases. #### Example 1: All tokens unlock after 1 week If you want all tokens to unlock after a certain time, then the only properties you need to consider are `initialMinimumBalance`, `cliffTime`, and `cliffAmount`. - Set `cliffAmount` equal to the `initialMinimumBalance` to ensure all tokens are unlocked when the cliff elapses. - Both `vestingPeriod` and `vestingIncrement` are unused, so set them to their default values, `1` and `0`: ```ts // example: 10 MINA to lock const tokensToLock = UInt64.from(10e9); // calculate 1 week in slots const cliffPeriod = UInt32.from((60 / 3) * 24 * 7); // fetch the current slot from the network const currentSlot = this.network.globalSlotSinceGenesis.get(); accountUpdate.account.timing.set({ initialMinimumBalance: tokensToLock, cliffTime: currentSlot + cliffPeriod, cliffAmount: tokensToLock, vestingPeriod: UInt32.from(1), // 0 is not allowed; default value is 1 vestingIncrement: UInt64.from(0), }); this.send({ to: accountUpdate, amount: tokensToLock }); ``` #### Example 2: Linear vesting over 1 year This example does not use a cliff, but vests a certain number of tokens linearly over 1 year. - Set the `vestingPeriod` to equivalent to 1 month defined in slots, so that new tokens are unlocked every month. - Set the `vestingIncrement` to the total amount divided by 12, so that the total amount is unlocked after 12 months. - Set both `cliffTime` and `cliffAmount` to 0. ```ts // example: 100000 MINA to lock const tokensToLock = UInt64.from(100000e9); // calculate 1 month in slots const vestingPeriod = UInt32.from(Math.round(((60 / 3) * 24 * 365) / 12)); // 1/12th of tokens unlocked every month const vestingIncrement = UInt64.from(Math.round(tokensToLock / 12)); accountUpdate.account.timing.set({ initialMinimumBalance: tokensToLock, cliffTime: UInt32.from(0), cliffAmount: UInt64.from(0), vestingPeriod, vestingIncrement, }); this.send({ to: accountUpdate, amount: tokensToLock }); ``` --- url: /zkapps/writing-a-zkapp/feature-overview/upgradability --- # ZkApp Upgradability The Mina protocol allows for the upgrading of verification keys on-chain. This article will demonstrate how to upgrade a ZkApp. ### First: A note on Permissions Permissions regarding ZkApp upgrades are thoroughly covered in: [Permissions](/zkapps/writing-a-zkapp/feature-overview/permissions#upgradeability-of-smart-contracts). The Permissions article explains the security assumptions in more detail, while this article explains how to perform an upgrade. ### Second: A note on Mina's execution model Upgradability on other blockchains may mean that a user thinks they're using one program, but since it has been upgraded, they are actually using another program. Two programs with the same function signature may have very different behavior and result in a bad or unsafe user experience. Mina's execution model is different. On Mina, users run their own program and upload the proof to the blockchain for verification only. So what it means to upgrade a ZkApp is only to change the verification key on-chain. Proofs generated with an older prover function will not be valid, and users will need to download the new prover function to generate a valid proof. ## Baseline ZkApp For example, let's use our standard `Add` example smart contract as the baseline ZkApp. ```ts export class Add extends SmartContract { @state(Field) num = State(); init() { super.init(); this.num.set(Field(1)); } @method async update() { const currentState = this.num.getAndRequireEquals(); const newState = currentState.add(2); this.num.set(newState); } } ``` This contract has a verification key of `"27729068461170601362912907281403262888852363473424470267835507636847418791713"` ## Upgraded ZkApp For our upgraded contract, let's use this updated example which adds by 4 instead of by 2. ```ts export class AddV2 extends SmartContract { @state(Field) num = State(); init() { super.init(); this.num.set(Field(1)); } @method async update() { const currentState = this.num.getAndRequireEquals(); const newState = currentState.add(4); this.num.set(newState); } } ``` This contract has a verification key of `"18150279532259194644722165513074833862035641840431153413486908511595437348455"` ## Upgrading a ZkApp Upgrading a ZkApp by signature can be done if you control the private key of a ZkApp. To do this, you need to sign a transaction that upgrades the ZkApp with that key. Imagine we have already deployed the `Add` contract, and we have the private key available as `zkAppKey` ```ts const verificationKey = (await AddV2.compile()).verificationKey; const contractAddress = zkAppKey.toPublicKey(); const upgradeTx = await Mina.transaction({ sender, fee }, async () => { const update = AccountUpdate.createSigned(contractAddress); update.account.verificationKey.set(verificationKey); } ); await upgradeTx.sign([senderKey, zkAppKey]).prove(); await upgradeTx.send(); ``` And just like that, when the transaction is applied to the blockchain, the verification key at the ZkApp address will be updated from `"27729068461170601362912907281403262888852363473424470267835507636847418791713"` to `"18150279532259194644722165513074833862035641840431153413486908511595437348455"`! ## Upgrades with More Surface Area In the previous example, we changed one small variable in the smart contract but kept the state and methods the same. However, there is no limit to what you can change via upgrade. Let's go through one more example where more things have changed. ```ts export class AddV3 extends SmartContract { @state(Field) num = State(); @state(Field) callCount = State(); init() { super.init(); this.num.set(Field(1)); } @method async add2() { this.add(2); } @method async add5() { this.add(5); } @method async add10() { this.add(10); } async add(n: number) { const callCount = this.callCount.getAndRequireEquals(); const currentState = this.num.getAndRequireEquals(); const newState = currentState.add(n); this.callCount.set(callCount.add(1)); this.num.set(newState); } } ``` This new contract is more of a departure from our original design. It has an extra piece of state that tracks how many times it has been called, and it allows for different operands to be used in the addition. It is a valid upgrade path to go from `AddV1` to `AddV3`. ```ts // The same pattern applies! const verificationKey = (await AddV3.compile()).verificationKey; const contractAddress = zkAppKey.toPublicKey(); const upgradeTx = await Mina.transaction({ sender, fee }, async () => { const update = AccountUpdate.createSigned(contractAddress); update.account.verificationKey.set(verificationKey); } ); await upgradeTx.sign([senderKey, zkAppKey]).prove(); await upgradeTx.send(); ``` ### State Variables **Warning**: If you change the order of the state in your upgraded contract, the upgrade will not match the states in the correct order Keep in mind that the state won't be reset when you upgrade. `init` will also not be called again. No raw values in the current state of your deployed contract will be edited by an upgrade other than the verification key. Make sure to avoid re-ordering state variables as in this unsafe example: ```ts export class AddV3Unsafe extends SmartContract { @state(Field) callCount = State(); // `num` used to be first! @state(Field) num = State(); init() { super.init(); this.num.set(Field(1)); } @method async add2() { this.add(2); } @method async add5() { this.add(5); } @method async add10() { this.add(10); } async add(n: number) { const callCount = this.callCount.getAndRequireEquals(); const currentState = this.num.getAndRequireEquals(); const newState = currentState.add(n); this.callCount.set(callCount.add(1)); this.num.set(newState); } } ``` --- url: /zkapps/writing-a-zkapp --- # zkApps Overview
    Terminal screenshot of zkApp CLI command line interface.

    :::info To protect end users and ensure your zkApps are secure, consider the information at [Security and zkApps](/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps) while architecting your solution and consider a third-party security audit before deploying to Mina mainnet. ::: :::info The maximum number of zkApp transactions per block is currently capped at **24**. This restriction will be gradually lifted after the Mainnet upgrade. ::: ### What are zkApps? zkApps (zero knowledge apps) are Mina Protocol smart contracts powered by zero knowledge proofs, specifically using zk-SNARKs. zkApps use an **off-chain execution** and mostly **off-chain state** model. This architecture allows for private computation and state that can be either private or public. zkApps can perform arbitrarily-complex computations off-chain while incurring only a flat fee to send the resulting zero knowledge proof to the chain for verification of this computation. This cost saving benefit is in contrast to other blockchains that run computations on-chain and use a variable gas-fee based model.
    Mina zkApp zero knowledge app architecture diagram

    To learn more, see [How zkApps Work](./writing-a-zkapp/introduction-to-zkapps/how-zkapps-work). ### TypeScript zkApps are written in [TypeScript](https://www.typescriptlang.org/). TypeScript provides an easy, familiar language (JavaScript), but with type safety, making it easy to get started writing zkApps. If you're new to using TypeScript, check out this helpful 12-min introductory video [TypeScript - The Basics](https://www.youtube.com/watch?v=ahCwqrYpIuM). ### Learn more To learn more about developing zkApps, see [how zkApps work](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-zkapps-work), [how to write a zkApp](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp) and [zkApps for Ethereum Developers](/zkapps/advanced/zkapps-for-ethereum-developers). Try the [zkApps tutorials](/zkapps/tutorials/hello-world) to learn by doing! ### Get help and join the community Join the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel on Mina Protocol Discord. --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/getting-started-zkapps --- # zkApps Getting Started You can start writing zkApps with just a few steps. The focus of this Getting Started Guide is a high-level workflow to build and deploy quickly. ## High-Level Workflow 1. [Install or update the zkApp CLI](#1-install-or-update-the-zkapp-cli) 1. [Create a project](#2-create-a-project) 1. [Add testing code](#3-add-testing-code) 1. [Add functionality](#4-add-functionality) 1. [Create an integration test](#5-create-integration-test) 1. [Test locally](#6-test-locally) 1. [Test with Lightnet](#7-test-with-lightnet) 1. [Test with a live network](#8-test-with-a-live-network) ### 1. Install or update the zkApp CLI ```sh npm install -g zkapp-cli ``` The zkApp CLI provides project scaffolding, including dependencies such as [o1js](/zkapps/o1js), a test framework, code auto-formatting, linting, and more. See [zkApp CLI Installation](/zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli). ### 2. Create a project ```sh $ zk project ``` [o1js](/zkapps/o1js) is automatically installed when you generate a project using the zkApp CLI. A zkApp consists of a smart contract and a UI to interact with it. - To proceed without an accompanying UI project, select `none` when prompted. See [Option B: Start your own project](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp#option-b-start-your-own-project). - To create a UI, select a framework and follow the prompts. See [How to Write a zkApp UI](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp-ui). ### 3. Add testing code When you use the zkApp CLI to create a project, tests and examples are included. 1. See the `import` statements in the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts#L1-L2) example file. 1. A simulated `LocalBlockchain` instance you can interact with is included in the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts#L27-L28) example file. 1. In o1js, an array of 10 test accounts to pay fees and sign transactions are provided for the simulated `LocalBlockchain` instance. These can be accessed with `Local.testAccounts` as shown in the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts#L29-L31) example file. The example uses the public/private key pairs of two of these accounts. The example uses these names, but the names can be anything: - `deployerAccount` deploys the smart contract - `senderAccount` pays transaction fees 1. Deploy the smart contract to the simulated `LocalBlockchain` instance that simulates a network for testing purposes. See the `localDeploy` function in the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts#L38-L46) example file. ### 4. Add functionality Add the logic for your smart contract. 1. Start experimenting with iterative development to build and test one method at a time. Add functionality to the smart contract by implementing a `@method`. See `@method async update()` in the [Add.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.ts#L20-L24) example file. 1. Build the smart contract: ```sh npm run build ``` 1. Invoke the `@method` you added or use new functionality in the test file. See the transaction code that invokes the `update()` method in the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts#L57-L66) file. - If it works as expected with no errors, add more functionality. - If there are errors, look through the stack traces to find the source of the errors and update the contract to resolve them. ### 5. Create integration test - Create a Node.js script to run the smart contract and test it's functionality, similar to step [3. Add testing code](#3-add-testing-code). For an example, see the Node.js script that runs the Tic Tac Toe smart contract in the [run.ts](https://github.com/o1-labs/zkapp-cli/blob/main/examples/tictactoe/ts/src/run.ts) file. ### 6. Test locally - [Test zkApps locally](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally) with a simulated local blockchain. ### 7. Test with Lightnet - Use [Lightnet](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet) to test your zkApp with an accurate representation of Mina blockchain. 1. Start Lightnet: ```sh zk lightnet start ``` The default settings start a single node that successfully serves the majority of testing requirements. 1. Verify the status of the local blockchain: ```sh zk lightnet status ``` 1. Communicate with the Mina Accounts-Manager service to fetch account details. - Mina Accounts-Manager is deployed to http://localhost:8181/ - Use HTTP endpoints to acquire, release, list, lock, and unlock accounts 1. Configure your zkApp for Lightnet blockchain. Use the endpoints provided by the `zk lightnet status` command. - Deploy name - Set the Mina GraphQL API URL to deploy to: http://localhost:8080/graphql - Set transaction fee to use when deploying (in MINA): 0.1 1. Deploy your zkApp to Lightnet: ```sh zk deploy ``` ### 8. Test with a live network {#8-test-with-a-live-network} To deploy the smart contract to the Testnet, run the `zk` commands from the directory that contains your smart contract. 1. Configure your zkApp. ```sh zk config ``` Follow the prompts to specify a deploy alias name (can be anything), URL to deploy to, fee (in MINA) to be used when sending your deploy transaction, and the fee payer account. For the Devnet, use: - Deploy alias name: `devnet` - Mina GraphQL API URL: `https://api.minascan.io/node/devnet/v1/graphql` - Transaction fee to use when deploying: `0.1` - Account to pay transaction fees: Create a new fee payer pair See [Add a deploy alias to config.json](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-deploy-a-zkapp#add-a-deploy-alias-to-configjson). For other Testnets, use the details provided. 1. Choose a fee payer alias. A fee payer account is a developer account that is funded and can always pay fees immediately. When you configure a zkApp, you can choose to use a stored account or create a new fee payer account. - When prompted to choose an account to pay transaction fees, select to use a different account: ```sh Use a different account (select to see options) ``` If this is the first time you are running the `zk config` command, you see these options: ```text > Recover fee payer account from an existing base58 private key Create a new fee payer key pair ``` The option to choose another account is shown only if you have a cached fee payer account. - Next, select **Create a new fee payer key pair**: ```sh Create a new fee payer key pair NOTE: the private key will be stored in plain text on this computer. ``` - When prompted, give an alias to your new fee payer key pair. 1. Fund your fee payer account. Follow the prompts to request tMina. 1. Deploy to the Testnet. ```sh zk deploy ``` Follow the prompts. See [How to deploy a zkApp](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-deploy-a-zkapp). 1. Create a script to interact with a live network. See the example files: - https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/interact.ts - https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/hello-world/run-live.ts 1. Run your script. For example: ```sh node build/src/interact.js ``` 1. Keep building and experimenting! After you add features to your contract, repeat [8. Test with a live network](#8-test-with-a-live-network) to test with a live network. ## Learn more To learn more about developing zkApps, see [how zkApps work](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-zkapps-work), [how to write a zkApp](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp), and [zkApps for Ethereum Developers](/zkapps/advanced/zkapps-for-ethereum-developers). Try the [zkApp Developer Tutorials](/zkapps/tutorials) for use cases that guide you to achieve a defined goal. ## Get help and join the community Join the [#zkapps-developers](https://discord.com/channels/484437221055922177/915745847692636181) channel on Mina Protocol Discord. --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-deploy-a-zkapp --- # How to Deploy a zkApp Before deploying, you must first define a few settings, such as which network you are deploying your zkApp to. ## Add a deploy alias to config.json First, change into the directory that contains your smart contract and then run the following command: ```sh $ zk config ``` When prompted, specify: - The name (can be anything) - The target network kind (`Testnet`, `Mainnet` or enter the custom network kind id) to deploy your zkApp to - The URL to send the deploy transaction to - Transaction fee (in MINA) to use when deploying - The fee payer account to pay transaction fees from For more details, see [deploy alias](/zkapps/tutorials/deploying-to-a-network#deploy-alias) section in corresponding tutorial. :::tip If your project contains multiple smart contracts (for example, `Foo` and `Bar`) that you intend to deploy to the same network, the best practice is to follow the naming convention such as `devnet-foo` and `devnet-bar` when naming your deploy aliases. You can change these alias names at any time by manually editing the `config.json` file. ::: You see the following output: ```sh $ zk config Add a new network: ✔ Create a name (can be anything): · devnet ✔ Choose the target network: · Testnet ✔ Set the Mina GraphQL API URL to deploy to: · https://api.minascan.io/node/devnet/v1/graphql ✔ Set transaction fee to use when deploying (in MINA): · 0.1 ✔ Choose an account to pay transaction fees: · Use stored account MyFeePayer (public key: B62...) ✔ Use stored fee payer MyFeePayer (public key: B62...) ✔ Create zkApp key pair at keys/devnet.json ✔ Add deploy alias to config.json Success! Next steps: - If this is the testnet, request tMINA at: https://faucet.minaprotocol.com/?address= - To deploy zkApp, run: `zk deploy devnet` ``` ## Request funds from the Faucet To deploy your zkApp, your fee payer account must have funds to pay for transaction fees. To get funds on the Devnet, use the URL that was shown in the zkApp CLI output: - Visit `https://faucet.minaprotocol.com/?address=` - Choose the corresponding network you're going to deploy your zkApp to (`Devnet` in this case) - And click the **Request** button Before proceeding to the next step, wait a few minutes for the next block to include your transaction, so that tMINA becomes available for the fee payer account. ## Deploy your smart contract To deploy your smart contract to the network, run the following command: ```sh $ zk deploy devnet ``` Among other activities, when running the deploy command, zkApp CLI computes the verification key for your zkApp. Computing verification key can take 10-30 seconds, so please be patient. The zkApp CLI shows the details of the process, such as the network name, the URL, and the smart contract to deploy. Finally, enter `yes` or `y` when prompted to confirm and send the deploy transaction. You see the following output: ```sh $ zk deploy devnet ✔ Build project ✔ Generate build.json ✔ Choose smart contract Only one smart contract exists in the project: Add Your config.json was updated to always use this smart contract when deploying to this network. ✔ Generate verification key (takes 10-30 sec) ✔ Build transaction ✔ Confirm to send transaction |-----------------|-------------------------------------------------| | Deploy alias | devnet | |-----------------|-------------------------------------------------| | Network kind | testnet | |-----------------|-------------------------------------------------| | URL | https://api.minascan.io/node/devnet/v1/graphql | |-----------------|-------------------------------------------------| | Fee payer | Alias : MyFeePayer | | | Account : B62... | |-----------------|-------------------------------------------------| | zkApp | Smart contract: Add | | | Account : B62... | |-----------------|-------------------------------------------------| | Transaction fee | 0.1 Mina | |-----------------|-------------------------------------------------| Are you sure you want to send (yes/no)? · y ✔ Send to network Success! Deploy transaction sent. Next step: Your smart contract will be live (or updated) at B62... as soon as the transaction is included in a block: https://minascan.io/devnet/tx/?type=zk-tx ``` After a few minutes, the transaction is included in the next block. To see the zkApp transaction and navigate to accounts involved you can follow the transaction link provided to you in zkApp CLI output. Or use the [Minascan](https://minascan.io) explorer to search for the account with deployed zkApp. ## Next Steps Now that you've learned how to deploy a smart contract, you can learn [how to write the UI for your zkApp](how-to-write-a-zkapp-ui). --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp-ui --- # How to Write a zkApp UI A zkApp consists of a smart contract and a UI to interact with it. To allow users to interact with your smart contract in a web browser, you typically want to build a website UI. You can write the UI with any framework like React, Vue, or Svelte, or with plain HTML and JavaScript. ## Using one of the provided UI framework scaffolds When you create a project using the zkApp CLI, you can choose a supported UI framework to be scaffolded as a part of your zkApp project. For example, Next.js, Sveltkit, or Nuxt.js. ## Adding your smart contract as a dependency of the UI You can use one of the provided scaffolding options and add your smart contract to an existing frontend, a different UI framework, or a plain HTML and JavaScript website. ### Specify the smart contracts to import The `index.ts` file is the entry point of your project that imports all smart contract classes you want access to and exports them to your smart contract. This pattern allows you to specify which smart contracts are available to import when consuming your project from npm within your UI. In `index.ts`: ```ts export { YourSmartContract }; ``` ### Local development To test iteratively and use your smart contract within your UI project during local development, you can use [npm link](https://docs.npmjs.com/cli/v8/commands/npm-link). This local use allows for rapid development without having to publish your project to npm. 1. To change into your smart contract project directory: ```sh cd ``` 1. To create the symlinks: ```sh npm link ``` where `your-package-name` is the `name` property used in your _smart contract's_ `package.json`. For example, the `name` property in `package.json` for the `sudoku` example project that you created in [How to Write a zkApp](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp) is `sudoku`. To create the symlinks for `sudoku`: ```sh npm link sudoku ``` 1. To import the smart contracts into your UI project, add the import statement to the `index.ts` file: ```ts import { YourSmartContract } from 'your-package-name';` ``` For example, to import the `sudoku` example project, your `index.ts` file is: ```ts import { SudokuZkApp } from './sudoku.js'; export { SudokuZkApp }; ``` 1. After you make changes to your project files, be sure to build your project so that the changes are reflected in the smart contract consumed by your UI project: ```sh npm run build ``` ### Publish to npm for production 1. Create an npm account. If you don't already have an account, go to npm [Sign Up](https://www.npmjs.com/signup). 1. Login to npm: ```sh npm login ``` When prompted, enter your username, password, and email address. 1. To publish your package from the root of your smart contract project directory: ```sh npm publish ``` Package names must be unique. An error occurs if the package name already exists. To use a different package name, change the `name` property in the `package.json` file. To check existing package names on npm, use the [npm search](https://docs.npmjs.com/cli/v7/commands/npm-search) command. To avoid naming collisions, npm allows you to publish scoped packages: `@your-username/your-package-name`. See [Introduction to packages and modules](https://docs.npmjs.com/packages-and-modules/introduction-to-packages-and-modules) in the npm reference docs. ### Consuming your smart contract in your UI After you have published your smart contract to npm, you can add it to any UI framework by importing the package. 1. Install your smart contract package from the root of your UI project directory: ```sh npm install your-package-name ``` If you published a scoped npm package: ```sh npm install @your-username/your-project-name ``` 1. Import your smart contract package into the UI using: ```ts import { YourSmartContract } from ‘your-package-name’; ``` where `YourSmartContract` is the named export that you chose in your smart contract. :::tip For a more performant UI, render your UI before importing and loading your smart contract so the o1js wasm workers can perform initialization without blocking the UI. For example, if your UI is built using React, instead of a top level import, load the smart contract in a `useEffect` to give the UI time to render its components before loading o1js. ::: ### Loading your contract with React ```ts useEffect(() => { (async () => { const { YourSmartContract } = await import('your-package-name'); })(); }, []); ``` ### Loading your contract with Svelte ```ts onMount(async () => { const { YourSmartContract } = await import('your-package-name'); }); ``` ### Loading your contract with Vue ```ts onMounted(async () => { const { YourSmartContract } = await import('your-package-name'); }); ``` ### Enabling COOP and COEP headers To load o1js code in your UI, you must set the [COOP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy) and [COEP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) headers. These headers enable o1js to use [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer) that o1js relies on to enable important WebAssembly (Wasm) features. - Set `Cross-Origin-Opener-Policy` to `same-origin`. - Set `Cross-Origin-Embedder-Policy` to `require-corp`. You can enable these headers in a number of different ways. If you deploy your UI to a host such as [Vercel](https://vercel.com/) or [Cloudflare Pages](https://pages.cloudflare.com/), you can set these headers in a custom configuration file. Otherwise, set these headers in the server framework of your choice (for example, Express for JavaScript). ### Set headers for Vercel If your app will be hosted on Vercel, set the headers in [`vercel.json`](https://vercel.com/docs/project-configuration). ```json { "headers": [ { "source": "/(.*)", "headers": [ { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }, { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" } ] } ] } ``` ### Set headers for Cloudflare Pages To host your app on Cloudflare Pages, set the headers in a [`_headers` file](https://developers.cloudflare.com/pages/platform/headers/). ``` /* Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp ``` ### Connecting your zkApp with a user's wallet The Mina community has created a variety of different wallets. Only the [Auro Wallet for Chrome](https://www.aurowallet.com) supports interactions with zkApps. To interact with your zkApp, users of your zkApp must have the Auro Wallet installed: - `window.mina` is automatically available in the user's browser environment. - Your zkApp uses this object to interact with the wallet. 1. Install the Chrome extension for [Auro Wallet](https://chrome.google.com/webstore/detail/auro-walletmina-protocol/cnmamaachppnkjgnildpdmkaakejnhae). 2. Get accounts. To fetch a user's list of Mina accounts, use the `requestAccounts()` method: ```ts let accounts; try { // Accounts is an array of string Mina addresses. accounts = await window.mina.requestAccounts(); // Show first 6 and last 4 characters of user's Mina account. const display = `${accounts[0].slice(0, 6)}...${accounts[0].slice(-4)}`; } catch (err) { // If the user has a wallet installed but has not created an account, an // exception will be thrown. Consider showing "not connected" in your UI. console.log(err.message); } ``` It is useful to indicate if the user's wallet is successfully connected to your zkApp: 3. Send a transaction. After your user interacts with your zkApp, you can sign and send the transaction using `sendTransaction()`. You receive a transaction ID as soon as the Mina network has received the proposed transaction. However, this does not guarantee that the transaction is accepted in the network into an upcoming block. ```ts try { // This is the public key of the deployed zkapp you want to interact with. const zkAppAddress = 'B62qq8sm7JdsED6VuDKNWKLAi1Tvz1jrnffuud5gXMq3mgtd'; const tx = await Mina.transaction(async () => { const YourSmartContractInstance = new YourSmartContract(zkAppAddress); await YourSmartContractInstance.foo(); }); await tx.prove(); const { hash } = await window.mina.sendTransaction({ transaction: tx.toJSON(), feePayer: { fee: '', memo: 'zk', }, }); console.log(hash); } catch (err) { // You may want to show the error message in your UI to the user if the transaction fails. console.log(err.message); } ``` The convention is to show the error message in your UI. :::info For details about the Mina Provider API, see the [Mina Provider](https://docs.aurowallet.com/general/reference/api-reference/mina-provider-api) API Reference docs. ::: ### Display assertion exceptions in your UI If an assertion exception occurs while a user interacts with any of your smart contract methods, you want to capture this error and display a helpful message for the user in your UI. 1. Use a try-catch statement to catch exceptions when a user invokes a method on your smart contract. 2. Use a switch-case statement to identify which exception was thrown. Add a matching case for each unique assertion within your method. To assist with this error handling, consider setting custom error messages for your assertions while writing the smart contract. For example: `INSUFFICIENT_BALANCE`. 3. Display a helpful error message for the user within your UI, like: ```ts try { YourSmartContract.yourMethod(); } catch (err) { let uiErrorMessage; switch (err.message) { // A custom error thrown within YourSmartContract.yourMethod() // when there is an insufficient balance. case 'INSUFFICIENT_BALANCE': // Set a helpful message to show the user in the UI. uiErrorMessage = 'Your account has an insufficient balance for this transaction'; break; // etc } } ``` --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp --- # How to Write a zkApp A zkApp consists of a smart contract and a UI to interact with it. Write your smart contract using the [zkApp CLI](https://www.npmjs.com/package/zkapp-cli/). First, install the zkApp CLI: ```sh npm install -g zkapp-cli ``` See [zkApp CLI Installation](/zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli). ## Start a project Now that you have the zkApp CLI installed, you can start with an example or create your own project. Example projects do not create an accompanying UI. ### Option A: Start with an example (recommended) Examples are based on the standard project structure and provide additional files in the `/src` directory. 1. Create the example project: ```sh zk example ``` The command prompts you to select an example project: ```text ? Choose an example … > sudoku tictactoe ``` Select the `sudoku` example project. The created project includes the example files (the smart contract) and the example test files in the project's `src` directory. 1. View the files that were created: - Change to the `sudoku` directory. - Run the `ls` command Or open the directory in a code editor, such as VS Code. 1. This example zkApp includes the `sudoku.test.ts` test file. To run tests and see the tests pass: ```sh npm run test ``` To rerun tests automatically after you save changes to your code, you can run the tests in watch mode: ```sh npm run testw ``` 1. Now that you have confirmed that tests run correctly, you can compile your TypeScript into JavaScript in the project `/build` directory. To build the example: ```sh npm run build ``` - The `npm run build` command builds the TypeScript files in `sudoku/src` that contain the code for the smart contract. - This build command compiles the TypeScript code into JavaScript in the `sudoku/build` directory. 1. Configure your zkApp: ```sh zk config ``` The command prompts guide you to add a deploy alias to your project `config.json` file. 1. Define a name for the deploy alias. For this example, use: ```text devnet ``` The deploy alias name does not have to match the network name. 1. Choose the target network kind: ```text Testnet ``` 1. Set the Mina GraphQL API URL to deploy to: ```text https://api.minascan.io/node/devnet/v1/graphql ``` 1. Set the transaction fee to use when deploying: ```text 0.1 ``` 1. When prompted to choose an account to pay transaction fees, select: ```text Use a different account (select to see options) ``` If this is the first time you are running the `zk config` command, you see these options: ```text > Recover fee payer account from an existing base58 private key Create a new fee payer key pair ``` The option to choose another account is shown only if you have a cached fee payer account. 1. Select to create a new fee payer key pair: ```sh Create a new fee payer key pair NOTE: the private key will be stored in plain text on this computer. ``` A fee payer account is a developer account that can always pay fees immediately for local testing. Do not use an account that holds a substantial amount of MINA. 1. When prompted to create an alias for this account, give an alias to your new fee payer key pair: ```text testnet-fees ``` Your key pairs and deploy alias are created. 1. Fund the fee payer account. After you fund the fee payer account, you can use to to pay fees across multiple zkApps. Follow the prompts to request tMINA to fund your fee payer account. For this example, your MINA address is populated on the Testnet Faucet. tMINA arrives at your address when the next block is produced (~3 minutes). 1. Deploy to Testnet: ```sh zk deploy ``` Follow the prompts to select the `devnet` deploy alias and confirm that you want to send the transaction. Your smart contract transaction is pending until the transaction is included in a block. 1. To view your transaction, click the block explorer link. For example: `https://minascan.io/devnet/tx/?type=zk-tx` For details, see [How to Deploy a zkApp](how-to-deploy-a-zkapp). ### Option B: Start your own project Instead of using a provided example, you can follow these steps to create your own project. 1. Create your own project: ```sh zk project ``` The created project includes the smart contract files in the project's `src/` directory. 1. Select an accompanying UI framework, if any: ```text ? Create an accompanying UI project too? … > next svelte nuxt empty none ``` For your selected UI framework, follow the prompts. See [How to Write a zkApp UI](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp-ui). To see the files that were created, change to the project (whatever you called ``) directory and run the `ls` command or open the directory in a code editor, such as VS Code. 1. When you use the zkApp CLI to create a project, the default `Add` smart contract is included along with the `Add.test.ts` test files. ```sh npm run test ``` To rerun tests automatically after you save changes to your code, you can run the tests in watch mode: ```sh npm run testw ``` 1. To compile your TypeScript into JavaScript in the project `/build` directory, build the example: ```sh npm run build ``` The `npm run build` command builds the TypeScript files in `yourproject/src` that contain the code for the smart contract. This build command compiles the TypeScript code into JavaScript in the `yourproject/build` directory. 1. Configure your zkApp: ```sh zk config ``` The command prompts guide you to add a deploy alias to your project `config.json` file. 1. To configure your deploy alias, follow the prompts: - Create a (deploy alias) name: _yourprojecttestnet_ - Choose the target network: `Testnet` - Set the Mina GraphQL API URL: `https://api.minascan.io/node/devnet/v1/graphql` - Set transaction fee to use when deploying (in MINA): `0.1` - Choose an account to pay transaction fees: - `Create a new fee payer key pair` - Create an alias for this account: _yourdeployalias_ Your key pair and deploy alias are created. 1. Fund your fee payer account. Follow the prompts to request tMina. 1. Deploy to Testnet: ```sh zk deploy yourprojecttestnet ``` Follow the prompts. To learn more about deploying, see [How to Deploy a zkApp](how-to-deploy-a-zkapp). ## Writing your smart contract zkApps are written in TypeScript using o1js. o1js is a TypeScript library for writing smart contracts based on zero knowledge proofs for the Mina Protocol. o1js is automatically included when you create a project using the zkApp CLI. To get started writing zkApps, begin with these o1js docs: - [Basic concepts](/zkapps/o1js/basic-concepts) - [Interacting with Mina](/zkapps/writing-a-zkapp/introduction-to-zkapps/interact-with-mina) A basic smart contract example is generated when you created a zk project. The high-level smart contract code workflow is: 1. Import `o1js`. See the `import` statement in the [Add.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.ts#L1) file. 1. Extend the `SmartContract` class. See the exported `class` in the [Add.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.ts#L12) file. For guided steps to create your first zkApp, start with [Tutorial 1: Hello World](/zkapps/tutorials/hello-world). For comprehensive details about the o1js API, see the [o1js reference](/zkapps/o1js-reference). ## Next Steps Now that you've learned how to write and operate a basic smart contract, you can learn about [Testing zkApps Locally](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally). --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/how-zkapps-work --- # How zkApps Work zkApps run in the latest versions of [Chrome](https://www.google.com/chrome/index.html), [Firefox](https://www.mozilla.org/en-US/firefox/new/), [Edge](https://microsoft.com/edge), and [Brave](https://brave.com/) web browsers. zkApps are written in TypeScript using the zkApp CLI. A zkApp consists of two parts: - A smart contract - A user interface (UI) for users to interact with the zkApp
    Diagram showing two parts of a zkApp
    - The term _smart contract_ refers to the code written with o1js. - The term _zkApp_ refers to the UI + the smart contract. ## Zero knowledge-based smart contracts zkApps are based on zero knowledge proofs (zk-SNARKs). As a zkApp developer, you use the zkApp CLI to scaffold and deploy your project. Provable code is written using o1js and generates a prover function and a corresponding verifier function that are derived during the build process. The prover function is the function that executes a smart contract's custom logic and runs in an end user's web browser as part of the zkApp. The prover function generates a proof of the executed code. When interacting with a zkApp UI, users enter any data (for example, buy ABC for y price) that is required as input to the prover function, which then generates a zero knowledge proof.
    Diagram showing private and public inputs to prover function to create zero knowledge proof
    Private and public inputs represent data that must be provided to the prover function when it runs in the end user's web browser. Private inputs are not required again. Because public inputs must also be provided to the verifier function when it runs on the Mina network, public inputs are not used for data that you want to remain private. The verifier function validates whether a zero knowledge proof successfully passes all the constraints defined in the prover function. The verifier function _always_ runs quickly and efficiently, irrespective of the prover function's complexity. Within the Mina network, Mina acts as the verifier and runs the verifier function.
    Diagram showing verifier function validation
    ## Prover Function and Verification Key After you write a smart contract, build it by running the `npm run build` command. The build process compiles the TypeScript code into JavaScript and outputs the `smart_contract.js` file. From this file, you can: - Run a prover function to run your smart contract - Generate a verification key to deploy your smart contract While the prover function runs in an end user's web browser, the verification key lives on-chain for a given zkApp account and is used by the Mina network to verify that a zero knowledge proof has met all constraints defined in the prover. A verification key is required to create a zkApp account. You can also use the verifier function or verification key to verify proofs off-chain. ## Deploy a smart contract zkApp developers use the zkApp CLI to deploy smart contracts to the Mina network. The deployment process sends a transaction that contains the verification key that is an output of the verifier function to an address on the Mina blockchain.
    Diagram showing deployment of a Mina zkApp smart contract
    When a Mina address contains a verification key, it acts as a zkApp account. A regular Mina account can receive any transactions. You can specify [permissions](/zkapps/writing-a-zkapp/feature-overview/permissions) so a zkApp account can successfully receive only the transactions that satisfy the verifier function. The Mina network rejects any transactions that do not pass the verifier function. When you deploy a zkApp to a new Mina address, the Mina Protocol charges a 1 MINA fee for account creation. This fee is unrelated to zkApps and helps to prevent Sybil or denial of service attacks. ## Deploy a zkApp UI A zkApp consists of a smart contract and a UI to interact with it. To enable users to interact with your smart contract in a web browser, you build a website UI and then deploy this interactive UI as a static website. Choosing a host that offers a global content delivery network (CDN) ensures the best experience for all users. Diagram of a zkApp that includes JavaScript and the UI Your website must contain the JavaScript `smart_contract.js` file that you generated with the `npm run build` command. To learn more, see [How to Write a zkApp](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp). ## How users interact with a zkApp To use a zkApp, end users must [Install a Wallet](/using-mina/install-a-wallet) that supports interactions with zkApps. After a zkApp is deployed to a host (for example, mycoolzkapp.com), end users can interact with it: 1. The user visits mycoolzkapp.com. 1. The user interacts with the zkApp and enters the required data. For example, if this were an automated market maker, the user might specify to buy x amount of ABC at y price. 1. The prover function in the zkApp generates a zero knowledge proof locally using the data entered by the user. This data can be either: - Private, the data is never seen by the blockchain. - Public, the data is stored on-chain or off-chain, depending on what the zkApp specified as required for a given use case. A list of state updates (called account updates) to be created by the transaction is generated. The account updates are associated with this proof. 1. The user selects **Submit to chain** in the zkApp UI. - The user confirms the transaction on their wallet. - The wallet signs the transaction containing the proof and the associated description of state to update. - The wallet sends the transaction to the Mina network. 1. The Mina network receives this transaction and verifies that the proof successfully passes the verifier method listed on the zkApp account. If the network accepts this transaction, this proof and the requested state changes are valid and are allowed to update the zkApp state. The end user's privacy is maintained because their interaction occurs locally in a web browser using JavaScript on the client. ### How state is updated on-chain The zkApp account gets updated on-chain. When the prover function runs in a web browser, the smart contract outputs a proof and some associated data called "account updates" that are sent to a zkApp address as part of the transaction. The account updates are a JSON plain text description that describes how to update the state on a zkApp account. The integrity of these account updates is ensured by passing a hash of the account updates as a public input to the smart contract. The account updates must be present and unmodified for the verification function to pass successfully when it runs on Mina. In this way, the Mina network can confirm the integrity of both the proof and the associated account updates that describe how to update the zkApp account state. ### zkApp state - On-chain state describes state that lives on the Mina blockchain. - Off-chain state describes state stored anywhere else. ### On-chain state Each zkApp account provides 8 fields of 32 bytes each of arbitrary storage. You may store anything here as long as it fits in the size provided. If you anticipate your state to be larger, or if the state accumulates per user with your zkApp, then use off-chain state instead. ### Off-chain state For larger data, you might want to consider storing the root of a [Merkle tree](/zkapps/o1js/merkle-tree) or a similar data structure within your zkApp's on-chain storage that references self-hosted off-chain state stored elsewhere. Mina doesn't offer an out-of-the-box solution for off-chain storage. When the zkApp runs in a user's web browser, it can insert state to an external storage, such as IPFS. When the transaction is sent to the Mina network, if it accepts this zkApp transaction then proof and state are known to be valid so the updates are allowed, then the zkApp transaction can update the root of the Merkle tree that is stored on chain. ### Keep going See [zkApps Getting Started](/zkapps/writing-a-zkapp/introduction-to-zkapps/getting-started-zkapps). --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli --- # zkApp CLI Installation Install and use the zkApp CLI to scaffold, write, test, and deploy zkApps (zero knowledge apps) for Mina Protocol using recommended best practices. :::tip To build zero knowledge apps that use [o1js](/zkapps/o1js), you only need to install the zkApp CLI. o1js is automatically included when you create a project using the zkApp CLI. In the root of your project directory, use `zk system` to show the system information with installed versions of zkApp CLI and o1js. ::: ### Dependencies - NodeJS v18 and later - NPM v10 and later - git v2 and later If you have a later version of a dependency, install the required version using the package manager for your system: - MacOs [Homebrew](https://brew.sh/) - Windows [Chocolatey](https://chocolatey.org/) - Linux (apt, yum, and others) As recommended by the Node.js project, you might need to install a recent Node.js version using NodeSource binary distributions: [Debian](https://github.com/nodesource/distributions#debinstall), [rpm](https://github.com/nodesource/distributions#rpminstall). To verify your installed versions of dependencies, use `node -v`, `npm -v`, and `git -v`. ## Usage To see usage information for all of the zkApp CLI commands: ```sh $ zk --help ``` ## Install the zkApp CLI To install the latest version: ```sh npm install -g zkapp-cli ``` To confirm successful installation: ```sh $ zk --version ``` ## Update the zkApp CLI You are prompted to install the new version if you are running an earlier zkApp CLI minor version. For example, if you are running version 0.12.1, but the current version is 0.13.0, you are prompted to update. You are not prompted to update if you are using an earlier patch version. For example, you are not notified to upgrade when you are running 0.12.0, and the current version is 0.13.1. To update to the latest version of the zkApp CLI: ```sh npm update -g zkapp-cli ``` --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/interact-with-mina --- # Interacting With Mina Now that you know about writing zkApp methods, it's time to learn how users can call these methods. ## Transactions Recall that smart contracts execute off-chain. The result of an off-chain execution is a _transaction_ that can be sent to the Mina network to apply the changes made by the smart contract. In this section, you learn what a transaction looks like and how to create one. ## Account updates The fundamental data structure that Mina transactions are built from is called an _account update_. An account update always contains updates to one specific on-chain account. For example, if you transfer MINA from one account to another, the balance on two accounts is updated – the sender and the receiver. Therefore, sending MINA requires two account updates. Account updates are a flexible and powerful data structure that can express all kinds of updates, events, and preconditions you use to develop smart contracts. ## Transaction structure A _transaction_ is a JSON object of the form: ```ts { feePayer, accountUpdates: [...], memo } ``` - `feePayer` is a special account update with a slightly simpler structure. - In particular, it contains a `fee` field, which must be used to specify the transaction fee. - `accountUpdates` is a list of normal account updates that make up the bulk of the transaction. - `memo` is an encoded string that can be used to attach an arbitrary short message. You create transactions in o1js by calling `Mina.transaction(...)`, which takes the sender (a public key) and a callback that contains your transaction logic: ```ts const sender = PublicKey.fromBase58('B62..'); // the user address const zkapp = new MyContract(address); // MyContract is a SmartContract const tx = await Mina.transaction(sender, async () => { await zkapp.myMethod(someArgument); }); ``` In this example, the transaction calls a single `SmartContract` method called `myMethod`. You can inspect the transaction by printing it to the console, in JSON format: ```ts console.log(tx.toJSON()); ``` This command outputs a massive JSON object with many fields, most of which are set to their default value. Inspecting transactions becomes easier if you print them in a condensed format, as follows: ```ts console.log(tx.toPretty()); ``` Depending on the logic of `myMethod()`, the output is something like: ```ts [ { publicKey: '..VeLh', fee: '0', nonce: '0', authorization: '..EzRQ', }, { label: 'MyContract.myMethod()', publicKey: '..Nq6w', update: { appState: '["1",null,null,null,null,null,null,null]' }, preconditions: { account: '{"state":["0",null,null,null,null,null,null,null]}', }, authorizationKind: 'Proof', authorization: undefined, }, ]; ``` This output includes several essential things to learn about transactions. First of all, this is an array with two entries -- the two account updates that make up this transaction. The first entry is always the fee payer, whose public key was passed in as `sender`. For the `fee`, which you didn't specify, o1js filled in 0; the `authorization` was filled with a dummy signature. In a user-facing zkApp, you typically don't care about setting those values – instead, you create a transaction like this in the browser and pass it on to the user's wallet. The wallet replaces your fee payer with one that represents the user account, with the user's settings for the fee. It would also fill the `authorization` field with a signature created from the user's private key. See [connecting your zkApp with a user's wallet](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-to-write-a-zkapp-ui#connecting-your-zkapp-with-a-users-wallet). The second account update has the `'MyContract.myMethod()'` label. The update corresponds to the method call. An `@method` call always results in the creation of an account update – an update to the zkApp account itself. Other fields in this account update are: - `publicKey` – the zkApp address (like other non-human-readable strings, this is truncated by `tx.toPretty()`) - `update: { appState: [...] }` – shows how the method updates the on-chain state, using `this..set()`. The names and pretty types defined using `@state` are removed in this representation, showing a raw list of 8 field elements or `null` for state fields that aren't updated. - `preconditions: { account: { state: [...] } }` – similar to the `update`, one entry per field of on-chain state for the preconditions created with `this..requireEquals()`. This example accepts transactions only if the first of the 8 state fields equals 0. The `null` values mean that no condition is set on the other 7 state fields. - `authorizationKind: 'Proof'` – indicates this account update must be authorized with a proof. Proof authorization is the default when calling a zkApp method, but not necessarily for other account updates. - `authorization: undefined` – the proof needed on this update isn't there yet. You learn how to add it in a minute. Note that there are many more fields that account updates can have, but `tx.toPretty()` prints only the fields with actual content. Also, not all of the fields must be present. For example, if a zkApp doesn't set a state, the `update` field might be missing. In that case, strictly speaking, it wouldn't be an "update" in the sense that the account is modified. The term "account update" is used for simplicity. As you might have noticed, account updates aren't created in a very explicit manner. Instead, o1js gives you an imperative API, with "commands" like `state.set()`, to create and modify account updates in a transaction. In the end, the entire transaction is sent to the network as one atomic update. If something fails – for example, one of the account updates has insufficient authorization – the _entire_ transaction is rejected and doesn't get applied. This is in contrast to an EVM contract, where the initial steps of a method call could succeed even if the method fails at a later step. ## Creating proofs Finally, here's how to create zero knowledge proofs! ```ts await MyContract.compile(); // this might take a while // ... const tx = await Mina.transaction(sender, async () => { await zkapp.myMethod(someArgument); }); await tx.prove(); // this might take a while ``` This example code includes two new operations: - `MyContract.compile()` creates prover and verification keys from your smart contract.[^1] You must create the keys before you can create any proofs. - `tx.prove()` goes through your transaction and creates proofs for all the account updates that came from method calls. [^1]: The name `compile()` is a metaphor for what this function does: creating prover and verifier functions from your code. It doesn't refer to literal "compilation" of JS into a circuit representation. The circuit representation of your code is created by _executing_ it, not by compiling it. Also, the prover function still includes the execution of your JS code as one step. Both of these heavy cryptographic operations can take between a few seconds and a few minutes, depending on the amount of logic you're proving and on how fast your machine is. If you print the transaction again with `tx.toPretty()`, it now has the proof as a Base64 string inside the `authorization` field: ```ts [ // ... { label: 'MyContract.myMethod()', // ... authorization: { proof: '..KSkp' }, }, ]; ``` ## How proofs link to account updates You might wonder: what, exactly, is proved? How is the proof linked to the account update it is part of? The proof attests to two different things: - The execution of `myMethod()` - The public input of that execution Recall that all method arguments are _private inputs_. So, the verifier doesn't get to see them, and the proof doesn't say anything about them (it only says that there were _some_ private inputs that satisfied all constraints). However, a zk proof can also have a public input. In the case of zkApps, **the public input is the account update** that is passed in implicitly with `tx.prove()`. The prover function (smart contract logic) creates its own account update and constrains it to equal the public input. The public input is data that is shared between the prover and verifier: - The verifier passes in the public input when verifying it. - The proof is valid only if it was created with _the same public input_. The proof attests to the validity of exactly this account update. If you change the account update before sending it to the Mina network, the proof is no longer valid. The only valid account updates for a zkApp account are the ones created according to the logic of your smart contract. This core concept is why zkApp smart contracts execute on the client side. ## Example: Payment from a zkApp To learn more about account updates, see the example for paying out MINA from a zkApp. To send MINA, use `this.send()` from a smart contract method: ```ts class MyContract extends SmartContract { @method async payout(amount: UInt64) { // TODO: logic that determines whether the user is allowed to claim this amount this.send({ to: this.sender, amount }); } } ``` The `@method async payout()` pays out a given amount of nanoMINA to the sender of the transaction, which you get with `this.sender`. In a real zkApp, you would add conditions to this method to determine who can call it with which amounts. To call this method in a transaction and print the result: ```ts const MINA = 1e9; const tx = await Mina.transaction(sender, async () => { await zkapp.payout(UInt64.from(5 * MINA)); }); await tx.prove(); console.log(tx.toPretty()); ``` :::info MINA amounts, in all o1js APIs and elsewhere in the protocol, are always denominated in nanoMINA = `10^(-9)` MINA, which is why you set `const MINA = 1e9`. ::: The transaction now has three account updates: ```ts [ { // fee payer }, { label: 'MyContract.payout()', publicKey: '..Nq6w', balanceChange: { magnitude: '5000000000', sgn: 'Negative' }, authorizationKind: 'Proof', authorization: { proof: '..KSkp' }, }, { publicKey: '..VeLh', balanceChange: { magnitude: '5000000000', sgn: 'Positive' }, callDepth: 1, caller: '..umxw', authorizationKind: 'None_given', }, ]; ``` - The zkApp update with label `'MyContract.payout()'` has a negative `balanceChange` of 5 billion (= 5 MINA). This makes sense, because you are sending MINA away from the zkApp account. - An additional account update has a corresponding positive balance change – the user account that receives MINA. Two quick observations: - You didn't explicitly create the receiver account update. It was created, and attached to the transaction, by calling `this.send()`. o1js tries to abstract away the low-level language of account updates where possible and give you intuitive commands to create the right ones. However, you might sometimes have to create account updates explicitly. - The user update has `authorizationKind: 'None_given'`. That means the update is not authorized. This is possible because it doesn't include any changes that require authorization: It just receives MINA. You can send someone MINA without their permission. In general, there are three kinds of authorizations that an account update can have: a proof, a signature, or none. You learn more about signatures in the next section. You can find more details in [Permissions](/zkapps/writing-a-zkapp/feature-overview/permissions). ## Account update tree structures Next, observe that the user account update has a `callDepth: 1`. This is because the update was created from within a zkApp call. Account updates, displayed as a flat list here, are implicitly structured as a _list of trees_. Updates with a call depth of 1 or higher are child nodes of another update in that list of trees. In this case, the zkApp (sender) account update is at the top level (`callDepth: 0`) and the user (receiver) account update is a child of it. So, what does this tree structure mean? Recall that the zkApp account update is public input to its proof. Now, the fully general version of that statement is: **In a tree of account updates, all nodes are public inputs to the proof of the root node.** (If there is such a proof. This also holds for sub-trees of each tree.) Concretely, in this example, both the zkApp account update and the user account update are public input to the zkApp method call. Intuitively, the public input means that the zkApp can "see" and constrain the update as part of its proof. Here, it means that no one can change the public key of the receiver, or amount they receive, without making the proof invalid. The update can contain only what the method specified. All of this is true because `this.send()` placed the receiver update at call depth 1, under the zkApp update. As a counter example: The fee payer is never part of the public input. It can be anything without affecting the validity of the proof. A key takeaway is: If you want something to become part of your proof, you must put it inside your `@method`. ## Signing transactions and explicit account updates To recap the workflow covered so far: You write a smart contract, and then create a transaction to call the smart contract. You've seen how this transaction consists of account updates that are created by o1js. The next example shows how an account update is created explicitly. You'll also learn how to use signatures for authorizing updates to user accounts. To continue the [Payment from a zkApp example](#example-payment-from-a-zkapp) in the other direction: make a deposit from the user into the zkApp. Payments made from a user account require a signature by the user. Here's the smart contract code: ```ts class MyContract extends SmartContract { @method async deposit(amount: UInt64) { let senderUpdate = AccountUpdate.create(this.sender); senderUpdate.requireSignature(); senderUpdate.send({ to: this, amount }); // TODO: logic that gives the user something in return for the deposit } } ``` To unpack what happens here, the first line of the method creates a new, empty account update for the sender account: ```ts let senderUpdate = AccountUpdate.create(this.sender); ``` - `AccountUpdate` is the class in o1js that represents account udpates. - `AccountUpdate.create()` instantiates this class and attaches the update to the current transaction at the same level where `create` is called. If it is called inside an `@method`, the `AccountUpdate` is created as a child (public input) of the zkApp update. The next line specifies that the update must be authorized with a signature: ```ts senderUpdate.requireSignature(); ``` You can also use a shortcut for `AccountUpdate.create()` and `requireSignature()` in a single command: ```ts let senderUpdate = AccountUpdate.createSigned(this.sender); // create + requireSignature ``` Finally, use `.send()` on the sender `AccountUpdate` to deposit into the zkApp with the same API as `this.send()`: ```ts senderUpdate.send({ to: this, amount }); ``` Note that instead of an address as the `to` field, pass in `this`, which is a `SmartContract`, so that `.send()` doesn't create an additional update, but uses the one already created for our zkApp. A transaction for calling this method looks like: ```ts [ { // fee payer }, { label: 'MyContract.deposit()', balanceChange: { magnitude: '5000000000', sgn: 'Positive' }, // ... }, { publicKey: '..VeLh', balanceChange: { magnitude: '5000000000', sgn: 'Negative' }, callDepth: 1, useFullCommitment: true, caller: '..umxw', authorizationKind: 'Signature', authorization: undefined, }, ]; ``` The third account update is the one created with `AccountUpdate.create()`. Two changes to the update were caused by calling `requireSignature()`: - `useFullCommitment: true`, not explained here but has to do with replay protection when using signatures. - `authorizationKind: 'Signature'` Finally, `authorization: undefined` indicates that the signature is not provided yet. In a user-facing zkApp, user signatures are typically added by a wallet, not within o1js. In that case, the missing signature is expected. However, in tests or when calling zkApps from a Node.js script, you must add the signatures with `tx.sign([...privateKeys])`, called after `Mina.transaction` on the finished transaction. For example: ```ts const sender = senderPrivateKey.toPublicKey(); // public key from sender's private key const tx = await Mina.transaction(sender, async () => { await zkapp.deposit(UInt64.from(5 * MINA)); }); await tx.prove(); tx.sign([senderPrivateKey]); // senderKey is a PrivateKey ``` - The example shows how to derive the sender's public key, `sender`, from its private key, `senderPrivateKey`. - `.sign()` goes through the transaction and adds signatures on all account updates that: - Need a signature - Whose public key matches one of the private keys that were provided `.sign()` takes an array, so you could provide multiple private keys for signing. In this example, two account updates are signed with `tx.sign()`: The fee payer and the depositor account update. Both have the `sender` public key on them that matches `senderPrivateKey.toPublicKey()`. :::tip o1js allows you to load and store private and public keys in Base58 format. To create the sender private key in a script: ```ts const senderPrivateKey = PrivateKey.fromBase58('EKEQc95...'); ``` In a real server-side deployment, you probably want to load keys from a file or environment variable, instead of hard-coding them in your source code. ::: Recall that account updates can have three types of authorization: - Proof authorization – used for zkApp accounts when you do an `@method` call. Proofs are verified against the on-chain verification key. - Signature authorization – used to update user accounts. Signatures are verified against the account's public key. - No authorization – used on updates which don't require authorization. For example, positive balance changes. These are common defaults. The full source of truth is set by the _account permissions_, see [Permissions](/zkapps/writing-a-zkapp/feature-overview/permissions). Using permissions, account owners can decide on a fine-grained level which type of authorization is required on which kinds of updates. Permissions are checked every time an account update tries to interact with an account. ## Sending transactions The final step of creating a transaction is sending it to the network. Like signing, in a user-facing zkApp this transaction is usually handled by a wallet. You can use this workflow for testing and scripting. To send a transaction, you must specify what network to interact with by specifying a "Mina instance" at the beginning of your script: ```ts const Network = Mina.Network('https://example.com/graphql'); Mina.setActiveInstance(Network); ``` The network URL must be a GraphQL endpoint that exposes a compatible GraphQL API. This URL determines where transactions are sent and where o1js gets account information from when _creating_ transactions. For example, when you do something like `this..get()` in your smart contract, the Mina instance is asked for the account using `Mina.getAccount`, which in turn causes the account to be fetched from the GraphQL endpoint. To send a transaction, use `tx.send()`: ```ts // set Mina instance const Network = Mina.Network('https://example.com/graphql'); Mina.setActiveInstance(Network); // create the transaction, add proofs and signatures const tx = await Mina.transaction(sender, async () => { // ... }); await tx.prove(); tx.sign([senderPrivateKey]); // send transaction await tx.send(); ``` The output of `tx.send()` can be used to: - Wait for inclusion of this transaction in a block - Get the transaction hash, which lets you look up the pending transaction on a block explorer ```ts // send transaction, log transaction hash let pendingTx = await tx.send(); console.log(`Got pending transaction with hash ${pendingTx.hash}`); // wait until transaction is included in a block await pendingTx.wait(); // our account updates are applied on chain! ``` In addition to `Mina.Network`, you can also use a simulated local blockchain for local testing: ```ts const Local = Mina.LocalBlockchain(); Mina.setActiveInstance(Local); ``` Doing this means setting up a fresh, local ledger that is pre-filled with a couple of accounts with funds that you have access to. "Sending" a transaction here just means applying your account updates to that local simulated Mina instance. This is helpful for testing, especially because account updates go through the same validation logic locally that they would on-chain. Fun fact: The `LocalBlockchain` instance literally uses the same OCaml code for transaction validation and application that the Mina node uses; it's compiled to JavaScript with [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml). You can learn more about testing in [Test zkApps Locally](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally). --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps --- # Security and zkApps On this page, you will find guidance for how to think about security when building zkApps. We also provide a list of best practices and common pitfalls to help you avoid vulnerabilities. ## Auditing your zkApp Apart from acquiring a solid understanding of security aspects of zkApps, we recommend that critical applications also get audited by independent security experts. There has been an internal audit of the o1js code base already, [the results of which you can find here](/zkapps/o1js#audits-of-o1js). You can also see the results of a third-party audit, performed by Veridise, [here](https://github.com/o1-labs/o1js/blob/a09c5167c4df64f879684e5af14c59cf7a6fce11/audits/VAR_o1js_240318_o1js_V3.pdf). ## Attack model The first and most important step for zkApp developers is to understand the attack model of zkApps, which differs from traditional web apps in important ways. In essence, there are two new kinds of attack: 1. **Adversarial environment**: Like smart contracts in general, zkApps are called in an environment that you don't control. For example, you have to make sure that your zkApps is not misbehaving when passed particular method inputs, or when used as part of transactions different than you intended. The caller chooses how and with what inputs to call your zkApp, not you; and they might use this opportunity to exploit your application. 2. **Underconstrained proofs**: Successfully "calling" a zkApp really just means getting a proof accepted onchain which is valid against your zkApp's verification key. Such a proof could, for example, be created using a _modified_ version of your zkApp code. This will work only if the modification doesn't change any of your constraints -- the logic that forms the proof. Hence, you have to take care that your zkApp code _correctly proves_ everything it needs to prove; unproved logic can be changed at will by a malicious prover. Note how the first point (adversarial environment) is relevant in all kinds of permissionless systems, like smart contracts. The second point, which can be seen as a special case of the first, is specific to the zkApp model. In classical smart contracts, you can rely on the fact that the code you deploy is exactly the code that is executed; in offchain-executed zkApps, you can't. While having your code modified due to underconstrained proofs sounds scary, we emphasize that most of the attack surface here is covered by o1js itself. It's o1js' job that when you call `a.assertLessThan(b)`, you prove that `a < b` under all circumstances; and the o1js team dedicates a lot of resources to the security of its standard library. The explicit goal is that when using o1js in an idiomatic way, you shouldn't have to worry about underconstrained logic. That story changes when you start writing your own low-level provable methods. When doing so, you enter expert territory, and there are many new pitfalls to be aware of. We plan to dedicate [a section to writing your own provable methods](#rolling-your-own-provable-methods) below. If there is just one take away from this post, it should be to always keep an adversarial mindset. Be paranoid about your zkApp's security! In the next section, we demonstrate the attack model of zkApps with a concrete example. ## Example: An insecure token contract Take a look at the following snippet of a token contract. The contract has a method called `mintOrBurn()` which is supposed to approve an account update that mints or burns tokens. The skeleton of `mintAndBurn()` exists: We read address and balance change (positive or negative) from the update, and we also call `this.approve()` so the update can use our token. However, as the TODO comment says, we still need to call `assertCanMint()` or `assertCanBurn()` to check if the minting or burning is allowed for this account. ```ts class FlawedTokenContract extends TokenContract { // ... @method async mintOrBurn(update: AccountUpdate) { // read mint/burn properties from the update let amount = update.balanceChange; let address = update.publicKey; // TODO: only allow minting and burning under certain conditions // approve the account update this.approve(update); // ... other actions related to minting or burning // like updating the total supply based on `amount` ... this.updateTokenSupply(amount); } assertCanMint(amount: Int64, address: PublicKey) { // ... logic asserting that minting is allowed for this account ... } assertCanBurn(amount: Int64, address: PublicKey) { // ... logic asserting that burning is allowed for this account ... } updateTokenSupply(amount: Int64) { // ... logic updating the total supply ... } } ``` :::note The pattern of passing in the full `AccountUpdate` here, and not just amount and address, is good practice and more flexible than creating the account updates inline: It allows the method to be used by zkApps, not just typical end-user accounts. zkApps need to put their own proof on the account update to authorize a spend. ::: ### Creating an insecure contract We need to use either `assertCanMint()` or `assertCanBurn()`, but how do we know which one? Well, let's just add a parameter to the method that tells us whether this is a mint or a burn. Then let's call the appropriate method based on that parameter. Github Copilot fills this out nicely for us: ```ts @method async mintOrBurn(update: AccountUpdate, isMint: Bool) { // read mint/burn properties from the update let amount = update.balanceChange; let address = update.publicKey; // only allow minting and burning under certain conditions if (isMint) { this.assertCanMint(amount, address); } else { this.assertCanBurn(amount, address); } // approve the account update this.approve(update); // ... other actions related to minting or burning // like updating the total supply based on `amount` ... this.updateTokenSupply(amount); } ``` LGTM! However, in tests this doesn't seem to work, and after some debugging we find the problem: `isMint`, being a `Bool` and not a JS boolean, is always truthy, so this always checks the mint condition and never the burn condition. Seems like we have to coerce it to a boolean first: ```diff - if (isMint) { + if (isMint.toBoolean()) { this.assertCanMint(amount, address); } else { this.assertCanBurn(amount, address); } ``` When compiling this contract, there's the next unpleasant surprise: A complicated error about not being able to call `.toBoolean()`. ``` Error: b.toBoolean() was called on a variable Bool `b` in provable code. ... To inspect values for debugging, use Provable.log(b). For more advanced use cases, there is `Provable.asProver(() => { ... })` which allows you to use b.toBoolean() inside the callback. Warning: whatever happens inside asProver() will not be part of the zk proof. ``` At least there is a hint at the end that this might work when wrapped inside `Provable.asProver()`: ```diff + Provable.asProver(() => { if (isMint.toBoolean()) { this.assertCanMint(amount, address); } else { this.assertCanBurn(amount, address); } + }); ``` With that change, compiling finally works and our tests do as well. Progress! 🚀 However, the statement about `asProver()` not being part of the zk proof is concerning. So maybe we should check that this actually prevents invalid minting and burning. After creating a test that tries to mint or burn tokens for an account that is not allowed to, we confirm that it fails. So we're good to go. Right? Unfortunately, not at all. The security of our contract is thoroughly broken. We ignored both [attack surfaces described above](#attack-model): _Adversarial environment_ and _underconstrained proofs_. ### First problem: we didn't prove everything The first problem was moving essential logic inside `Provable.asProver()`. It can be generalized as: - **Security advice #1: Don't move your logic outside the proof.** Other APIs that let you do this are `Provable.witness()` and `Provable.witnessFields()`. They are essential in advanced provable code, but you have to use them carefully! Checks that are not part of the proof can be bypassed. In our case, a bad actor could simply get our source code and delete the entire `Provable.asProver()` block. From that, they can call our contract without the `assertCanMint()` and `assertCanBurn()` checks, and mint any amount of tokens they like. In particular, negative tests that fail on invalid actions are not enough to show that these actions are impossible, under the attack model that our code can be changed. A second thing to note is that we had to fight o1js quite hard to make our insecure code work. This should be a red flag in general. - **Security advice #2: Don't try to trick o1js.** The fact that o1js doesn't allow you to call `.toBoolean()` on a `Bool` inside provable code is a security feature. It's hard to circumvent for a reason. There are tons of vulnerable patterns that would be introduced if we allowed going back and forth between provable variables (the `Bool`) and JS values (the `boolean`), and doing so is a frequent source of issues in lower-level frameworks like arkworks. If o1js makes something really hard to do and puts warnings in front of it, it's best to assume this is for a reason and not try to hack around it. And of course, reach out on [our discord](https://bit.ly/MinaDiscord) when in doubt about your code's security. ### Fix: Adding the missing constraints Let's see how to solve the `asProver()` issue. In provable code, we can't do assertions conditionally, so we have to do all of them at the same time. In our case, we could refactor the mint and burn checks so that they can be applied conditionally. The result could look like this: ```ts async mintOrBurn(update: AccountUpdate, isMint: Bool) { // ... // only allow minting and burning under certain conditions this.assertCanMint(isMint, amount, address); this.assertCanBurn(isMint.not(), amount, address); // ... } assertCanMint(enabledIf: Bool, amount: Int64, address: PublicKey) { // ... logic asserting that minting is allowed for this account ... } assertCanBurn(enabledIf: Bool, amount: Int64, address: PublicKey) { // ... logic asserting that burning is allowed for this account ... } ``` ### Second problem: we trusted the caller However, our contract is still insecure, because we forgot that it's called in an adversarial environment. Our contract just takes the `isMint` parameter for granted, even though the `update` could be either minting or burning tokens. A bad actor could easily call `mintOrBurn()` with a positive balance change on the `update` and `isMint = false`. This would bypass the `assertCanMint()` check and only do `assertCanBurn()` instead, which might mean they can mint tokens without much restrictions. - **Security advice #3: Don't trust the caller of a zkApp method.** In a sense, this is the same issue as moving logic outside the proof: Method inputs originate from an unconstrained source. If our logic relies on correlations between variables, those correlations must be put into constraints. ### Fix: Removing assumptions on method inputs The issue with `isMint` is, of course, simple to fix. Instead of letting the caller pass it in, we can compute it inside our method, as `amount.isPositive()`: ```diff - async mintOrBurn(update: AccountUpdate, isMint: Bool) { + async mintOrBurn(update: AccountUpdate) { // read mint/burn properties from the update let amount = update.balanceChange; + let isMint = amount.isPositive(); let address = update.publicKey; ``` This concludes our example of fixing an insecure token contract. ## Best practices for zkApp security In the last section, we already gave three pieces of advice concerning zkApp security. - **Don't move your logic outside the proof.** - **Don't try to trick o1js.** - **Don't trust the caller of a zkApp method.** This section collects more recommendations and describes more complex attacks on a zkApp that you might not be aware of. - [**Lock down permissions as much as possible**](#lock-down-permissions-as-much-as-possible) - [**Only call external contracts with locked down permissions**](#only-call-external-contracts-with-locked-down-permissions) - [**Don't deadlock your zkApp by interacting with unknown accounts**](#dont-deadlock-your-zkapp-by-interacting-with-unknown-accounts) :::info The list above is intended to grow over time. If you have a security tip that you think should be included, [please let us know](https://github.com/o1-labs/docs2/edit/main/docs/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps.mdx)! ::: ### Lock down permissions as much as possible Like every account on Mina, zkApps have permissions that restrict what account updates are possible and what authorization they need. The default permissions on deployment include the following (leaving out some permissions that are not relevant for most zkApps): ```ts { editState: Permission.proof(), send: Permission.proof(), receive: Permission.none(), setDelegate: Permission.signature(), setPermissions: Permission.signature(), setVerificationKey: Permission.VerificationKey.signature(), setZkappUri: Permission.signature(), editActionState: Permission.proof(), setTokenSymbol: Permission.signature(), incrementNonce: Permission.signature(), setVotingFor: Permission.signature(), setTiming: Permission.signature(), access: Permission.none(), } ``` If you don't know what these permissions mean, we recommend to read the [permissions docs](/zkapps/writing-a-zkapp/feature-overview/permissions) first. Two of these defaults stand out as highly problematic: - `setVerificationKey: signature`. This means that the account owner (zkApp developer) can change the code and redeploy the zkApp. In a sense, the zkApp is upgradable in arbitrary ways. This makes it hard to trust the zkApp from a user perspective. - `setPermissions: signature`. In a sense, this overrides all other permissions, since the zkApp developer can arbitrarily change the permissions themselves. For example, if they change the `editState` permission back to `signature`, they can reset zkApp state to any value they want. They can even do this, change the state to their favor and reset the permission back to `proof` atomically in a single transaction, hoping that no one notices. You should view these permissions as training wheels. They are useful for iterating on the zkApp during development. We thought it was a better default to let developers redeploy their zkApp in the early stages, as they find bugs or have to redesign some aspect of the zkApp. However, it means that these zkApps essentially have to be viewed as a trusted service, not a permissionless protocol. If you are confident that your zkApp code is final, you should lock down permissions: Set both `setVerificationKey` and `setPermissions` to `impossible`. Alternatively, set `setVerificationKey` to `proof` and add a method that can upgrade the zkApp according to a permissionless, open protocol. More generally, we recommend to follow the _principle of least authority_: Remove any way to update the account that is not necessary for your application. For example: - `setTiming`: The timing field allows you to [lock the funds](/zkapps/writing-a-zkapp/feature-overview/time-locked-accounts) in an account for a certain amount of time. If you don't plan on using this feature, then it poses an unnecessary risk. Change it to `setTiming: impossible`. - `setTokenSymbol`: Similarly, if your zkApp is a token, and its token symbol is not supposed to ever change, you could use `setTokenSymbol: impossible`. For some permissions, `signature` might be a good choice: - `setDelegate`: for most zkApps, setting the delegate (the block producer that zkApp balance is staked with) can be seen as an administrative decision that is independent of the zkApp's main function. It's fine to keep this as `signature`, unless your zkApp logic specifically deals with setting and updating the delegate. - `incrementNonce`: typically, incrementing the account nonce is itself only done when signing a transaction. Similar to `setDelegate`, if the nonce doesn't play a special role in your zkApp logic, it should be fine to keep this as `signature`. However, incrementing the nonce can be useful to make any action non-repeatable. If you want to leverage this for both zkApp methods and administrative actions, you can set it to `proofOrSignature`. ### Only call external contracts with locked down permissions This is the flipside of the previous advice. The permissions of third-party zkApps you call into are an important factor for the security of your own zkApp. The most obvious reason is simply to guarantee that you will always be _able_ to call the external contract. Imagine one of the following scenarios: - The called contract has `setPermissions: signature`. One day, the contract's maintainer decides to shut down their contract. Maybe not even in their own will, but because they are pressured to do so. They can simply change their `access` permission to `impossible`, which means no one will ever be able to call their contract again. - The called contract has `setPermissions: impossible`, but still allows verification key upgrades with `setVerificationKey: signature`. Similarly, this gives them a trivial way to make their contract unusable: Just replace the verification key with one where all methods prove a contradictory statement, like `x === 0 && x === 1`. In either of these scenarios, the unusable third-party contract makes your own zkApp unusable as well. For this reason alone, you should only call external contracts that have locked down verification key changes as well as made changes to the permissions themselves impossible. Apart from the deadlock risk described above, there can be other attacks enabled by an upgradable external contract. You should be mindful of those whenever your own zkApp relies on particular behaviour of the external contract. For example, calling a DEX might involve spending your own token A and _trusting the DEX_ to give you a fair amount of token B in return. If the DEX is upgradable, its maintainer might modify the code you trusted and rob you or your users of tokens. ### Don't deadlock your zkApp by interacting with unknown accounts In the [previous section](#only-call-external-contracts-with-locked-down-permissions), we described how calling a contract which sets its `access` permission to `impossible` can deadlock your zkApp. It was fairly easy to defend against because we assumed that you know the contract account up front, and can manually check its permissions. There is a more complicated version of this problem when interacting with accounts that you _can't_ check a priori, or can't expect to have locked-down permissions. It typically arises in the scenario where you create account updates from a [reducer](/zkapps/writing-a-zkapp/feature-overview/actions-and-reducer) call. #### A problematic token airdrop To have a concrete example, consider a token airdrop. As the token contract developer, you precompute a [Merkle map](/zkapps/o1js/merkle-tree) containing eligible accounts and their airdrop amounts, and store the Merkle root onchain. _Claiming_ an airdrop has to involve updating the tree and onchain root, because otherwise the same account could claim the airdrop multiple times. To scale payouts to multiple concurrent users per block, you approach the problem with [actions and reducer](/zkapps/writing-a-zkapp/feature-overview/actions-and-reducer). To claim, a user dipatches a "claim" action that contains their address and airdrop amount. On top of that, every block, you run a reducer method which contains the following logic: 1. For every pending "claim" action, you check whether it's really contained in the Merkle map (i.e., you either prove inclusion or non-inclusion). 2. If the claim is valid, you create an account update that mints the airdrop amount to the user. 3. You remove the claiming account from your Merkle map. This should work well unless a single eligible user doesn't like your token and decides to dispatch a valid "claim" action while also setting either their `access` or `receive` permission to `impossible` (or `signature`, or `proof`). This makes the reducer fail at step 2: The account update it is creating does not have the necessary authorization, and the entire reducer transaction fails. At this point, the reducer is stuck because actions can only be processed in order. No reducer call will ever succeed again, your contract is deadlocked. #### Fixed airdrop: lock down all token account permissions A solution for this particular application scenario is to not even allow users to create token accounts with problematic `access` and `receive` permissions. This is possible since a token contract already has logic that approves on every single account update on every single token account. In its `approveBase()` method, the token contract asserts that `access` and `receive` permissions on every account update are not updated to anything else than the default (`none`). This prevents the attack. #### Be careful with creating account updates from a reducer The fix above was possible because user accounts were using a token that we controlled ourselves. The behavior of preventing bad permissions is also part of Mina's upcoming [fungible token standard](https://github.com/MinaFoundation/mina-fungible-token), so the issue won't exist at all for tokens following that standard. There will be cases where a similar fix is not applicable; but more complicated mitigations are possible. In any case, you should be careful whenever you create account updates for unknown accounts from a reducer, or in any other scenario where a single invalid child update deadlocks your zkApp. ### When developing a token, extend a standard token contract When developing a token contract, a number of security considerations come into play. First and foremost, it is important to implement token approvals correctly. The [`access` permission](/zkapps/writing-a-zkapp/feature-overview/permissions#types-of-permissions) exists so that token contracts are able to have every token interaction approved by one of the contract's methods. When a token is built off of the default `SmartContract` and doesn't change the `access` permission from its `none` default, users can get any token interaction approved. Simply by including a dummy account update of the token contract in their transaction, they can mint an arbitrary number of tokens to themselves. Even creating the token owner account before deploying the contract there, and thus leaving it in a temporary state where the `access` permission is not set, could allow this attack. The base `TokenContract` exported from o1js avoids all these pitfalls and gives you tools that abstract away considerable complexity to implement general-purpose token approval logic. We highly recommend extending `TokenContract` or a token standard that is based on it. ## Rolling your own provable methods :::caution This section is not written yet. When developing your own provable methods, make sure to [prove everything](#first-problem-we-didnt-prove-everything) you need, and [not to trick o1js](#first-problem-we-didnt-prove-everything). ::: --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/smart-contracts --- # Smart Contracts You write smart contracts by extending the base class `SmartContract`: ```ts class HelloWorld extends SmartContract {} ``` The `constructor` of a `SmartContract` is inherited from the base class and cannot be overriden. The zkApp account address (a public key) is its only argument: ```ts let zkAppKey = PrivateKey.random(); let zkAppAddress = PublicKey.fromPrivateKey(zkAppKey); let zkApp = new HelloWorld(zkAppAddress); ``` ## zkApp Accounts On Mina, there is no strong distinction between normal "user accounts" and "zkApp accounts". A zkApp account: - Is an account on the Mina blockchain where a zkApp smart contract is deployed. - Has a verification key associated with it. The verification key stored on the zkApp account can verify zero knowledge proofs generated with the smart contract. The verification key lives on-chain for a given zkApp account and is used by the Mina network to verify that a zero knowledge proof has met all constraints defined in the prover. See [Prover Function and Verification Key](/zkapps/writing-a-zkapp/introduction-to-zkapps/how-zkapps-work#prover-function-and-verification-key). ## Methods Interaction with a smart contract happens by calling one or more of its _methods_. You declare methods using the `@method` decorator: ```ts class HelloWorld extends SmartContract { @method async myMethod(x: Field) { x.mul(2).assertEquals(5); } } ``` Within a method, you can use o1js data types and methods to define your custom logic. To understand what successful execution means, look at this line in the example: ```ts x.mul(2).assertEquals(5); ``` Creating a proof for this method is possible only if the input `x` satisfies the equation `x * 2 === 5`. This is called a "constraint". Magically, the proof can be checked without seeing `x` because it's a _private input_. The method has one input parameter, `x` of type `Field`. In general, arguments can be any of the built-in o1js types: `Bool`, `UInt64`, `PrivateKey`, and so on. These types are referred to as [structs`](#custom-data-types). ## zk-SNARK circuits Internally, every `@method` defines a zk-SNARK circuit. From the cryptography standpoint, a smart contract is a collection of circuits, all of which are compiled into a single prover and a verification key. The proof says something to the effect of "I ran one of these methods, with some private input, and it produced this particular set of account updates". In zero knowledge proof terms, the account updates are the _public input_. The proof is accepted on the network only if it verifies against the verification key stored in the account. This verification requirement ensures that the same zkApp code also ran on the end user's device and that the account updates conform to the smart contract's rules. ### @method Inside a `@method`, things sometimes behave a little differently. To construct a circuit which can then be proven, o1js calls into SnarkyML, a language that builds circuits and connects variables and constraints. As a zkApp developer, you must use the methods, functions, and types provided by o1js. Plain JavaScript code does not call into SnarkyML and therefore is not able to construct circuits. When `SmartContract` is compiled into prover and verification keys, methods are in an environment where the method inputs don't have any concrete values attached to them. Instead, they are like mathematical variables `x`, `y`, `z` that are used to build up abstract computations like `x^2 + y^2` by running the method code. In contrast, all the variables _have_ actual values attached to them (cryptographers call them "witnesses") during proof generation. To log these values for debugging, use a special function for logging from inside your method: ```ts Provable.log(x); ``` The API is like `console.log`, but it automatically handles printing o1js data types in a readable format. However, the `Provable.log(x)` function does not have any effect while `SmartContract` is being compiled. ## On-chain state A smart contract can contain [on-chain state](/glossary#on-chain-state). Declare it as a property on the class with the `@state` decorator: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); // ... } ``` Here, `x` is of type `Field`. Like with method inputs, only o1js structs can be used for state variables. The state can consist of at most 8 fields of 32 bytes each. These states are stored on the zkApp account. Some structs take up more than one `Field`. For example, a `PublicKey` needs two of the eight fields. States are initialized with the `State()` function. A method can modify on-chain state by using `this..set()`: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); @method async setX(x: Field) { this.x.set(x); } } ``` As a zkApp developer, if you add this method to your smart contract, you are saying: "Anyone can call this method to set `x` on the account to any value they want." ## Reading state This example _reads_ state: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); @method async increment() { // read state const x = this.x.get(); this.x.requireEquals(x); // write state this.x.set(x.add(1)); } } ``` The `@increment()` method fetches the current on-chain state `x` with `this.x.get()`. Later, it sets the new state to `x + 1` using `this.x.set()`. Simple! Another line might looks weird at first: ```ts this.x.requireEquals(x); ``` Here's what it means to "use an on-chain value" during off-chain execution. When you use an on-chain value, you have to _prove_ that this value is the on-chain value. Verification has to fail if it's a different value. Otherwise, a malicious user could modify o1js and make it just use any other value than the current on-chain state – breaking the zkApp. You must link "`x` at proving time" to be the same as "`x` at verification time". This is a _precondition_, a condition that is checked by the verifier (a Mina node) when it receives the proof in a transaction: ```ts this.x.requireEquals(x) ``` This code adds the precondition that `this.x` – the on-chain state at verification time – must equal `x` – the value fetched from the chain on the client side. In zkSNARK language, `x` becomes part of the public input. Using `this..requireEquals` is more flexible than equating with the current value. For example, `this.x.requireEquals(10)` fixes the on-chain `x` to the number `10`. Why not use `this.x.get()` to add the precondition automatically, instead of writing `this.x.requireEquals(x)`? To keep things explicit. The assertion reminds you to add logic which makes the proof fail: If `x` isn't the same at verification time, the transaction will be rejected. So, you must use care to read on-chain values if many users are expected to read and update state concurrently. It is applicable in some situations, but might cause race conditions or call for workarounds, in some situations. One workaround is to use actions. See [Actions and Reducer](/zkapps/writing-a-zkapp/feature-overview/actions-and-reducer). ## Assertions Assertions can be incredibly useful to constrain state updates. Common assertions you can use are: ```ts x.assertEquals(y); // x = y x.assertBoolean(); // x = 0 or x = 1 x.assertLt(y); // x < y x.assertLte(y); // x <= y x.assertGt(y); // x > y x.assertGte(y); // x >= y ``` For a full list, see the [o1js reference](/zkapps/o1js-reference). To modify the `increment()` method to accept a parameter: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); @method async increment(xPlus1: Field) { const x = this.x.get(); this.x.requireEquals(x); x.add(1).assertEquals(xPlus1); this.x.set(xPlus1); } } ``` Here, after obtaining the current state `x` and asserting that it equals the on-chain value, make another assertion: ```ts x.add(1).assertEquals(xPlus1); ``` If the assertion fails, o1js throws an error and does not submit the transaction. If the assertion succeeds, it becomes part of the proof that is verified on-chain. Because of this, the new version of `increment()` is _guaranteed_ to behave like the previous version: It can only ever update the state `x` to `x + 1`. ### Debugging Add optional failure messages to assertions to make debugging easier. For example, write the previous example as: ```ts x.add(1).assertEquals(xPlus1, 'x + 1 should equal xPlus1'); ``` ## Public and private inputs While the state of a zkApp is **public**, method parameters are **private**. When a smart contract method is called, the proof it produces uses zero knowledge to hide inputs and details of the computation. The only way method parameters can be exposed is when the computation explicitly exposes them. For example, in the last example the input was directly stored in the public state: `this.x.set(xPlus1);` If this were not the case, define a new method called `incrementSecret()`: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); // ... @method async incrementSecret(secret: Field) { const x = this.x.get(); this.x.requireEquals(x); Poseidon.hash(secret).assertEquals(x); this.x.set(Poseidon.hash(secret.add(1))); } } ``` This time, the input is called `secret`. Check that the hash of the secret is equal to the current state `x`. If this is the case, add `1` to the secret and set `x` to the hash of that. When this code is run successfully, it just proves that the code was run with _some_ input `secret` whose hash is `x` and that the new `x` is set to `hash(secret + 1)`. However, the secret itself remains private, because it can't be deduced from its hash. ## Initializing state To initialize on-chain state, use the `init()` method. Like the constructor, `init()` is predefined on the base `SmartContract` class. - It is called when you deploy your zkApp with the zkApp CLI for the first time. - It is not called if you upgrade your contract and deploy a second time. You can override this method to add initialization of your on-chain state: ```ts class HelloWorld extends SmartContract { @state(Field) x = State(); init() { super.init(); this.x.set(Field(10)); // initial state } } ``` You must call `super.init()` to set your entire state to 0. If you don't have any state to initialize to values other than 0, then there's no need to override `init()`, you can just leave it out. The previous example set the state `x` to `Field(10)`. ## Composing zkApps A powerful feature of zkApps is that they are composable, just like Ethereum smart contracts. You can simply call smart contract methods from other smart contract methods: ```ts class HelloWorld extends SmartContract { @method async myMethod(otherAddress: PublicKey) { const calledContract = new OtherContract(otherAddress); calledContract.otherMethod(); } } class OtherContract extends SmartContract { @method async otherMethod() {} } ``` When a zkApp user calls `HelloWorld.myMethod()`, o1js creates two separate proofs: - One proof for the execution of `myMethod()` as usual - A _separate_ proof for the execution of `OtherContract.otherMethod()` The `myMethod()` proof: - Computes an appropriate hash of the function signature of `otherMethod()` plus any arguments and return values of that function call. - Guarantees that this hash matches the `callData` field on the account update produced by `otherMethod()` that is made part of `myMethod()`'s public input. Therefore, when you call another zkApp method, you effectively prove: "I called a method with this name, on this zkApp account, with this particular arguments and return value." To return a value from the method, you have to explicitly declare the return type using the `method.returns` decorator: Here's an example of returning a `Bool` called `isSuccess`: ```ts @method.returns(Bool) async otherMethod(): Promise { // annotated return type // ... return isSuccess; } ``` ## Custom data types Smart contract method arguments can be any of the built-in [o1js types](/zkapps/o1js/basic-concepts#built-in-data-types). However, what if you want to define your own data type? You can create a custom data type for your smart contract using the `Struct` function that o1js exposes: 1. Create a class that extends `Struct({ })`. 1. Then, inside the object `{ }`, define the fields that you want to use in your custom data type. For example, you can create a custom data type called `Point` to represent a 2D point on a grid. The `Point` struct has no instance methods and is used only to hold information about the `x` and `y` points. To create the `Point` class, extend the `Struct` class: ```ts class Point extends Struct({ x: Field, y: Field, }) {} ``` Now that `Struct` is defined, you can use it in your smart contract for any o1js built-in types. For example, the following smart contract uses the `Point` struct defined earlier as state and as a method argument: ```ts export class Grid extends SmartContract { @state(Point) p = State(); @method async init() { this.p.set(new Point({ x: Field(1), y: Field(2) })); } @method async move(newPoint: Point) { const point = this.p.get(); this.p.requireEquals(point); const newX = point.x.add(newPoint.x); const newY = point.y.add(newPoint.y); this.p.set(new Point({ x: newX, y: newY })); } } ``` Note that your `Struct` classes can contain o1js built-in types like `Field`, `Bool`, `UInt64`, and so on, or even other custom types that you've defined that are based on the `Struct` class. This flexibility allows for great composability and reusability of structs. --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet --- :::caution Use of the **Lightnet** is appropriate for the **local development and testing** only. It is **not** intended to replicate all aspects of the real public networks. ::: # Testing zkApps with Lightnet ## What is Lightnet? It is a fast, resource-efficient solution to launch a lightweight Mina network and associated tools in a single Docker container. It lets you test zkApps locally on an accurate representation of Mina blockchain before you test same zkApps against the public testnet. Lightnet provides the following benefits: - Reduces the time from ideation to launch by letting you test zkApps against the close-to-real Mina network locally. - Provides the resource-efficient blockchain network with fast startup and syncing times. - Supports `multi-mode` networks. (single-node network managed by multi-purpose Mina Daemon or multi-node network with diverse participant types) - Creates and funds accounts so that you can deploy and interact with your zkApps. The genesis ledger is configured with `1000` pre-funded accounts with the `1550 MINA` balance on each. - Runs the archive data tools like [Mina archive process](/node-operators/archive-node), `PostgreSQL RDBMS`, [Archive-Node-API](/zkapps/writing-a-zkapp/feature-overview/fetch-events-and-actions) (can be disabled if there is no need) - Provides the Mina accounts manager helper tool so you can automate accounts retrieval using, for example, the `Lightnet` [o1js API namespace](https://github.com/o1-labs/o1js/blob/23cdfa3e17a8e8132b70895d34aab711cebd676f/src/lib/mina/fetch.ts#L804). - Simplifies zkApps and network state monitoring by - providing convenient access to detailed services logs - launching the [lightweight Mina explorer](#lightweight-mina-explorer) web application ## Prerequisites `Docker Engine` is required to be installed, see [Install Docker Engine](https://docs.docker.com/engine/install/) official documentation. Lightnet requires minimum hardware resources to operate properly. - Default `single-node` mode - `4.5 GB` of RAM to start up - `1.5-2 GB` of RAM to operate Fewer resources are required if you start the Lightnet without the archive data tools. See [start the network without the archive data tools](#start-the-network-without-the-archive-data-tools). - Closer-to-real `multi-node` mode - More than `16 GB` of RAM See [start the multi node network](#start-the-multi-node-network). When you use Lightnet via the [`zkapp-cli`](/zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli) application, the mentioned resources availability is checked automatically. ## High-level workflow for Lightnet 1. [Write tests for your smart contract](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally#writing-tests-for-your-smart-contract) and test locally on a simulated local blockchain 1. Start the `Docker Engine` 1. [Start the Lightnet](#start-the-single-node-network) 1. [Configure and deploy your zkApp to Lightnet](#configure-your-zkapp) 1. Explore the Docker container processes [log files](#log-files) 1. Use [lightweight Mina explorer](#lightweight-mina-explorer) to visualize the network state 1. Develop, iterate, celebrate, [monitor and troubleshoot](#monitor-and-troubleshoot-the-network-state) 1. [Stop the Lightnet](#stop-the-network) The best way to experience Lightnet is by using it via the [`zkapp CLI`](/zkapps/writing-a-zkapp/introduction-to-zkapps/install-zkapp-cli). ## Start the Lightnet Most of your zkApp testing can be done on a single node network. `Docker Engine` must be running before you can start the Lightnet. ### Start the single node network To start a single node network with default configuration: ```sh $ zk lightnet start ``` This command performs the following operations: - Pulls the latest Docker image for your environment from the [Docker Hub](https://hub.docker.com/r/o1labs/mina-local-network) repository - Prepares the file system - Uses the artifacts built from the `berkeley` branch of the Mina GitHub [repository](https://github.com/MinaProtocol/mina) - Configures the network properties to achieve fast startup, syncing and operation times - Disables the blockchain `SNARK` proofs - Sets the Mina processes logging level to `Trace` - Properly configures the `CORS` settings of the `Nginx reverse proxy` that will serve communications with the Mina Daemon's GraphQL endpoint - Forms the network using `multi-purpose single Mina Daemon` - Starts the `PostgreSQL RDBMS`, `Mina archive process` and the [Archive-Node-API](https://github.com/o1-labs/Archive-Node-API) application - Waits for the network to reach the `synchronized` state ### Use `--no-` prefix for boolean sub-commands To see the options for a sub-commands, use the `--help` (or `-h`) parameter. For example: ```sh $ zk lightnet start --help ``` Some of the `zk lightnet` sub-commands have `boolean` values that default to `true`. For these sub-commands, the option is active when present. For example, the default value for `--sync` is `true`, so using `zk lightnet start` is the same as `zk lightnet start --sync`. For sub-commands that show the option as (`[boolean] [default: true]`), negation happens by adding the `--no-` prefix to the option. For example, to start Lightnet without waiting for the network to reach the `synchronized` state, use: ```sh $ zk lightnet start --no-sync ``` ### Start the network with other settings To see the options to start the blockchain network with other-than-default settings: ```sh $ zk lightnet start --help ``` You can configure different network properties as appropriate to your testing requirements. ### Start the network without the archive data tools By default, the Lightnet blockchian network starting up also launches the archive data tools such as the `Mina archive process`, the `PostgreSQL RDBMS` and the `Archive-Node-API` application. To use fewer resources when your testing does not require the archive data tools, you can start the network without them. To disable the archive data tools use the `--no-archive` option: ```sh $ zk lightnet start --no-archive ``` ### Keep the current product versions New `Docker` images are built and published to the [`Docker Hub`](https://hub.docker.com/r/o1labs/mina-local-network) repository every night. You might not always want to get the latest product versions. For example, when your zkApp relies on the well-defined APIs and you want to continue developing in your current environment. To keep your current working versions of tools provided by the Lightnet, use the `--no-pull` option: ```sh $ zk lightnet start --no-pull ``` ### Start the multi node network You can start the network with multiple participants. Please keep in mind that such the network uses more resources. To start the network in `multi-node` mode with `closer-to-real-world` properties use the following command: ```sh $ zk lightnet start --mode multi-node --type real --proof-level full ``` ### Restart the network for a clean slate To reinstantiate Lightnet to a clean state, stop the network and start it again: ```sh $ zk lightnet stop $ zk lightnet start ``` ## Stop the network To stop the network, remove the Docker container, and clean up the environment use the following command: ```sh $ zk lightnet stop ``` When the Lightnet is being stopped, the log files for Docker container services are saved to the host file system at `${HOME}/.cache/zkapp-cli/lightnet/logs/`. To disable saving of log files you can use the `--no-save-logs` option: ```sh $ zk lightnet stop --no-save-logs ``` ## Configure your zkApp When you first build your zkApp, you test it locally and create the deploy alias as described in [Tutorial 3: Deploy to a Live Network](/zkapps/tutorials/deploying-to-a-network#deploy-alias) to later use it duting zkApp deployment to the public network. With Lightnet the deploy alias is automatically configured to be compatible with the lightweight Mina blockchain network. Now that you have Lightnet running, you can execute a single command to configure your zkApp deploy alias in non-interactive mode: ```sh $ zk config --lightnet ``` No extra steps are required. ## Monitor and troubleshoot the network state Tools that help you monitor and troubleshoot the network state. ### Lightweight Mina explorer To visualize the network state, launch the lightweight Mina explorer with the following command: ```sh $ zk lightnet explorer ``` By default, this command downloads (if needed) and launches the latest version of [lightweight Mina explorer](https://github.com/o1-labs/mina-lightweight-explorer) web application. To list versions, their published dates, and show the version in use: ```sh $ zk lightnet explorer --list ``` To use a specific version of the lightweight Mina explorer: ```sh $ zk lightnet explorer use ``` ### Log files Log files for various processes are saved inside the Docker container as: - `/root/logs/*.log` - `/root/.mina-network/mina-local-network-2-1-1/nodes/**/logs/*.log` To save the log files that are produced by Docker container processes to the host machine file system use the following command: ```sh $ zk lightnet logs save ``` You can stream the Docker container processes logs in real time for debugging and monitoring purposes. Try the following command: ```sh $ zk lightnet logs follow ``` Then select the Docker container process to follow logs for. Press `Ctrl+C` to stop streaming. ### Lightnet status To get the network status use the following command: ```sh $ zk lightnet status ``` The network status is returned, including HTTP endpoints, network propertis and state, code snippet of a zkApp using o1js API, and more. ## Blockchain accounts Each Docker image is packaged with the `genesis ledger` that is configured with `1000` pre-funded accounts with the `1550 MINA` balance on each. The Mina [`accounts manager`](https://github.com/shimkiv/mina-accounts-manager) helper tool provides the random key pair from the genesis ledger. By default it is available at the [http://localhost:8181/](http://localhost:8181/). This endpoint is the same for all users and is available when the Lightnet is up and running. Use HTTP endpoints to manage accounts: ```text HTTP GET: http://localhost:8181/acquire-account Supported Query params: isRegularAccount=, default: true Useful if you need to get non-zkApp account. unlockAccount=, default: false Useful if you need to get unlocked account. Returns JSON account key-pair: { pk:"", sk:"" } ``` ```text HTTP PUT: http://localhost:8181/release-account Accepts JSON account key-pair as request payload: { pk:"", sk:"" } Returns JSON status message ``` ```text HTTP GET: http://localhost:8181/list-acquired-accounts Returns JSON list of acquired accounts key-pairs: [ { pk:"", sk:"" }, ... ] ``` ```text HTTP PUT: http://localhost:8181/lock-account Accepts JSON account key-pair as request payload: { pk:"", sk:"" } Returns JSON status message ``` ```text HTTP PUT: http://localhost:8181/unlock-account Accepts JSON account key-pair as request payload: { pk:"", sk:"" } Returns JSON status message ``` **Pro tip**: the genesis ledger configuration file is named `daemon.json`. You can manually access the Docker container file system to manage this file. In default Lightnet configuration it can be found at `/root/.mina-network/mina-local-network-2-1-1/daemon.json` path. ### Lightnet o1js API namespace The `acquireKeyPair()`, `releaseKeyPair()`, and `listAcquiredKeyPairs()` methods in the `Lightnet` o1js API namespace handle the communication with the running Mina accounts manager helper tool. For details, see the source code comments of the correspointing [namespace](https://github.com/o1-labs/o1js/blob/23cdfa3e17a8e8132b70895d34aab711cebd676f/src/lib/mina/fetch.ts#L804) methods. For the real-world example of using Lightnet and o1js API, see [run-live.ts](https://github.com/o1-labs/o1js/blob/main/src/examples/zkapps/hello-world/run-live.ts) example file. ## Feedback and contributions Share your feedback, submit feature requests, and report issues with Lightnet at the [zkapp-cli GitHub repository](https://github.com/o1-labs/zkapp-cli). Remember to use the `lightnet` label. --- url: /zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-locally --- # Testing zkApps Locally Before you can test your zkApps, create automated tests for your smart contract and test with a simulated local blockchain. Test automation is essential to ensure your code is well-tested during development. ## Writing tests for your smart contract All zkApp projects that are created using the zkApp CLI include the [Jest](https://jestjs.io/) JavaScript testing framework. Although you can use any testing framework, the instructions in this document are supported for Jest. Use the zkApp CLI to create tests for your smart contract. To scaffold a TypeScript file with a corresponding test file, run: - `zk file foo` The `foo.ts` and `foo.test.ts` files are generated. The `foo.test.ts` file is a great place to start writing your smart contract test code. To write valid unit tests, be sure you understand your smart contract functionality. It's good practice to break down the functionality of your smart contract into `describe` blocks to organize your test groupings in the same file. By mapping out your unit tests using the `describe` convention, you provide helpful documentation to developers who read your smart contract. The following example shows the describe block for `test` in the `foo.test.ts` file: ```ts describe('foo.test.ts', () => { describe('test()', () => { // your test here }); }); ``` When you start testing with the Jest testing framework, it is helpful to create `describe` blocks for all areas where your smart contract modifies its state so you can verify that your state updates as expected. For basic test examples that deploy and update the state on a smart contract using Jest, see the [Add.test.ts](https://github.com/o1-labs/zkapp-cli/blob/main/templates/project-ts/src/Add.test.ts) file. You can also find this file inside every new project that is created using `zk project `. ## Running tests To run all test files in your project, run these commands from your project's root directory: - `npm run test` - `npm run testw` for watchmode To generate a test coverage report for your project, run: - `npm run coverage` The code coverage result is output to your terminal and shows the percentage of tested code. ### Creating a simulated local blockchain You can quickly test your smart contract by running it on a simulated local blockchain. The `Mina.LocalBlockchain()` method specifies a mock Mina ledger of accounts and contains logic for updating the ledger that can be used to test your smart contract. ```ts const Local = await Mina.LocalBlockchain(); Mina.setActiveInstance(Local); ``` :::tip To specify whether to generate and verify proofs, you can provide the optional `proofsEnabled` parameter to the `Mina.LocalBlockchain()` method: - `{ proofsEnabled: true }` - default value, the local instance generates and verifies proofs - `{ proofsEnabled: false }` - the local instance does not generate or verify proofs when you want to run tests in the CI or quickly debug your smart contract without waiting for proofs to be generated You can also programmatically enable and disable the `proofsEnabled` flag in your test flow by calling `Local.setProofsEnabled(x: boolean)`. ::: ### Deploying a contract locally The simulated local blockchain contains test accounts you can use to deploy smart contracts and pay transaction fees. First, access a test account provided by the simulated local blockchain. ```ts // Local.testAccounts is an array of 10 test accounts that have been pre-filled with Mina let feePayer = Local.testAccounts[0].key; ``` Next, generate a zkApp account and a new instance of the smart contract to deploy locally for testing. ```ts // zkapp account let zkAppPrivateKey = PrivateKey.random(); let zkAppAddress = zkAppPrivateKey.toPublicKey(); let zkAppInstance = new Add(zkAppAddress); ``` Then, use the test account and zkApp keys to construct a transaction to pay account creation fees and deploy your smart contract. This transaction is sent to the local blockchain. ```ts let txn = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); async zkAppInstance.deploy({ zkappKey: zkAppPrivateKey }); }); const txPromise = await txn.send(); /* `txn.send()` returns a promise with two closures - `.wait()` and `.hash` `.hash` returns the transaction hash, as the name might indicate `.wait()` automatically resolves once the transaction has been included in a block. this is redundant for the LocalBlockchain, but very helpful for live testnets */ await txPromise.wait(); ``` ## Writing integration tests A well-written integration test verifies the flow of expected behavior for your smart contract and confirms the correctness of state updates. After you test the expected behavior, be sure to verify the preconditions of your methods and test the edge cases of your smart contract. The following example is a basic integration test script: ```ts describe('Add smart contract integration test', () => { let feePayer: PrivateKey, zkAppAddress: PublicKey, zkAppPrivateKey: PrivateKey, zkAppInstance: Add, currentState: Field, txn; beforeAll(async () => { // setup local blockchain let Local = await Mina.LocalBlockchain(); Mina.setActiveInstance(Local); // Local.testAccounts is an array of 10 test accounts that have been pre-filled with Mina feePayer = Local.testAccounts[0].key; // zkapp account zkAppPrivateKey = PrivateKey.random(); zkAppAddress = zkAppPrivateKey.toPublicKey(); zkAppInstance = new Add(zkAppAddress); // deploy zkapp txn = await Mina.transaction(feePayer, async () => { AccountUpdate.fundNewAccount(feePayer); await zkAppInstance.deploy(); }); await txn.prove(); // this tx needs .sign(), because `deploy()` adds an account update that requires signature authorization await txn.sign([feePayerKey, zkAppPrivateKey]).send(); }); it('sets intitial state of num to 1', async () => { currentState = zkAppInstance.num.get(); expect(currentState).toEqual(Field(1)); }); it('correctly updates num from intial state to 3', async () => { txn = await Mina.transaction(feePayer, async () => { await zkApp.update(); }); await txn.prove(); await txn.sign([feePayerKeyKey]).send(); currentState = zkAppInstance.num.get(); expect(currentState).toEqual(Field(3)); }); }); ``` ## Learn more See the [Jest Getting Started](https://jestjs.io/docs/getting-started) documentation. ## Next Steps Now that you know how to test a smart contract on a simulated local blockchain, you can move on to [Testing zkApps with Lightnet](/zkapps/writing-a-zkapp/introduction-to-zkapps/testing-zkapps-lightnet) before you learn [how to deploy your zkApp](how-to-deploy-a-zkapp) to public networks. --- url: /zkapps/zkapp-development-frameworks --- :::info To protect end users and ensure your zkApps are secure, consider the information at [Security and zkApps](/zkapps/writing-a-zkapp/introduction-to-zkapps/secure-zkapps) while architecting your solution and consider a third-party security audit before deploying to Mina mainnet. ::: # zkApp Development Frameworks Developers building zkApps in the Mina ecosystem can leverage two different frameworks, each tailored to optimize different types of solutions. Explore the options below to find the perfect fit for your project. If you are unsure about any of the information presented here and need guidance on choosing the most suitable framework for you, drop by [Discord](https://discord.gg/minaprotocol) and let us help! ## [o1js](/zkapps/o1js) o1js is the framework for building **zkApps on the Mina L1** and new infrastructure such as rollups. o1js is TypeScript based for ease of use, comes with a host of built-in features, is extensible to suit various use cases, and takes full advantage of the unique aspects of the Mina protocol. o1js is also the **zkDSL** used for: - Writing general-purpose zk circuits. - Constructing new primitives and data structures. There are some key considerations when choosing to build a zkApp with o1js on Mina L1: - zkApps are subject to protocol throughput limitations. - At present, zkApps that require support for multiple concurrent users require specific architecture to avoid race conditions: - Where more than the eight on-chain field elements are required to manage state, and access to that state is not shared between users, the experimental [Offchain Storage API](/zkapps/writing-a-zkapp/feature-overview/offchain-storage) offers a solution. - Where concurrent access to _shared global state_ is required, the required architecture is available **out of the box** when using the Protokit framework to build your zkApp as an zkApp-chain (L2). There is currently no easy-to-use equivalent for shared state in o1js L1 contracts. Start here: - [Developer documentation](/zkapps/o1js) - [o1js repository](https://github.com/o1-labs/o1js) - [Discord](https://discord.gg/minaprotocol) ## [Protokit](https://protokit.dev/) Protokit is a powerful framework designed to build **ZK appchains and smart contracts** that are user-facing, privacy-preserving, interoperable. It offers a familiar developer experience similar to Solidity dApps, making it easier and intuitive for developers to leverage ZK in their blockchain solutions. It provides a full set of tools necessary for: - zkApps that require high throughput or multiple concurrent users. - zkApps that require shared or global state access. - Developers familiar with execution environments such as EVM. - Developers who wish to leverage the modular architecture of Protokit. Start here: - [Developer documentation](https://protokit.dev/docs/what-is-protokit) - [Protokit repository](https://github.com/proto-kit) - [Starter Kit](https://github.com/proto-kit/starter-kit) - [Discord](https://discord.gg/bEGZTWRy) ## Framework comparison || o1js SmartContract | Protokit | |--|--|--| |**Production readiness**|v1.0 released, internal audit complete, 3rd party audit in progress.|Beta release, internal audit in progress, 3rd party audit not started. Testnet only.| |**Censorship resistance**|Decentralized and censorship resistant.|Censorship resistance via hybrid sequencing model.| |**Support for multi-user apps**|Many multi-user use cases require sophisticated architecture and are limited by L1 throughput.|Capable of handling higher throughput and multiple concurrent users, thanks to Protokit's modular sequencer.| |**Execution environment**|Proving off-chain, verification on-chain, transaction ordering possible on-chain.|Hybrid execution model, both on-chain (sequencer) and off-chain thanks to recursive zk-proofs, verification on-chain (MINA L1).| |**DX**|New programming model, distinct from traditional web3.0 development.|Module oriented app-chain development, similiar to Substrate Pallets, Cosmos SDK Modules or EVM smart contracts.| |**Composability**|Fully composable. Contracts can call other contracts directly within a single transaction.|Protokit supports bi-directional L2 ↔ L1 messaging out of the box.|