如何在Solana上使用Elusiv的零知识证明启用代币隐私

  • QuickNode
  • 发布于 2025-01-30 13:42
  • 阅读 24

本文介绍了Elusiv平台如何利用零知识证明在Solana上实现私密交易。详细说明了使用Elusiv SDK创建私密代币转账的步骤,包括环境配置、创建新的密钥对、连接Solana集群等。最后,文章强调了保护用户隐私对Web3技术普及的重要性,并提供了相关资源链接。

Elusiv 结束

在2024年2月29日,Elusiv 宣布 将结束 Elusiv 平台。该协议将保持在仅限提取模式,直到2025年1月1日。

概述

Web3 技术 adoption 的一个常见障碍是对隐私的需求。区块链交易是公开的,这意味着任何人都可以查看交易的细节,包括发送者和接收者。虽然在许多情况下,这种透明性是有益的,但也有许多案例需要用户的隐私。例如,如果你是一个企业主,你可能不希望你的竞争对手知道你支付给员工的薪水。然而,如果你是一个用户,可能希望让朋友不知道你投资了多少。随着Web3吸引更多用户和用例,隐私将变得越来越重要。

在 Solana 上,一些协议正在出现以便实现私密交易。在本指南中,我们将介绍如何使用 Elusiv,一个基于 Solana 的零知识 (ZK) 隐私协议,来创建一个私密的 SPL 代币转账。

你将做什么

在本指南中,你将:

  1. 了解 Elusiv,一个基于 Solana 的零知识 (ZK) 隐私协议
  2. 使用 Elusiv SDK 创建一个私密的 USDC 转账
  3. 验证该交易是否是私密的

你需要准备

什么是 Elusiv?

在 Solana 上的交易是公开的。任何具备 Explorer 权限和用户公钥的人都可以追踪和监控该用户的交易活动。Elusiv 旨在打破发送者和接收者之间的联系,以实现私密交易。Elusiv 是一个基于 Solana 的隐私协议,采用零知识加密技术。该协议使用户和应用程序能够访问通用加密和控制,允许他们选择分享什么以及不分享什么。Elusiv 利用 zk-SNARKS 来进行私密交易和去中心化合规解决方案。

Elusiv 主要有两个功能:

  • Elusiv 程序:Elusiv 通过管理一个由 Elusiv 程序管控的共享池来运作。用户可以存入和提取池中的资金(公开交易),然后在池内向其他用户转移资金(私密交易)。虽然交易细节对支付发起者是私密的,但发起者可以创建查看密钥,以允许他人查看特定交易。
  • Elusiv Warden:Elusiv Warden 负责将客户端请求转发至网络,并(在未来)将负责管理基于合规的任务(例如,防止黑名单地址进行交易)。

Elusiv 创建了一个简单的应用程序,展示该技术,使你能创建私密的代币转账。可以访问 https://app.elusiv.io/ 查看。

Elusiv 应用

让我们来看看 Elusiv SDK,了解如何将此功能集成到我们的应用程序中。

创建新项目

mkdir elusiv-demo && cd elusiv-demo && echo > app.ts

安装 Solana Web3 依赖:

yarn init -y
yarn add @solana/web3.js@1 @solana/spl-token @elusiv/sdk @noble/ed25519

或者

npm init -y
npm install --save @solana/web3.js@1 @solana/spl-token @elusiv/sdk @noble/ed25519

导入依赖

打开你选择的代码编辑器中的 app.ts,在第1行导入以下内容:

import { Connection, Keypair } from '@solana/web3.js';
import { createAssociatedTokenAccountIdempotent } from '@solana/spl-token';
import { airdropToken, Elusiv, getTokenInfo, SEED_MESSAGE } from '@elusiv/sdk';
import { sign } from '@noble/ed25519';

这些导入将允许我们连接到 Solana 网络、创建一个代币,并与 Elusiv SDK 进行交互。我们将在后面的指南中详细介绍每个元素。

创建新的 Keypair

首先,我们需要一个新的 Keypair 来进行演示。使用下面的小部件生成一个,并将输出复制/粘贴到你的代码编辑器中。

🔑生成一个新的 Devnet SOL 钱包

创建新钱包

你应该会看到类似这样的内容——确保包含从小部件生成的私钥:

const secret = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]; // 在此处粘贴你的密钥
const keyPair = Keypair.fromSecretKey(new Uint8Array(secret));

你需要用一些 devnet SOL 为该账户提供资金,以便在 devnet 上运行交易。你可以通过访问 Solana Faucet 并粘贴你的新公钥,或者在终端中输入以下命令来进行:

solana airdrop 1 <your public key> -ud

如果你需要帮助,可以参考我们 关于给 Devnet SOL 空投的完整指南

使用你的 QuickNode 端点连接到 Solana 集群

要在 Solana 上构建,你需要一个 API 端点以连接到网络。你可以使用公共节点,或部署和管理自己的基础设施;但是,如果你希望响应时间快8倍,你可以将繁重的工作留给我们。

了解为何超过50%的 Solana 项目选择 QuickNode,并在 这里 注册获取免费账户。我们将使用 Solana Devnet 端点。

复制 HTTP 提供者链接:

然后使用以下代码连接到 Solana 网络:

const cluster = 'devnet';
const quickNodeEndpoint = 'https://example.solana.quiknode.pro/012345' // 👈 用你的端点替换这个
const connection = new Connection(quickNodeEndpoint);

框架应用程序

接下来,创建一个 main 函数,并在文件底部调用它。这将是我们编写代码的地方。

async function main() {
    // 代码在这里
}

main()
    .catch(err => console.error(err))
    .finally(() => process.exit());

很好。我们已经准备好开始构建我们的应用程序。

构建应用程序

在我们的 main 函数中,我们将创建六个步骤,演示如何使用 Elusiv SDK:

  1. 创建一个 Elusiv 实例
  2. 向我们的 devnet USDC 关联代币账户空投一些 "USDC"
  3. 检查我们的私密余额
  4. 如有需要,补充私密余额
  5. 私密地将一些 USDC 发送到一个随机地址
  6. 验证我们的 keypair 是否在交易中

创建 Elusiv 实例

Elusiv SDK 允许我们通过传递 seed、公钥、Solana 连接和集群来创建 Elusiv 程序的实例。

main 中,添加步骤 1:

    // 步骤 1 - 创建 Elusiv 实例
    console.log('1. 创建 Elusiv 实例');
    const seed = await sign(
        Buffer.from(SEED_MESSAGE, 'utf-8'),
        keyPair.secretKey.slice(0, 32),
    );
    const elusiv = await Elusiv.getElusivInstance(seed, keyPair.publicKey, connection, cluster);

如果你遇到 etc.sha512Sync not set 错误,请参考 Elusiv SDK 文档2. 基本用法 部分。 我们生成的 seed 是通过签名从 Elusiv SDK 导入的常量生成的。这个种子允许任何人解密并支出用户的私密资产,因此在生产中要小心处理。

我们将 Elusiv 的实例保存为 elusiv,以便我们在应用程序中使用它。

空投开发 USDC

Elusiv SDK 有一些方便的测试工具用于空投 SPL 代币。因为我们将测试一个私密的 USDC 转账,我们需要一些 devnet USDC 来进行演示。在你的 main 函数中添加步骤 2:

    // 步骤 2 - 向我们的 devnet USDC 关联代币账户空投一些 "USDC"
    console.log('2. 空投 USDC');
    const usdcInfo = getTokenInfo('USDC');
    const oneUsdc = 10 ** usdcInfo.decimals;
    const usdcMint = usdcInfo.mintDevnet;

    const ataAcc = await createAssociatedTokenAccountIdempotent(
        connection,
        keyPair,
        usdcMint,
        keyPair.publicKey,
        { commitment: 'finalized' }
    );
    await airdropToken(
        'USDC',
        1000 * oneUsdc,
        ataAcc,
    );

在空投 USDC 之前,我们必须首先确定铸造地址,然后为我们的 keypair 创建(或获取)一个关联代币账户 (ATA)。

  • Elusiv 有一个助手函数 getTokenInfo,会为其协议支持的给定代币获取代币详情(例如,主网和 devnet 上的铸造地址、小数等)。我们用它来获取 devnet 上 USDC 的铸造地址和与该代币铸造相关的小数位数。
  • 我们将 oneUsdc 定义为 10 的小数位数的幂。这将使我们能够轻松计算转账金额,而无需担心小数位问题。
  • 然后将该铸造地址传递给一个 SPL 代币助手函数 createAssociatedTokenAccountIdempotent。如果需要,该函数将创建一个新的 ATA,并返回该 ATA 的公钥。有关 ATA 的更多信息,请查看我们的 指南:如何查找 Solana 钱包和铸造的关联代币地址
  • 我们将代币、金额和新 ATA 传递给另一个 Elusiv 工具函数 airdropToken。这将向 ATA 空投 1,000 USDC。

检查私密余额

在继续之前,让我们检查一下我们的私密账户余额(还应为 0,因为我们还没有做任何操作)。在你的 main 函数中添加步骤 3:

    // 步骤 3 - 检查我们的私密余额
    console.log('3. 检查私密余额');
    let privateBalance = await elusiv.getLatestPrivateBalance('USDC');

Elusiv 协议处理使用我们之前创建的 Elusiv 实例的私密余额解密。

补充私密余额

由于我们在初始测试中没有私密余额,因此让我们为我们的私密余额账户存款(或“补充”)。

    // 步骤 4 - 如有需要,补充私密余额
    if (privateBalance === BigInt(0)) {
        console.log('4. 补充私密余额');
        const topupTx = await elusiv.buildTopUpTx(500 * oneUsdc, 'USDC');
        topupTx.tx.partialSign(keyPair);
        await elusiv.sendElusivTx(topupTx);
        privateBalance = await elusiv.getLatestPrivateBalance('USDC');
    } else {
        console.log('4. 私密余额不需要补充。当前余额:', (privateBalance / BigInt(10 ** usdcInfo.decimals)).toString());
    }

让我们分析一下:

  • 首先,我们验证余额为 0。如果不是,我们将跳过此步骤。
  • 然后,我们使用 Elusiv 的 buildTopUpTx 函数创建一个将 500 USDC 充入私密余额的交易。
  • 我们使用我们的 keypair 部分签名该交易。
  • 最后,我们将交易发送到网络并获取最新的私密余额。

私密发送 USDC

在步骤 4 之后,我们的私密账户中应有正余额。让我们使用它发送一个私密交易。我们将在你的 main 函数中添加步骤 5:

    // 步骤 5 - 将一些 USDC 发送到一个随机地址
    console.log('5. 向随机地址发送 USDC');
    if (privateBalance <= BigInt(0)) {
        throw new Error("不能从空私密余额发送");
    }

    const sendTx = await elusiv.buildSendTx(10 * oneUsdc, Keypair.generate().publicKey, 'USDC');
    const sig = await elusiv.sendElusivTx(sendTx);

    console.log(`   https://explorer.solana.com/tx/${sig.signature}?cluster=${cluster}`);

首先,我们再次确认私密账户中确实有正余额。如果没有,我们抛出一个错误。接下来,我们使用 Elusiv 的 buildSendTx 函数创建一个将 10 USDC 发送到随机地址的交易。然后将交易发送到网络,并在控制台中记录交易的 URL。

到此为止,我们已经成功发送了一笔私密交易。干得好!

验证交易

让我们再添加一个额外的步骤检查我们的交易是否是私密的。我们将使用 Solana Web3 SDK 的 getTransaction 方法,然后解析结果。在你的 main 函数中添加步骤 6:

    // 步骤 6 - 检查我们的 keypair 是否在交易中
    console.log('6. 检查我们的 keypair 是否在交易中');
    const txDetail = await connection.getTransaction(sig.signature, {
        commitment: 'confirmed',
        maxSupportedTransactionVersion: 0
    });
    const readonly = txDetail?.meta?.loadedAddresses?.readonly ?? [];
    const writable = txDetail?.meta?.loadedAddresses?.writable ?? [];
    const allAccounts = [...new Set([...readonly, ...writable])];
    const isSenderInTx = allAccounts.some(pubKey => pubKey.toBase58() === keyPair.publicKey.toBase58());
    if (isSenderInTx) {
        console.log('❌ - 我们的 Keypair 在交易中(意外)');
    } else {
        console.log('✅ - 我们的 Keypair 不在交易中(预期)');
    }

让我们逐步分析这段新代码:

  • 首先,我们调用我们私人转账的交易签名上的 getTransaction 方法。这将返回交易细节。
  • 接下来,我们解析交易细节,以获取在交易过程中加载到内存中的账户列表。我们获取 readonlywritable 账户,然后将它们组合成一个包含交易中所有公钥的数组。
  • 最后,我们使用 .some 检查我们的发送者密钥是否在交易中。我们期望发送者密钥不在交易中,因此如果不在,我们记录一条成功消息。如果在,我们记录一条错误消息。

运行应用程序

现在我们已经构建了我们的应用程序,让我们运行它。在你的终端中输入:

ts-node app.ts

你应该会看到类似这样的内容:

qn elusiv-demo % ts-node app
1. 创建 Elusiv 实例
2. 空投 USDC
3. 检查私密余额
4. 私密余额不需要补充。当前余额:  359777742
5. 向随机地址发送 USDC
   https://explorer.solana.com/tx/5fP4TvgCbYMWFRaQuzikmwovSgJWJM7F7c59kKMP82BJjgDurUPdwH49gbJxhhcjWHH1bxbxeYRorw9j6QFRE7HD?cluster=devnet
6. 检查我们的 keypair 是否在交易中
✅ - 我们的 Keypair 不在交易中(预期)

注意:如果你遇到 etc.sha512Sync not set 错误,请参考 Elusiv SDK 文档2. 基本用法 部分。

如果在最后看到成功消息,你已经成功使用 Elusiv SDK 在 Solana 上发送了私密交易。你应该能够在 Solana Explorer 中浏览该交易,并重新检查我们的付款钱包未与交易关联。做得好!

总结

在你的 dapp 中启用私密交易是保护用户隐私和减少 Web3 技术采纳障碍的好方法。Elusiv 使集成此功能变得简单。我们迫不及待想看看你会有什么新创意!

如果你有问题或想分享的想法,请在 DiscordTwitter 上给我们留言!

我们 ❤️ 反馈!

让我们知道 如果你有任何反馈或对新主题的请求。我们很想听到你的声音。

资源

  • 原文链接: quicknode.com/guides/sol...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。