WalletConnect 協議完整實作指南:從原理到開發部署
WalletConnect 是一個開放的協議,用於實現去中心化應用(DApp)與加密貨幣錢包之間的安全連接。作為 Web3 生態系統中最廣泛採用的連接標準,WalletConnect 使錢包能夠與任何區塊鏈應用程式進行交互,無需用戶暴露私鑰或安裝特定的瀏覽器擴展。本文深入解析 WalletConnect 的技術架構、協定版本演進、實際開發步驟、以及常見問題的解決方案,幫助開發者從零開始構建支援 W
WalletConnect 協議完整實作指南:從原理到開發部署
概述
WalletConnect 是一個開放的協議,用於實現去中心化應用(DApp)與加密貨幣錢包之間的安全連接。作為 Web3 生態系統中最廣泛採用的連接標準,WalletConnect 使錢包能夠與任何區塊鏈應用程式進行交互,無需用戶暴露私鑰或安裝特定的瀏覽器擴展。本文深入解析 WalletConnect 的技術架構、協定版本演進、實際開發步驟、以及常見問題的解決方案,幫助開發者從零開始構建支援 WalletConnect 的應用。
一、WalletConnect 協議核心概念
1.1 設計目標與解決問題
傳統的 Web3 應用程式與錢包交互存在諸多痛點:用戶必須在瀏覽器中安裝擴展錢包(如 MetaMask),或者使用錢包內建的瀏覽器。這種模式限制了用戶的選擇權,也增加了安全風險。WalletConnect 的設計目標是建立一個錢包與應用程式之間的標準化通信協議,實現以下能力:
跨平台連接:無論是桌面瀏覽器、移動應用還是硬體錢包,只要有網絡連接能力,就可以通過 WalletConnect 與 DApp 建立安全會話。
無私鑰暴露:錢包的私鑰始終保留在用戶設備上,所有簽名請求都需要用戶在錢包端確認,避免了 Web 應用直接接觸私鑰的風險。
會話管理:支持建立長期會話,用戶一次授權後可以持續使用,無需每次操作都掃描二維碼。
多鏈支持:單一連接可以同時支持多條區塊鏈,簡化了跨鏈應用的開發。
1.2 架構組件解析
WalletConnect 的架構由三個核心組件構成:
WalletConnect 架構示意:
┌─────────────────────────────────────────────────────────────┐
│ DApp(去中心化應用) │
│ - 發起連接請求 │
│ - 發送交易簽名請求 │
│ - 處理錢包回應 │
└────────────────────────┬────────────────────────────────────┘
│ WebSocket / HTTP
┌────────────────────────▼────────────────────────────────────┐
│ WalletConnect Bridge Server │
│ - 建立會話 │
│ - 消息路由 │
│ - 會話狀態管理 │
│ - 端對端加密 │
└────────────────────────┬────────────────────────────────────┘
│ 錢包特定協議
┌────────────────────────▼────────────────────────────────────┐
│ Wallet(加密貨幣錢包) │
│ - 顯示連接請求 │
│ - 請求用戶授權 │
│ - 執行簽名操作 │
│ - 返回結果 │
└─────────────────────────────────────────────────────────────┘
Bridge Server:作為中繼伺服器,負責在 DApp 和錢包之間轉發加密消息。值得注意的是,Bridge Server 本身無法解密消息內容,因為所有消息都採用端對端加密(E2EE)機制。
DApp Client:DApp 端實現的 WalletConnect SDK,負責發起連接、管理會話、構建和發送各種區塊鏈請求。
Wallet Client:錢包端實現的 WalletConnect SDK,處理連接請求、管理已授權的會話列表、處理簽名和交易請求。
1.3 版本演進:從 v1.0 到 v2.0
WalletConnect 協議經歷了重大升級,從 v1.0 到 v2.0(現在被稱為「WalletConnect」)帶來了根本性的變化:
v1.0 特性:
- 基於 QR 碼的連接方式
- 單一區塊鏈支持
- 會話期限固定
- 即將停止維護
v2.0 核心改進:
- 多鏈支持:單一會話可同時連接多條區塊鏈
- 靈活的會話權限:可細粒度控制授權範圍
- 更強的加密:升級為更安全的密鑰交換算法
- 推送通知:支持錢包向用戶發送交易狀態更新
- 配對系統:使用 URI 配對而非僅依賴 QR 碼
二、WalletConnect v2.0 技術詳解
2.1 會話建立流程
WalletConnect v2.0 的會話建立過程涉及複雜的密碼學操作,以下是完整流程:
WalletConnect v2.0 會話建立流程:
1. DApp 初始化
│
▼
2. DApp 生成 topic、對稱密鑰
│
▼
3. DApp 發送 pairing request(包含區塊鏈網絡、方法是)
│
▼
4. Bridge Server 轉發配對請求到錢包
│
▼
5. 錢包向用戶顯示連接請求(包含 DApp URL、權限)
│
▼
6. 用戶批准連接
│
▼
7. 錢包生成會話密鑰、回傳 response
│
▼
8. 雙方建立加密會話
│
▼
9. DApp 發送區塊鏈請求(如 eth_requestAccounts)
│
▼
10. 錢包處理請求、返回結果
2.2 訊息格式與結構
WalletConnect v2.0 使用 JSON-RPC 2.0 作為消息格式標準。以下是典型的請求和回應結構:
Session Request(會話請求):
{
"id": 1698765432100,
"jsonrpc": "2.0",
"method": "wc_sessionRequest",
"params": {
"requester": {
"metadata": {
"name": "My DeFi App",
"description": "Decentralized Finance Application",
"url": "https://my-defi-app.com",
"icons": ["https://my-defi-app.com/icon.png"]
},
"publicKey": "0x1234567890abcdef..."
},
"chains": ["eip155:1", "eip155:137"],
"methods": [
"eth_requestAccounts",
"eth_sendTransaction",
"personal_sign",
"eth_signTypedData_v4"
],
"events": [
"accountsChanged",
"chainChanged"
]
}
}
Response(回應):
{
"id": 1698765432100,
"jsonrpc": "2.0",
"result": {
"approved": true,
"chainId": 1,
"accounts": ["0x742d35Cc6634C0532925a3b844Bc9e7595f..."],
"metadata": {
"name": "MetaMask",
"description": "Ethereum Wallet",
"url": "https://metamask.io",
"icons": ["https://metamask.io/icon.png"]
}
}
}
2.3 加密機制深度分析
WalletConnect v2.0 使用 X25519 橢圓曲線密鑰交換協議建立共享密鑰,然後使用 ChaCha20-Poly1305 對稱加密算法加密消息。這種組合提供了前向安全性(Forward Secrecy),即使長期密鑰被洩露,過往的會話內容也無法被解密。
密鑰交換過程:
- DApp 生成臨時密鑰對(X25519)
- 將公鑰附加在配對 URI 中
- 錢包接收到配對請求後,生成自己的臨時密鑰對
- 雙方各自計算共享密鑰(使用對方的公鑰和自己的私鑰)
- 共享密鑰用於會話期間的所有消息加密
前向安全性保障:每次會話都使用臨時密鑰,會話結束後密鑰即被銷毀。即使攻擊者獲取了某一方的長期私鑰,也無法解密已經結束的會話內容。
2.4 多鏈架構設計
WalletConnect v2.0 支持「鏈 ID 命名空間」(Chain ID Namespace)機制,讓單一會話可以同時管理多條區塊鏈。命名空間格式為 {protocol}:{chainId},例如:
eip155:1- Ethereum Mainneteip155:5- Goerli Testneteip155:137- Polygoneip155:42161- Arbitrum Onesolana:mainnet-beta- Solana Mainnet
開發者可以通過 chains 參數指定應用支持的區塊鏈列表,錢包則會根據用戶持有的資產情況過濾顯示。
三、DApp 端開發實作
3.1 專案初始化
首先建立一個支援 WalletConnect 的 DApp 專案。我們使用 React 作為前端框架,配合 @walletconnect/ethereum-provider 實現連接功能:
# 建立 React 專案
npx create-react-app my-dapp
cd my-dapp
# 安裝 WalletConnect 相關依賴
npm install @walletconnect/ethereum-provider @web3modal/ethers ethers
3.2 錢包連接實現
以下程式碼展示如何在 DApp 中實現 WalletConnect 連接功能:
// src/walletConnect.js
import EthereumProvider from '@walletconnect/ethereum-provider';
let provider = null;
// 初始化 WalletConnect Provider
export async function initWalletConnect() {
// 專案 ID 從 WalletConnect Cloud 註冊獲得
const projectId = 'YOUR_PROJECT_ID';
// 定義支援的鏈和方法
const metadata = {
name: 'My DeFi App',
description: 'Decentralized Finance Application',
url: 'https://my-defi-app.com',
icons: ['https://my-defi-app.com/icon.png']
};
// 初始化 provider
provider = await EthereumProvider.init({
projectId,
chains: [1], // Ethereum Mainnet
methods: [
'eth_requestAccounts',
'eth_sendTransaction',
'personal_sign',
'eth_signTypedData_v4'
],
events: [
'accountsChanged',
'chainChanged',
'disconnect'
],
metadata
});
// 監聽帳戶變化
provider.on('accountsChanged', (accounts) => {
console.log('帳戶變更:', accounts);
if (accounts.length === 0) {
// 用戶已斷開連接
handleDisconnect();
}
});
// 監聽鏈變化
provider.on('chainChanged', (chainId) => {
console.log('鏈變更:', chainId);
window.location.reload();
});
// 監聽斷開連接
provider.on('disconnect', (code, reason) => {
console.log('斷開連接:', code, reason);
handleDisconnect();
});
return provider;
}
// 發起連接請求
export async function connectWallet() {
if (!provider) {
await initWalletConnect();
}
// 發送連接請求
const accounts = await provider.request({
method: 'eth_requestAccounts'
});
return accounts;
}
// 斷開連接
export async function disconnectWallet() {
if (provider) {
await provider.disconnect();
}
}
// 發送交易
export async function sendTransaction(to, value) {
const accounts = await provider.request({ method: 'eth_accounts' });
const from = accounts[0];
const tx = {
from,
to,
value: '0x' + value.toString(16), // 轉換為十六進制
gasLimit: '0x5208', // 21000 Gwei
gasPrice: '0x4A817C800' // 20 Gwei
};
const txHash = await provider.request({
method: 'eth_sendTransaction',
params: [tx]
});
return txHash;
}
// 請求用戶簽名
export async function signMessage(message) {
const accounts = await provider.request({ method: 'eth_accounts' });
const from = accounts[0];
// 使用 personal_sign 方法
const signature = await provider.request({
method: 'personal_sign',
params: [message, from]
});
return signature;
}
3.3 React 整合範例
以下是完整的 React 元件範例,展示錢包連接的 UI 和狀態管理:
// src/App.jsx
import React, { useState, useEffect } from 'react';
import {
initWalletConnect,
connectWallet,
disconnectWallet,
sendTransaction
} from './walletConnect';
function App() {
const [accounts, setAccounts] = useState([]);
const [connecting, setConnecting] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
// 頁面載入時初始化
initWalletConnect()
.then(() => {
// 檢查是否已有連接
checkConnection();
})
.catch(err => {
console.error('初始化失敗:', err);
setError('WalletConnect 初始化失敗');
});
}, []);
const checkConnection = async () => {
try {
const accounts = await window.ethereum?.request({
method: 'eth_accounts'
});
if (accounts && accounts.length > 0) {
setAccounts(accounts);
}
} catch (err) {
console.error('檢查連接失敗:', err);
}
};
const handleConnect = async () => {
setConnecting(true);
setError(null);
try {
const accounts = await connectWallet();
setAccounts(accounts);
} catch (err) {
setError(err.message || '連接失敗');
} finally {
setConnecting(false);
}
};
const handleDisconnect = async () => {
await disconnectWallet();
setAccounts([]);
};
return (
<div className="wallet-connect">
<h1>WalletConnect DApp 範例</h1>
{error && <div className="error">{error}</div>}
{accounts.length === 0 ? (
<button
onClick={handleConnect}
disabled={connecting}
>
{connecting ? '連接中...' : '連接錢包'}
</button>
) : (
<div className="connected">
<p>已連接帳戶:</p>
<code>{accounts[0]}</code>
<button onClick={handleDisconnect}>斷開連接</button>
</div>
)}
</div>
);
}
export default App;
3.4 自訂配對 URI 處理
WalletConnect v2.0 支持通過 URI 進行配對,這在移動端應用中特別有用:
// 處理 WalletConnect URI
export async function handleWalletConnectUri(uri) {
// URI 格式: wc:topic@2?symKey=symmetricKey&relayProtocol=irn
if (!provider) {
await initWalletConnect();
}
// 通過 URI 建立配對
await provider.pair({ uri });
// 配對成功後,錢包會顯示批准請求
// 用戶批准後,會話即建立
}
四、Walle t端整合實作
4.1 錢包端職責概述
錢包端實現 WalletConnect 需要處理以下核心功能:
- 監聽來自 Bridge Server 的配對請求
- 向用戶顯示連接批准 UI
- 管理已授權的會話列表
- 處理區塊鏈操作請求(簽名、交易)
- 推送通知管理
4.2 錢包 SDK 整合
以下是錢包端整合 WalletConnect 的基本架構:
// wallet/walletConnect.js
import { Core } from '@walletconnect/core';
import { WalletClient } from '@walletconnect/web3wallet';
let web3wallet = null;
// 初始化錢包客戶端
export async function initWalletClient(projectId) {
const core = new Core({
projectId
});
web3wallet = await WalletClient.init({
core,
metadata: {
name: 'My Wallet',
description: 'Secure Ethereum Wallet',
url: 'https://my-wallet.com',
icons: ['https://my-wallet.com/icon.png']
}
});
// 監聽會話請求
web3wallet.on('session_request', async (event) => {
const { id, params, topic } = event;
// 顯示批准 UI
const approved = await showApprovalModal(params);
if (approved) {
// 授權會話
await web3wallet.approveSession({
id,
chainId: 1,
accounts: ['0x742d35Cc6634C0532925a3b844Bc9e7595f...']
});
} else {
// 拒絕會話
await web3wallet.rejectSession({
id,
message: 'User rejected'
});
}
});
// 監聽 RPC 請求
web3wallet.on('session_event', async (event) => {
const { topic, params, id } = event;
switch (params.request.method) {
case 'eth_sendTransaction':
await handleTransactionRequest(id, params.request.params);
break;
case 'personal_sign':
await handleSignMessage(id, params.request.params);
break;
case 'eth_signTypedData_v4':
await handleSignTypedData(id, params.request.params);
break;
}
});
return web3wallet;
}
// 處理交易請求
async function handleTransactionRequest(id, params) {
// 顯示交易確認 UI
const tx = params[0];
const confirmed = await showTransactionConfirm(tx);
if (confirmed) {
// 廣播交易
const txHash = await broadcastTransaction(tx);
// 返回結果
await web3wallet.respondSessionRequest({
id,
result: txHash
});
} else {
// 用戶拒絕
await web3wallet.respondSessionRequest({
id,
error: {
code: 4001,
message: 'User rejected request'
}
});
}
}
// 處理簽名請求
async function handleSignMessage(id, params) {
const [message, address] = params;
// 顯示簽名確認 UI
const confirmed = await showSignConfirm(message, address);
if (confirmed) {
const signature = await signMessage(message, address);
await web3wallet.respondSessionRequest({
id,
result: signature
});
} else {
await web3wallet.respondSessionRequest({
id,
error: {
code: 4001,
message: 'User rejected request'
}
});
}
}
4.3 會話管理策略
錢包需要實現完善的會話管理機制:
// 會話管理
export class SessionManager {
constructor(web3wallet) {
this.wallet = web3wallet;
this.sessions = new Map();
}
// 載入所有會話
async loadSessions() {
const sessionNamespaces = this.wallet.getActiveSessions();
for (const [topic, session] of Object.entries(sessionNamespaces)) {
this.sessions.set(topic, {
peer: session.peer.metadata,
chains: session.namespaces.eip155?.chains || [],
methods: session.namespaces.eip155?.methods || [],
events: session.namespaces.eip155?.events || [],
expiry: session.expiry
});
}
}
// 斷開特定會話
async disconnectSession(topic) {
await this.wallet.disconnectSession({
topic,
message: 'User disconnected'
});
this.sessions.delete(topic);
}
// 斷開所有會話
async disconnectAll() {
for (const topic of this.sessions.keys()) {
await this.disconnectSession(topic);
}
}
// 更新會話權限
async updateSession(topic, newMethods, newEvents) {
await this.wallet.updateSession({
topic,
namespaces: {
eip155: {
chains: this.sessions.get(topic).chains,
methods: newMethods,
events: newEvents,
accounts: []
}
}
});
}
// 檢查會話是否即將過期
checkExpiry() {
const now = Math.floor(Date.now() / 1000);
const expiringSessions = [];
for (const [topic, session] of this.sessions) {
if (session.expiry - now < 3600) { // 小於 1 小時
expiringSessions.push(topic);
}
}
return expiringSessions;
}
}
五、常見問題與最佳實踐
5.1 連接問題排查
問題:配對請求無回應
可能原因:
- Bridge Server 連接問題
- 錢包未正確初始化
- 網絡防火牆阻止
解決方案:
// 添加連接狀態監控
provider.on('connect', () => console.log('連接成功'));
provider.on('disconnect', (err) => {
console.log('連接斷開:', err);
// 嘗試重新連接
if (err) {
initWalletConnect();
}
});
provider.on('error', (err) => console.error('連接錯誤:', err));
問題:交易請求超時
解決方案:
const txHash = await Promise.race([
provider.request({ method: 'eth_sendTransaction', params: [tx] }),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('超時')), 60000)
)
]);
5.2 安全最佳實踐
驗證 DApp 元數據:錢包應始終向用戶顯示 DApp 的 URL 和描述,幫助用戶識別潛在的钓鱼攻擊。
限制授權範圍:錢包應實現「最小權限」原則,只授權 DApp 請求的方法,而非全部權限。
會話過期機制:設定合理的會話過期時間,定期要求用戶重新確認。
惡意網站識別:錢包應維護已知惡意網站的黑名單,在連接前向用戶發出警告。
5.3 錯誤碼處理
WalletConnect 定義了一組標準錯誤碼:
| 錯誤碼 | 含義 | 處理方式 |
|---|---|---|
| 4000 | 無效請求 | 記錄日誌並返回錯誤 |
| 4001 | 用戶拒絕 | 正常流程,通知用戶 |
| 4100 | 未授權 | 提示用戶連接錢包 |
| 4200 | 不支援的方法 | 向用戶說明並提供替代方案 |
| 4300 | 超出配額 | 提示稍後再試 |
| 4900 | 斷開連接 | 清理會話狀態 |
5.4 效能優化建議
連接池管理:對於需要同時管理多個會話的錢包,建議使用連接池來維護與 Bridge Server 的連接。
消息批量處理:當有多個待處理請求時,批量處理而非逐個發送。
本地緩存:緩存已授權的會話信息,減少重複的 Bridge Server 查詢。
// 會話緩存實現
const sessionCache = {
get(key) {
const data = localStorage.getItem(`wc_session_${key}`);
return data ? JSON.parse(data) : null;
},
set(key, value) {
localStorage.setItem(`wc_session_${key}`, JSON.stringify(value));
},
clear() {
// 清理所有會話緩存
Object.keys(localStorage)
.filter(key => key.startsWith('wc_session_'))
.forEach(key => localStorage.removeItem(key));
}
};
六、WalletConnect 與其他標準的整合
6.1 與 ERC-4337 的整合
WalletConnect 可以與 ERC-4337 帳戶抽象標準無縫整合,實現更複雜的交易場景:
// 使用 WalletConnect 發送 ERC-4337 UserOperation
async function sendUserOperationWithWalletConnect(
provider,
userOp,
entryPoint
) {
// 通過 WalletConnect 發送
const userOpHash = await provider.request({
method: 'eth_sendUserOperation',
params: [{
userOp,
entryPoint,
chainId: 1
}]
});
return userOpHash;
}
6.2 多鏈場景應用
WalletConnect v2.0 的多鏈支持使其特別適合 DeFi 聚合器等複雜應用:
// 多鏈配置
const chains = [
{ chainId: 1, name: 'Ethereum' },
{ chainId: 137, name: 'Polygon' },
{ chainId: 42161, name: 'Arbitrum' }
];
// 發送跨鏈請求
async function sendCrossChainRequest(provider, chainId, request) {
const session = provider.session;
const namespace = session.namespaces.eip155;
// 檢查目標鏈是否在會話授權範圍內
const targetChain = `eip155:${chainId}`;
if (!namespace.chains.includes(targetChain)) {
// 請求擴展授權
await provider.extendSession({
chainIds: [targetChain]
});
}
return provider.request({
method: request.method,
params: request.params,
chainId: targetChain
});
}
6.3 與 Web3Modal 的整合
Web3Modal 提供了一個更簡化的 UI 框架,內建 WalletConnect 支援:
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers/react';
// 初始化 Web3Modal
const metadata = {
name: 'My DApp',
description: 'My DApp Description',
url: 'https://my-dapp.com',
icons: ['https://my-dapp.com/icon.png']
};
const ethersConfig = defaultConfig({
metadata,
projectId: 'YOUR_PROJECT_ID'
});
createWeb3Modal({
ethersConfig,
projectId: 'YOUR_PROJECT_ID',
chains: [
{
chainId: 1,
name: 'Ethereum',
currency: 'ETH',
explorerUrl: 'https://etherscan.io',
rpcUrl: 'https://cloudflare-eth.com'
}
],
enableAnalytics: true
});
結論
WalletConnect 已經成為 Web3 生態系統中不可或缺的基礎設施。通過本文的深入解析,開發者應該能夠全面理解 WalletConnect 協議的技術原理,並有能力在 DApp 和錢包兩端實現完整的整合功能。隨著以太坊帳戶抽象、意圖經濟等趨勢的發展,WalletConnect 的角色將更加重要,建議開發者持續關注其版本更新和生態演進。
參考資源
- WalletConnect 官方文檔:https://docs.walletconnect.com
- WalletConnect GitHub:https://github.com/walletconnect
- WalletConnect Cloud 註冊:https://cloud.walletconnect.com
相關文章
- Flashbots MEV-Boost 完整指南:以太坊 MEV 基礎設施深度解析 — Flashbots 是以太坊生態系統中最重要的 MEV(最大可提取價值)基礎設施之一。自 2020 年成立以來,Flashbots 從一個研究組織發展成為涵蓋 MEV 提取、交易隱私、去中心化排序等多個領域的綜合性平台。MEV-Boost 作為 Flashbots 的核心產品,已經成為以太坊網路中不可或缺的基礎設施,顯著改變了 MEV 的分配方式和區塊生產的生態格局。本文深入解析 Flashbot
- 隱私協議合規框架與實務操作指南:以 Aztec、Railgun 為核心的深度分析 — 區塊鏈隱私協議在提供交易隱私的同時,也面臨著全球監管機構日益嚴格的審查。2022 年 Tornado Cash 遭受 OFAC 制裁後,整個隱私協議領域陷入了合規性的深層次討論。Aztec Network 和 Railgun 作為以太坊生態中最重要的兩個隱私解決方案,它們在技術架構和合規策略上走出了一條不同的道路。本文深入分析這兩個協議的合規框架,提供詳細的實務操作指南,幫助用戶和開發者在保護隱私
- Noir 隱私合約開發完整指南:從零知識證明到實際應用 — Noir 是由 Aztec Labs 開發的開源程式語言,專為編寫零知識證明(Zero-Knowledge Proof)電路而設計。作為以太坊隱私 Layer 2 解決方案 Aztec Network 的核心組成部分,Noir 提供了一種抽象化的方式,讓開發者能夠以傳統程式設計的思維編寫隱私保護應用,而無需深入理解複雜的密碼學底層實現。本文將全面介紹 Noir 的語言特性、开发環境、實際應用場景,
- Solidity 智慧合約開發基礎 — Solidity 是以太坊智慧合約的主要程式語言,專為區塊鏈上的去中心化應用設計。自 2014 年首次發布以來,Solidity 已經成為智慧合約開發的業界標準,被廣泛應用於 DeFi、NFT、DAO 等各種區塊鏈應用。
- OpenZeppelin 智慧合約庫使用完整指南 — OpenZeppelin 是以太坊智慧合約開發領域最重要的開源庫和工具提供商。其合約庫經過嚴格審計、被廣泛採用,並成為智慧合約安全的行業標準。本文將全面介紹 OpenZeppelin 庫的核心組件、使用方法、最佳實踐,以及在實際項目中的集成策略。適合具有一定 Solidity 基礎的開發者閱讀。
延伸閱讀與來源
- Ethereum.org Developers 官方開發者入口與技術文件
- EIPs 以太坊改進提案
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!