跳至主要內容

如何透過 Elusiv 的零知識證明在 Solana 上啟用代幣隱私功能

更新於
2026年1月30日

閱讀時間 10 分鐘

Elusiv 即將停用

2024年2月29日,Elusiv宣布將逐步停用 Elusiv 平台。本指南僅供歷史性教育參考之用。

若想了解現代化的替代方案,請參閱《Solana 上的保密轉帳:Token-2022開發者指南》

概覽

Web3 技術普及的一大障礙,在於對隱私需求的增加。區塊鏈交易是公開的,這意味著任何人都能查看交易的詳細資訊,包括發送方和接收方。雖然在許多應用場景中,這種透明度是有益的,但在許多情況下,使用者仍需要隱私。 舉例來說,若您是企業主,可能不希望競爭對手知道您支付給員工的薪資金額;又或者,若您是一般使用者,可能希望避免讓朋友知道您的投資金額。隨著 Web3 觸及更多使用者與應用場景,隱私的重要性將日益提升。

Solana 平台上正陸續出現數種旨在實現隱私交易的協議。在本指南中,我們將逐步說明如何使用 Elusiv——一款基於 Solana 的零知識(ZK)隱私協議——來進行隱私的 SPL 代幣轉帳。

您將負責的工作內容

在本指南中,您將:

  1. 了解 Elusiv——一款基於 Solana 的零知識(ZK)隱私協定
  2. 使用 Elusiv SDK 建立一筆私密的 USDC 轉帳
  3. 確認該交易是否為私下交易

您需要準備的物品

什麼是 Elusiv?

Solana 上的交易是公開的。任何能夠存取區塊鏈瀏覽器並持有使用者公鑰的人,都能追蹤和監控該使用者的交易活動。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 依賴項:

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

npm init -y
npm 安裝 --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 進行互動。本指南後續將更詳細地說明各個項目。

建立新的金鑰對

首先,我們需要一組新的金鑰對來進行示範。請使用下方的工具產生一組金鑰對,並將生成的內容複製並貼上至您的程式碼編輯器中。

🔑使用 Devnet SOL建立新的錢包

您應該會看到類似以下的內容——請務必包含由小工具生成的密鑰:

const secret = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...]; // 請在此處貼上您的密鑰
const keyPair = Keypair.fromSecretKey(new Uint8Array(secret));

您需要向帳戶存入一些開發網(devnet)的 SOL,才能在開發網執行交易。您可以透過造訪Solana Faucet並貼上您的新公鑰,或在終端機中輸入以下指令來完成此操作:

solana airdrop 1 <your public key> -ud 

如果您需要協助,請參閱我們關於 Devnet SOL 空投的完整指南

使用您的 Quicknode 端點連線至 Solana 叢集

若要在 Solana 上進行開發,您需要一個 API 端點來連線至該網路。您可以使用公開節點,或自行部署並管理基礎架構;不過,若您希望將回應時間縮短 8 倍,不妨將繁重的工作交給我們處理。

了解為何在 索拉納 選擇 Quicknode,立即開始免費試用 這裡. 我們將使用一個 索拉納 Devnet 終點。

複製該 HTTP 服務提供者連結:

接著,請使用以下程式碼透過它連線至 Solana 網路:

const 叢集 = 'devnet';
const 快速節點端點 = 'https://example.solana.quiknode.pro/012345' // 👈 請將此處替換為您的端點
const connection = new Connection(快速節點端點);

建立應用程式框架

接下來,建立一個 主頁 函式,並在檔案底部呼叫它。這裡就是我們將撰寫程式碼的地方。

async function main() {
// code goes here
}

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

太好了。我們已經準備好要開始開發我們的應用程式了。

建置應用程式

在我們的 主頁 功能,我們將透過六個步驟來示範如何使用 Elusiv SDK:

  1. 建立一個 Elusiv 實例
  2. 將一些「USDC」空投至我們的開發網(devnet)中與 USDC 相關的代幣帳戶
  3. 查詢我們的私人帳戶餘額
  4. 如有需要,請為私人帳戶儲值
  5. 將一些 USDC 私下轉帳至一個隨機地址
  6. 確認我們的金鑰對並未包含在該交易中

建立一個 Elusiv 實例

透過傳入種子、公鑰、Solana 連線及叢集,我們便能使用 Elusiv SDK 建立Elusiv程式的實例。

內頁 主頁, 新增步驟 1:

    // 步驟 1 - 建立一個 Elusiv 實例
控制台.log('1. 建立 Elusiv 實例');
const seed = await sign(
Buffer.來自(SEED_MESSAGE, 'utf-8'),
keyPair.secretKey.slice(0, 32),
);
const elusiv = await Elusiv.getElusivInstance(種子, keyPair.publicKey, connection, 叢集);

請參閱 2. 基本用法 關於 Elusiv SDK 文件 如果你遇到一個 etc.sha512Sync 未設定 錯誤。 該 種子 我們所產生的密鑰,是透過簽署從 Elusiv SDK 匯入的常數所生成。此種子會讓任何人都能解密並動用使用者的私人資產,因此在正式環境中請務必謹慎處理。

我們將我們的 Elusiv 作為 elusiv 這樣我們就能在整個應用程式中使用它。

USDC 空投開發版

Elusiv SDK 提供了一些方便的測試工具,可用於釋放 SPL 代幣。由於我們將測試 USDC 的私有轉帳,因此需要一些開發網(devnet)上的 USDC 來進行示範。請將「步驟 2」加入您的 主頁 函式:

    // Step 2 - Airdrop some "USDC" to our devnet USDC associated token account
console.log('2. Airdropping 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 之前,我們必須先確定鑄造地址,然後為我們的金鑰對建立(或取得)一個相關的代幣帳戶(ATA)。

  • Elusiv 提供了一個輔助函式, getTokenInfo, 該函式將擷取其協定所支援的特定代幣之詳細資訊(例如:主網與開發網上的鑄造地址、小數位數等)。我們利用此函式來取得開發網上的 USDC 鑄造地址,以及與該代幣鑄造相關的小數位數。
  • 我們定義 oneUsdc 即 10 乘以小數位數。這樣一來,我們就能輕鬆計算轉帳金額,無需擔心小數問題。
  • 接著,我們將該 mint 傳入 SPL Token 輔助函式中, 建立關聯代幣帳戶(冪等). 此操作會在必要時建立一個新的 ATA,並回傳該 ATA 的公鑰。有關 ATA 的更多資訊,請參閱我們的 指南:如何查找 Solana 錢包的相關代幣地址並進行鑄造.
  • 我們將代幣、金額以及新的 ATA 傳入另一個 Elusiv 輔助函式中, airdropToken. 這將向 ATA 注入 1,000 USDC。

查詢個人餘額

在繼續之前,讓我們先查看我們的私人帳戶餘額(由於我們尚未進行任何操作,餘額應為 0)。將「步驟 3」加入您的 主頁 函式:

    // 步驟 3 - 查詢我們的私人餘額
控制台.log('3. 查詢私人餘額');
let privateBalance = await elusiv.getLatestPrivateBalance('USDC');

Elusiv 協定會利用我們先前建立的Elusiv實例,來處理私人餘額的解密作業。

為私人帳戶儲值

由於在初步測試中我們不會有私有餘額,因此讓我們為私有餘額帳戶存入資金(或「儲值」)。

    // Step 4 - Top up private balance if needed
if (privateBalance === BigInt(0)) {
console.log('4. Topping up private balance');
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. Private balance top up not needed. Current Balance: ', (privateBalance / BigInt(10 ** usdcInfo.decimals)).toString());
}

讓我們來分析一下:

  • 首先,我們會確認餘額是否為 0。若非如此,我們將跳過此步驟。
  • 接著,我們使用 Elusiv 的 buildTopUpTx 一個用於建立交易的功能,該交易將為我們的私人餘額充值 500 USDC。
  • 我們使用自己的金鑰對對該交易進行部分簽名。
  • 最後,我們將交易發送至網路,並取得最新的私人餘額。

私下轉帳 USDC

完成第 4 步後,我們的私人帳戶應已呈現正餘額。讓我們利用這筆餘額發送一筆私人交易。具體做法是將一些 USDC 發送至一個隨機地址。請將第 5 步加入您的 主頁 函式:

    // Step 5 - Send some USDC to a random address
console.log('5. Sending USDC to a random address');
if (privateBalance <= BigInt(0)) {
throw new Error("Can't send from an empty private balance");
}

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 發送至一個隨機地址。接著,我們將該交易發送至網路,並將交易網址記錄至控制台。

至此,我們已成功發送了一筆私密交易。做得很好!

驗證交易

讓我們再增加一個步驟,用來檢查我們的交易是否為私有。我們將透過使用 getTransaction Solana Web3 SDK 中的方法,然後解析結果。將步驟 6 加入您的 主頁 函式:

    // Step 6 - Check if our keypair was in the transaction
console.log('6. Checking if our keypair was in the transaction');
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('❌ - Our Keypair was in the transaction (unexpected)');
} else {
console.log('✅ - Our Keypair was not in the transaction (expected)');
}

讓我們來逐步解析這段新程式碼:

  • 首先,我們呼叫該 getTransaction 對我們的私有轉帳交易簽名呼叫此方法。這將返回交易詳情。
  • 接著,我們解析交易明細,以取得該筆交易期間載入記憶體中的帳戶清單。我們正在擷取 唯讀 以及 可寫入的 帳戶,然後將它們合併成一個單一陣列,其中包含該交易中使用的所有公鑰。
  • 最後,我們透過以下方式檢查發送者金鑰是否出現在該交易中: .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=開發網
6. 檢查 是否 我們的金鑰對是否 是否 該筆交易中
✅ - 我們的金鑰對並未 包含在 該筆交易中 (預期)

註:請參閱 2. 基本用法 關於 Elusiv SDK 文件 如果你遇到一個 etc.sha512Sync 未設定 錯誤。 若您在最後看到成功訊息,即表示您已成功使用 Elusiv SDK 在 Solana 上發送了一筆私密交易。您應該可以在 Solana Explorer 中瀏覽該筆交易,並再次確認我們的付款人錢包並未與該筆交易相關聯。做得很好!

總結

在您的去中心化應用程式(dapp)中啟用私密交易,是保護使用者隱私並降低 Web3 技術採用門檻的絕佳方式。Elusiv 讓您能輕鬆將這項功能整合至您的應用程式中。我們迫不及待想看看您會創造出什麼樣的成果!

如果您有任何問題或想分享的想法,歡迎透過DiscordTwitter 聯絡我們!

我們 ❤️ 您的回饋!

如果您有任何意見回饋或對新主題的建議,請告訴我們。我們非常樂意聽取您的意見。

資源

分享這份指南