探索 Mina 协议:zk 应用程序的实际用例
来源:dev.to
时间:2025-01-14 12:48:53 475浏览 收藏
你在学习文章相关的知识吗?本文《探索 Mina 协议:zk 应用程序的实际用例》,主要介绍的内容就涉及到,如果你想提升自己的开发能力,就不要错过这篇文章,大家要知道编程理论基础和实战操作都是不可或缺的哦!
zkapps(零知识应用)是由零知识证明支持的 mina 协议智能合约,特别是 zk-snarks [零知识简洁非交互式知识论证]。zkapps 取代了 snapps [智能非交互式知识论证]应用]。 zkapp 智能合约是使用 o1js(typescript 库)编写的。 zkapps 在用户的 web 浏览器中运行客户端,并仅发布一个小的有效性证明,然后由 mina 节点进行验证。 zkapp 由智能合约和 ui 组成,我将在下一节中进一步描述。
应用
我创建了关于年龄验证的 zkapp,其中用户年龄在不干预个人数据的情况下得到验证。
我继续安装 zkapp-cli npm 包,它实际上创建了用于继续使用证明器函数和验证器函数的模板,作为 zk 证明构建过程的一部分
执行
下面是添加验证自定义逻辑的实现。它定义了 zk-snark 的电路逻辑,在证明生成过程中使用。实际的证明者函数由 o1js 库管理,并在使用私有输入在链外执行 zkapp 方法时调用。
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); } }
下面的脚本是一个与 ageverification zkapp 交互的测试套件。它在 txn.prove() 期间调用证明者逻辑,并通过检查其更新状态来验证 zkapp 的行为。
实际的证明者功能位于底层的 zkapp 方法(verifyage)中,txn.prove() 是在测试过程中生成证明的机制。
为了测试输入,我编辑了测试脚本,如下所示。
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 }); });
以下是测试结果
我在interact.ts文件中添加了证明者机制,它基本上生成一个zk-snark证明,并在mina区块链中进行交易时提交证明。当 interact.ts 脚本生成证明时,验证是在处理交易时由 mina 区块链执行的。这是 zk-snark 系统的一个关键方面,证明者生成验证者(mina 网络)检查的证明。
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}`; }
我使用的年龄和阈值输入为 25 和 18。
由于测试已通过运行 npm run test 成功完成。我继续使用 zk config 在 devnet 上进行部署
我提供了以下输入:
部署别名:test
网络类型:测试网
网址:https://api.minascan.io/node/devnet/v1/graphql
付费者:新的付费者密钥
交易:0.1
可以从这里检索 url:
然后在部署后我得到了以下响应。
合约部署在以下devnet
部署后,我继续使用 ui,通过提供 rpc url 和部署的合约地址,选择简单的 html、css 和 js,这是最终的 ui。
将智能合约与ui集成后zkapp的创建就完成了。在为 ageverification zkapp 构建用户界面 (ui) 后,前端与智能合约的集成允许用户与零知识证明系统无缝交互。 ui 有助于向合约提交用户年龄和阈值数据,同时通过 zk-snark 维护隐私。这使得用户能够在不透露实际值的情况下验证自己的年龄,从而保持机密性。后端利用证明者功能生成证明,mina 区块链对其进行有效验证。这种端到端解决方案可确保安全、用户友好的体验,同时充分利用 mina 基于 zk-snark 的架构提供的隐私和可扩展性功能。
好了,本文到此结束,带大家了解了《探索 Mina 协议:zk 应用程序的实际用例》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
474 收藏
-
410 收藏
-
225 收藏
-
449 收藏
-
466 收藏
-
226 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习