Home Web Front-end JS Tutorial Exploring the Mina Protocol: Practical Use Cases for zk Applications

Exploring the Mina Protocol: Practical Use Cases for zk Applications

Dec 29, 2024 am 07:32 AM

Zkapps (zero knowledge applications) are mina protocol smart contracts which are powered by zero knowledge proofs, specifically zk-Snarks [Zero-Knowledge Succinct Non-Interactive Argument of Knowledge].zkapps replaced snapps [Smart Non-Interactive Argument of Knowledge Applications]. ZkApp smart contracts are written using o1js (a TypeScript library). zkApps runs client side in a user’s web browser, and publish only a small validity proof which is then verified by the Mina nodes. Zkapp consists of smart contract and UI which I will further describe in the next section.

Application

I created zkapp regarding age verification where the user age gets validated without intervention to the personal data.

I proceeded by installing zkapp-cli npm package which actually created templates for proceeding with prover function and verifier function as part of the zk proof build process

Implementation

Below is the implementation of adding verification custom logic. It defines the circuit logic for zk-SNARKs, which is used during proof generation. The actual prover function is managed by the o1js library and invoked when zkApp methods are executed off-chain with private inputs.

import { Field, SmartContract, state, State, method } from 'o1js';

/**
 * Private Age Verification Contract
 * The contract will verify if the user's age is greater than or equal to the threshold age.
 * The contract uses zero-knowledge proofs to keep the user's age private.
 */
export class AgeVerification extends SmartContract {
  // State variable to store the verification result (valid or invalid)
  @state(Field) valid = State<Field>();

  // Method to initialize the state
  init() {
    super.init();
    this.valid.set(Field(0)); // Default is invalid
  }

  // Method to verify the age
  @method async verifyAge(age: Field, threshold: Field) {


    // Compute age - threshold
    const difference = age.sub(threshold);

    // Use circuit-compatible logic to check if the difference is non-negative
    const isValid = difference.equals(Field(0)).or(difference.greaterThanOrEqual(Field(0)))
      ? Field(1)
      : Field(0);

    // Set the validity of the verification result
    this.valid.set(isValid);
  }
}


Copy after login

The below script is a test suite that interacts with the AgeVerification zkApp. It invokes the prover logic during txn.prove() and verifies the zkApp's behavior by checking its updated state.

The actual prover function lies in the underlying zkApp method (verifyAge), and txn.prove() is the mechanism to generate the proof during testing.

To test the inputs I have edited the test script as follows.

import { AccountUpdate, Field, Mina, PrivateKey, PublicKey } from 'o1js';
import { AgeVerification } from './AgeVerification'; // Import the correct contract

let proofsEnabled = false;

describe('AgeVerification', () => {
  let deployerAccount: Mina.TestPublicKey,
    deployerKey: PrivateKey,
    senderAccount: Mina.TestPublicKey,
    senderKey: PrivateKey,
    zkAppAddress: PublicKey,
    zkAppPrivateKey: PrivateKey,
    zkApp: AgeVerification; // Update to use AgeVerification instead of Add

  beforeAll(async () => {
    if (proofsEnabled) await AgeVerification.compile(); // Update compile for AgeVerification
  });

  beforeEach(async () => {
    const Local = await Mina.LocalBlockchain({ proofsEnabled });
    Mina.setActiveInstance(Local);
    [deployerAccount, senderAccount] = Local.testAccounts;
    let feePayer = Local.testAccounts[0].key;
    deployerKey = deployerAccount.key;
    senderKey = senderAccount.key;

    zkAppPrivateKey = PrivateKey.random();
    zkAppAddress = zkAppPrivateKey.toPublicKey();
    zkApp = new AgeVerification(zkAppAddress); // Instantiate AgeVerification contract
  });



  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 `AgeVerification` smart contract', async () => {
    await localDeploy();
    const valid = zkApp.valid.get(); // Access the 'valid' state variable
    expect(valid).toEqual(Field(0)); // Initially, the contract should set 'valid' to Field(0)
  });

  it('correctly verifies the age in the `AgeVerification` smart contract', async () => {
    await localDeploy();

    const age = Field(25); // Example age value
    const threshold = Field(18); // Example threshold value

    // Call the verifyAge method
    const txn = await Mina.transaction(senderAccount, async () => {
      await zkApp.verifyAge(age, threshold); // Use the verifyAge method
    });
    await txn.prove();
    await txn.sign([senderKey]).send();

    const valid = zkApp.valid.get(); // Check the validity state after verification
    expect(valid).toEqual(Field(1)); // Expected to be valid if age >= threshold
  });
});


Copy after login

Below is the testing result

Exploring the Mina Protocol: Practical Use Cases for zk Applications

I have added the prover mechanism in interact.ts file which basically generates a zk-SNARK proof and submits the proof when it goes for transaction in mina blockchain. While the interact.ts script generates the proof, the verification is performed by the Mina blockchain when the transaction is processed. This is a key aspect of zk-SNARK systems that the prover generates a proof that the verifier (Mina network) checks.

import fs from 'fs/promises';
import { Mina, NetworkId, PrivateKey, Field } from 'o1js';
import { AgeVerification } from './AgeVerification'; 

// check command line arg
let deployAlias = process.argv[2];
if (!deployAlias)
  throw Error(`Missing <deployAlias> argument.

Usage:
node build/src/interact.js <deployAlias>
`);
Error.stackTraceLimit = 1000;
const DEFAULT_NETWORK_ID = 'testnet';

// parse config and private key from file
type Config = {
  deployAliases: Record<
    string,
    {
      networkId?: string;
      url: string;
      keyPath: string;
      fee: string;
      feepayerKeyPath: string;
      feepayerAlias: string;
    }
  >;
};
let configJson: Config = JSON.parse(await fs.readFile('config.json', 'utf8'));
let config = configJson.deployAliases[deployAlias];
let feepayerKeysBase58: { privateKey: string; publicKey: string } = JSON.parse(
  await fs.readFile(config.feepayerKeyPath, 'utf8')
);

let zkAppKeysBase58: { privateKey: string; publicKey: string } = JSON.parse(
  await fs.readFile(config.keyPath, 'utf8')
);

let feepayerKey = PrivateKey.fromBase58(feepayerKeysBase58.privateKey);
let zkAppKey = PrivateKey.fromBase58(zkAppKeysBase58.privateKey);

// set up Mina instance and contract we interact with
const Network = Mina.Network({
  // We need to default to the testnet networkId if none is specified for this deploy alias in config.json
  // This is to ensure the backward compatibility.
  networkId: (config.networkId ?? DEFAULT_NETWORK_ID) as NetworkId,
  mina: config.url,
});

const fee = Number(config.fee) * 1e9; // in nanomina (1 billion = 1.0 mina)
Mina.setActiveInstance(Network);
let feepayerAddress = feepayerKey.toPublicKey();
let zkAppAddress = zkAppKey.toPublicKey();
let zkApp = new AgeVerification(zkAppAddress);

let age = Field(25); // Example age
let threshold = Field(18); // Example threshold age

// compile the contract to create prover keys
console.log('compile the contract...');
await AgeVerification.compile();

try {
  // call verifyAge() and send transaction
  console.log('build transaction and create proof...');
  let tx = await Mina.transaction(
    { sender: feepayerAddress, fee },
    async () => {
      await zkApp.verifyAge(age, threshold); // Replacing update() with verifyAge
    }
  );
  await tx.prove();

  console.log('send transaction...');
  const sentTx = await tx.sign([feepayerKey]).send();
  if (sentTx.status === 'pending') {
    console.log(
      '\nSuccess! Age verification transaction sent.\n' +
        '\nYour smart contract state will be updated' +
        `\nas soon as the transaction is included in a block:` +
        `\n${getTxnUrl(config.url, sentTx.hash)}`
    );
  }
} catch (err) {
  console.log(err);
}

function getTxnUrl(graphQlUrl: string, txnHash: string | undefined) {
  const hostName = new URL(graphQlUrl).hostname;
  const txnBroadcastServiceName = hostName
    .split('.')
    .filter((item) => item === 'minascan')?.[0];
  const networkName = graphQlUrl
    .split('/')
    .filter((item) => item === 'mainnet' || item === 'devnet')?.[0];
  if (txnBroadcastServiceName && networkName) {
    return `https://minascan.io/${networkName}/tx/${txnHash}?type=zk-tx`;
  }
  return `Transaction hash: ${txnHash}`;
}


Copy after login

I have used inputs for age and threshold as 25 and 18.

Since testing has been done successfully by running npm run test. I proceeded with deploying on devnet by using zk config

Where I provided following inputs:

Deploy alias: test
Network kind: testnet
URL: https://api.minascan.io/node/devnet/v1/graphql
Feepayer: New feepayer keys
Transaction: 0.1

The URL can be retrieved from here:

Exploring the Mina Protocol: Practical Use Cases for zk Applications

Then upon deployment I got the following response.

Exploring the Mina Protocol: Practical Use Cases for zk Applications

Exploring the Mina Protocol: Practical Use Cases for zk Applications

The contract is deployed at the following devnet

After deployment I proceeded with UI where I chose simple html, css and js by giving my RPC URL and deployed contract address and this is the final UI.

Exploring the Mina Protocol: Practical Use Cases for zk Applications

This concludes the creation of zkapp after integrating smart contract with UI. After building the user interface (UI) for the AgeVerification zkApp, the integration of the frontend with the smart contract allows users to interact seamlessly with the zero-knowledge proof system. The UI facilitates the submission of user age and threshold data to the contract, while maintaining privacy through zk-SNARKs. This enables users to verify their age without revealing the actual value, preserving confidentiality. The backend, utilizing the prover function, generates the proof, and the Mina blockchain verifies it efficiently. This end-to-end solution ensures a secure, user-friendly experience while taking full advantage of the privacy and scalability features offered by Mina's zk-SNARK-based architecture.

The above is the detailed content of Exploring the Mina Protocol: Practical Use Cases for zk Applications. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1675
14
PHP Tutorial
1278
29
C# Tutorial
1257
24
Python vs. JavaScript: The Learning Curve and Ease of Use Python vs. JavaScript: The Learning Curve and Ease of Use Apr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

JavaScript and the Web: Core Functionality and Use Cases JavaScript and the Web: Core Functionality and Use Cases Apr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript in Action: Real-World Examples and Projects JavaScript in Action: Real-World Examples and Projects Apr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

Understanding the JavaScript Engine: Implementation Details Understanding the JavaScript Engine: Implementation Details Apr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: Community, Libraries, and Resources Python vs. JavaScript: Community, Libraries, and Resources Apr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

Python vs. JavaScript: Development Environments and Tools Python vs. JavaScript: Development Environments and Tools Apr 26, 2025 am 12:09 AM

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

The Role of C/C   in JavaScript Interpreters and Compilers The Role of C/C in JavaScript Interpreters and Compilers Apr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

Python vs. JavaScript: Use Cases and Applications Compared Python vs. JavaScript: Use Cases and Applications Compared Apr 21, 2025 am 12:01 AM

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

See all articles