Web3钱包:钱包集成与签名验证

Web3钱包:钱包集成与签名验证

大家好,我是欧阳瑞(Rich Own)。今天想和大家聊聊Web3钱包这个重要话题。作为一个全栈/Web3开发者,钱包集成是DApp开发的核心功能。今天就来分享一下钱包集成和签名验证的实战经验。

Web3钱包概述

常见钱包

钱包 说明 类型
MetaMask 浏览器插件钱包 热钱包
WalletConnect 跨平台钱包协议 协议
Coinbase Wallet Coinbase官方钱包 热钱包
Ledger 硬件钱包 冷钱包

核心功能

复制代码
连接钱包 → 获取用户地址
签名交易 → 授权转账
签名消息 → 身份验证
监听事件 → 账户/网络变化

MetaMask集成

基础连接

javascript 复制代码
async function connectWallet() {
  if (window.ethereum) {
    try {
      const accounts = await window.ethereum.request({
        method: 'eth_requestAccounts'
      });
      return accounts[0];
    } catch (error) {
      console.error('连接失败:', error);
      throw error;
    }
  } else {
    throw new Error('请安装MetaMask');
  }
}

获取账户信息

javascript 复制代码
async function getAccountInfo() {
  const provider = new ethers.providers.Web3Provider(window.ethereum);
  const signer = provider.getSigner();
  
  const address = await signer.getAddress();
  const balance = await provider.getBalance(address);
  const chainId = await provider.getNetwork().then(net => net.chainId);
  
  return {
    address,
    balance: ethers.utils.formatEther(balance),
    chainId
  };
}

监听变化

javascript 复制代码
// 监听账户变化
window.ethereum.on('accountsChanged', (accounts) => {
  if (accounts.length === 0) {
    console.log('账户已断开');
  } else {
    console.log('账户已切换:', accounts[0]);
  }
});

// 监听网络变化
window.ethereum.on('chainChanged', (chainId) => {
  console.log('网络已切换:', chainId);
  window.location.reload();
});

WalletConnect集成

初始化连接

javascript 复制代码
import WalletConnect from '@walletconnect/client';
import QRCodeModal from '@walletconnect/qrcode-modal';

const connector = new WalletConnect({
  bridge: 'https://bridge.walletconnect.org',
  qrcodeModal: QRCodeModal
});

async function connectWithWalletConnect() {
  if (!connector.connected) {
    await connector.createSession();
  }
  
  connector.on('connect', (error, payload) => {
    if (error) {
      throw error;
    }
    const { accounts, chainId } = payload.params[0];
    console.log('已连接:', accounts[0]);
  });
  
  connector.on('disconnect', (error, payload) => {
    console.log('已断开连接');
  });
}

签名验证

签名消息

javascript 复制代码
async function signMessage(message) {
  const provider = new ethers.providers.Web3Provider(window.ethereum);
  const signer = provider.getSigner();
  
  const signature = await signer.signMessage(message);
  return signature;
}

验证签名

javascript 复制代码
function verifySignature(message, signature, address) {
  const signer = ethers.utils.verifyMessage(message, signature);
  return signer === address;
}

登录示例

javascript 复制代码
async function login() {
  const nonce = generateNonce();
  localStorage.setItem('nonce', nonce);
  
  const message = `欢迎登录!\n\nNonce: ${nonce}`;
  const signature = await signMessage(message);
  
  // 发送到后端验证
  const response = await fetch('/api/login', {
    method: 'POST',
    body: JSON.stringify({
      address: await getAddress(),
      signature,
      nonce
    })
  });
  
  return response.json();
}

实战案例:DApp钱包集成

javascript 复制代码
class WalletService {
  constructor() {
    this.provider = null;
    this.signer = null;
    this.address = null;
    this.chainId = null;
  }
  
  async connect() {
    if (!window.ethereum) {
      throw new Error('请安装Web3钱包');
    }
    
    this.provider = new ethers.providers.Web3Provider(window.ethereum);
    const accounts = await this.provider.send('eth_requestAccounts', []);
    
    this.address = accounts[0];
    this.signer = this.provider.getSigner();
    this.chainId = await this.provider.getNetwork().then(net => net.chainId);
    
    this.setupListeners();
    
    return this.address;
  }
  
  setupListeners() {
    window.ethereum.on('accountsChanged', (accounts) => {
      if (accounts.length > 0) {
        this.address = accounts[0];
        this.signer = this.provider.getSigner();
      }
    });
    
    window.ethereum.on('chainChanged', () => {
      window.location.reload();
    });
  }
  
  async getBalance() {
    if (!this.provider || !this.address) {
      throw new Error('请先连接钱包');
    }
    
    const balance = await this.provider.getBalance(this.address);
    return ethers.utils.formatEther(balance);
  }
  
  async sendTransaction(to, amount) {
    if (!this.signer) {
      throw new Error('请先连接钱包');
    }
    
    const tx = await this.signer.sendTransaction({
      to,
      value: ethers.utils.parseEther(amount)
    });
    
    return tx.hash;
  }
}

// 使用
const wallet = new WalletService();
await wallet.connect();
console.log('地址:', wallet.address);
console.log('余额:', await wallet.getBalance());

最佳实践

1. 多钱包支持

javascript 复制代码
// 支持多种钱包
const wallets = {
  metamask: connectMetaMask,
  walletconnect: connectWalletConnect,
  coinbase: connectCoinbase
};

2. 错误处理

javascript 复制代码
try {
  await connectWallet();
} catch (error) {
  if (error.code === 4001) {
    // 用户拒绝连接
    console.log('用户拒绝连接');
  } else {
    console.error('连接失败:', error);
  }
}

总结

Web3钱包集成是DApp开发的基础。通过正确的钱包连接、签名验证和事件监听,可以提供良好的用户体验。

我的鬃狮蜥Hash对钱包也有自己的理解------它总是安全地保护自己的领地,这也许就是自然界的"钱包"吧!

如果你对Web3钱包集成有任何问题,欢迎留言交流!我是欧阳瑞,极客之路,永无止境!


技术栈:Web3钱包 · MetaMask · WalletConnect

相关推荐
Richown8 小时前
跨链桥接:多链资产转移实现
区块链·react
master-dragon8 小时前
区块链共识机制基础知识
区块链
kida_yuan8 小时前
【以太来袭】7. Besu 性能基线(Caliper)
区块链·测试
穗余11 小时前
什么是ERC-8004
人工智能·web3·区块链
Richown11 小时前
区块链开发:智能合约测试与调试技巧
区块链·react
Richown1 天前
物联网开发:MQTT与传感器数据采集
区块链·react
葫三生1 天前
《论三生原理》对《周易》《道德经》的一次根本性重写?
人工智能·算法·计算机视觉·区块链·量子计算
Richown1 天前
性能优化:前端加载性能优化指南
区块链·react