閱讀時間 10 分鐘
2024年2月29日,Elusiv宣布將逐步停用 Elusiv 平台。本指南僅供歷史性教育參考之用。
若想了解現代化的替代方案,請參閱《Solana 上的保密轉帳:Token-2022開發者指南》。
概覽
Web3 技術普及的一大障礙,在於對隱私需求的增加。區塊鏈交易是公開的,這意味著任何人都能查看交易的詳細資訊,包括發送方和接收方。雖然在許多應用場景中,這種透明度是有益的,但在許多情況下,使用者仍需要隱私。 舉例來說,若您是企業主,可能不希望競爭對手知道您支付給員工的薪資金額;又或者,若您是一般使用者,可能希望避免讓朋友知道您的投資金額。隨著 Web3 觸及更多使用者與應用場景,隱私的重要性將日益提升。
Solana 平台上正陸續出現數種旨在實現隱私交易的協議。在本指南中,我們將逐步說明如何使用 Elusiv——一款基於 Solana 的零知識(ZK)隱私協議——來進行隱私的 SPL 代幣轉帳。
您將負責的工作內容
在本指南中,您將:
- 了解 Elusiv——一款基於 Solana 的零知識(ZK)隱私協定
- 使用 Elusiv SDK 建立一筆私密的 USDC 轉帳
- 確認該交易是否為私下交易
您需要準備的物品
- Solana基礎知識
- 零知識證明的基本知識
- 已安裝Node.js(版本 18.16 或更高)
- 已安裝TypeScript 和 ts-node(最新版本)
什麼是 Elusiv?
Solana 上的交易是公開的。任何能夠存取區塊鏈瀏覽器並持有使用者公鑰的人,都能追蹤和監控該使用者的交易活動。Elusiv 旨在切斷發送者與接收者之間的關聯,以實現隱私交易。Elusiv 是一個基於 Solana 的 隱私協議,透過零知識加密技術實現。 該協議讓使用者和應用程式能夠運用通用加密與控制功能,使其得以自主選擇分享與不分享的內容。Elusiv 運用zk-SNARKS技術來實現隱私交易與去中心化合規解決方案。
Elusiv 有兩項主要功能:
- Elusiv 程式:Elusiv 的運作方式是管理一個由 Elusiv 程式所管轄的共享資金池。使用者可將資金存入或從資金池中提取(公開交易),並在資金池內將資金轉帳給其他使用者(私有交易)。雖然交易詳情對付款發起人而言是私密的,但發起人可建立檢視金鑰,讓他人得以查看特定交易。
- Elusiv Warden:Elusiv Warden 負責將客戶請求轉發至網路,並將於未來負責管理合規相關任務(例如:防止黑名單中的地址進行交易)。
Elusiv 開發了一款簡單的應用程式,用以展示這項可讓您進行私有代幣轉帳的技術。請前往https://app.elusiv.io/ 查看。

讓我們來看看 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 進行互動。本指南後續將更詳細地說明各個項目。
建立新的金鑰對
首先,我們需要一組新的金鑰對來進行示範。請使用下方的工具產生一組金鑰對,並將生成的內容複製並貼上至您的程式碼編輯器中。
您應該會看到類似以下的內容——請務必包含由小工具生成的密鑰:
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:
- 建立一個 Elusiv 實例
- 將一些「USDC」空投至我們的開發網(devnet)中與 USDC 相關的代幣帳戶
- 查詢我們的私人帳戶餘額
- 如有需要,請為私人帳戶儲值
- 將一些 USDC 私下轉帳至一個隨機地址
- 確認我們的金鑰對並未包含在該交易中
建立一個 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 讓您能輕鬆將這項功能整合至您的應用程式中。我們迫不及待想看看您會創造出什麼樣的成果!
如果您有任何問題或想分享的想法,歡迎透過Discord或Twitter 聯絡我們!
我們 ❤️ 您的回饋!
如果您有任何意見回饋或對新主題的建議,請告訴我們。我們非常樂意聽取您的意見。
