Zkapps(零知識應(yīng)用)是由零知識證明支持的 mina 協(xié)議智能合約,特別是 zk-Snarks [零知識簡潔非互動式知識論證]。 zkapps 取代了 snapps [智慧非互動式知識論證]應(yīng)用]。 ZkApp 智能合約是使用 o1js(一個(gè) TypeScript 函式庫)編寫的。 zkApps 在使用者的 Web 瀏覽器中執(zhí)行客戶端,並僅發(fā)布一個(gè)小的有效性證明,然後由 Mina 節(jié)點(diǎn)進(jìn)行驗(yàn)證。 Zkapp 由智能合約和 UI 組成,我將在下一節(jié)中進(jìn)一步描述。
應(yīng)用
我創(chuàng)建了關(guān)於年齡驗(yàn)證的 zkapp,其中使用者年齡在不干預(yù)個(gè)人資料的情況下得到驗(yàn)證。
我繼續(xù)安裝 zkapp-cli npm 包,它實(shí)際上創(chuàng)建了用於繼續(xù)使用證明器函數(shù)和驗(yàn)證器函數(shù)的模板,作為 zk 證明構(gòu)建過程的一部分
執(zhí)行
以下是新增驗(yàn)證自訂邏輯的實(shí)作。它定義了 zk-SNARK 的電路邏輯,在證明產(chǎn)生過程中使用。實(shí)際的證明者函數(shù)由 o1js 函式庫管理,並在使用私有輸入在鏈外執(zhí)行 zkApp 方法時(shí)呼叫。
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() 期間呼叫證明者邏輯,並透過檢查其更新狀態(tài)來驗(yàn)證 zkApp 的行為。
實(shí)際的證明者功能位於底層的 zkApp 方法(verifyAge)中,txn.prove() 是在測試過程中產(chǎn)生證明的機(jī)制。
為了測試輸入,我編輯了測試腳本,如下所示。
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 }); });
以下是測試結(jié)果
我在interact.ts檔案中加入了證明者機(jī)制,它基本上產(chǎn)生一個(gè)zk-SNARK證明,並在mina區(qū)塊鏈中進(jìn)行交易時(shí)提交證明。當(dāng) interact.ts 腳本產(chǎn)生證明時(shí),驗(yàn)證是在處理交易時(shí)由 Mina 區(qū)塊鏈執(zhí)行的。這是 zk-SNARK 系統(tǒng)的關(guān)鍵方面,證明者產(chǎn)生驗(yàn)證者(Mina 網(wǎng)路)檢查的證明。
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。
由於測試已透過執(zhí)行 npm run test 成功完成。我繼續(xù)使用 zk config 在 devnet 上部署
我提供了以下輸入:
部署別名:test
網(wǎng)路類型:測試網(wǎng)
網(wǎng)址:https://api.minascan.io/node/devnet/v1/graphql
付費(fèi)者:新的付費(fèi)者金鑰
交易:0.1
可以從這裡檢索 URL:
然後在部署後我得到了以下回應(yīng)。
合約部署在以下devnet
部署後,我繼續(xù)使用 UI,透過提供 RPC URL 和部署的合約位址,選擇簡單的 html、css 和 js,這是最終的 UI。
將智能合約與UI整合後zkapp的創(chuàng)建就完成了。在為 AgeVerification zkApp 建立使用者介面 (UI) 後,前端與智慧合約的整合允許使用者與零知識證明系統(tǒng)無縫互動。 UI 有助於向合約提交用戶年齡和閾值數(shù)據(jù),同時(shí)透過 zk-SNARK 維護(hù)隱私。這使得用戶能夠在不透露實(shí)際值的情況下驗(yàn)證自己的年齡,從而保持機(jī)密性。後端利用證明者功能產(chǎn)生證明,Mina 區(qū)塊鏈對其進(jìn)行有效驗(yàn)證。這種端對端解決方案可確保安全性、使用者友好的體驗(yàn),同時(shí)充分利用 Mina 基於 zk-SNARK 的架構(gòu)提供的隱私和可擴(kuò)展性功能。
以上是探索 Mina 協(xié)定:zk 應(yīng)用程式的實(shí)際用例的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

在JavaScript中,選擇單行註釋(//)還是多行註釋(//)取決於註釋的目的和項(xiàng)目需求:1.使用單行註釋進(jìn)行快速、內(nèi)聯(lián)的解釋;2.使用多行註釋進(jìn)行詳細(xì)的文檔說明;3.保持註釋風(fēng)格的一致性;4.避免過度註釋;5.確保註釋與代碼同步更新。選擇合適的註釋風(fēng)格有助於提高代碼的可讀性和可維護(hù)性。

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

評論arecrucialinjavascriptformaintainingclarityclarityandfosteringCollaboration.1)heelpindebugging,登機(jī),andOnderStandingCodeeVolution.2)使用林格forquickexexplanations andmentmentsmmentsmmentsmments andmmentsfordeffordEffordEffordEffordEffordEffordEffordEffordEddeScriptions.3)bestcractices.3)bestcracticesincracticesinclud

JavaScripthasseveralprimitivedatatypes:Number,String,Boolean,Undefined,Null,Symbol,andBigInt,andnon-primitivetypeslikeObjectandArray.Understandingtheseiscrucialforwritingefficient,bug-freecode:1)Numberusesa64-bitformat,leadingtofloating-pointissuesli

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時(shí)區(qū)問題建議使用支持時(shí)區(qū)的庫,如Luxon。掌握這些要點(diǎn)能有效避免常見錯誤。

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)
