多链 DApp
介绍
多链 DApp,即支持多个区块链网络的去中心化应用程序,是区块链技术发展的重要方向。通过支持多链,DApp 可以提供更广泛的功能和更灵活的用户体验。本教程将以Bitget Wallet为例,介绍多链 DApp 的两个主要业务场景,以及如何通过注入提供者和 Http 桥接实现链切换。
业务场景
多链 DApp 有两个主要业务场景:
1. 支持多链的单链业务
在这种场景下,DApp 的核心业务是单链的,但用户可以在初始化时选择目标链。示例包括:
- Uniswap :一个去中心化交易所(DEX),允许用户在以太坊及其 Layer 2 网络上交换代币。
- PancakeSwap :运行在币安智能链(BSC)上的去中心化交易所(DEX),支持各种代币的交易和流动性提供。
在这种场景下,DApp 在不同链上提供相同的功能,用户可以根据需要选择不同的链进行交互。实现这种支持的主要挑战是确保 DApp 在不同链上的部署和运行的一致性,并处理链之间的差异。
2. 跨链业务
在这种场景下,DApp 需要在多个链之间进行通信以完成复杂的业务流程。它可以选择支持多链异构钱包,或在不同链之间切换钱包。示例包括:
- Babylon 的早期版本:利用
Cosmos
实现跨链 DeFi 功能,需要使用钱包连接到BTC
和Babylon
。
在这种场景下,DApp 需要在不同链之间传输数据和资产,通常需要更复杂的跨链协议和机制。此类业务的实现更具挑战性,因为它需要解决不同链之间的数据一致性、交易安全性和跨链通信效率等问题。
实现链切换
提供链切换功能是实现多链 DApp 的重要部分。本文将介绍如何使用注入提供者和 Http 桥接实现链切换。
1. 使用注入提供者切换链
注入提供者是 DApp 连接钱包的常见方法,使用注入提供者允许 DApp 在用户界面内切换链。实现步骤如下:
1. 检测当前链
DApp 首先需要检测用户当前连接的区块链网络。这通常使用 Web3 提供的 API 完成。例如,在以太坊上,您可以使用web3.eth.net.getId()
获取当前网络 ID。
web3.eth.net.getId().then((netId) => {
console.log('当前网络ID:', netId)
})
2. 为用户提供切换链的 UI
在 DApp 的用户界面中提供一个选项,允许用户切换链。这可以是下拉菜单、按钮或其他 UI 组件,允许用户选择要切换到的区块链网络。
<select id="networkSelector">
<option value="1">以太坊主网</option>
<option value="8453">Base</option>
<!-- 根据需要添加其他网络 -->
</select>
3. 监听用户选择
当用户选择新网络时,DApp 需要捕获此事件并相应处理。
document
.getElementById('networkSelector')
.addEventListener('change', (event) => {
const newNetworkId = event.target.value
switchNetwork(newNetworkId)
})
4. 根据用户操作选择适当的提供者
如果是在同一主网内的切换,通常不需要选择不同的提供者。例如,从以太坊主网切换到 Base 链时,Bitget Wallet提供的提供者仍然是window.bitkeep.ethereum
。
但是,如果是不同主网之间的切换,例如从以太坊切换到 BTC,您需要更改提供者,从window.bitkeep.ethereum
到window.bitkeep.unisat
。不同提供者提供的 API 也不同,请参考相应提供者的 API 文档。
5. 切换链
DApp 可以调用 Bitget Wallet 提供者提供的 API 来请求用户切换到新链。
async function switchNetwork(chainId) {
try {
await window.bitkeep.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: `0x${parseInt(chainId).toString(16)}` }],
})
console.log('网络切换成功')
} catch (switchError) {
// 处理错误
console.error('切换网络失败', switchError)
// 如果链尚未添加到BitgetWallet,您可以请求用户添加链
if (switchError.code === 4902) {
try {
await window.bitkeep.ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: `0x${parseInt(chainId).toString(16)}`,
chainName: 'Base',
nativeCurrency: {
name: 'Ether',
symbol: 'ETH',
decimals: 18,
},
rpcUrls: ['https://api.mycryptoapi.com/eth'],
blockExplorerUrls: ['https://etherscan.io'],
},
],
})
} catch (addError) {
console.error('添加网络失败', addError)
}
}
}
}
6. 重新初始化 DApp:
切换链后,DApp 需要重新初始化所有与区块链交互的实例,例如合约实例、Web3 或 Ethers.js 提供的提供者等。
async function initializeDApp() {
const provider = new ethers.providers.Web3Provider(window.bitkeep.ethereum)
const signer = provider.getSigner()
const contract = new ethers.Contract(contractAddress, contractABI, signer)
//调用相关方法
try {
const result = await contract.someMethod()
console.log(result)
} catch (error) {
console.error('调用合约方法时出错:', error)
}
}
//调用初始化函数
initializeDApp()
2. 使用 Http 桥接切换链
Http 桥接是链切换的另一种常见方法,通常在WalletConnect
的上下文中看到,但请注意WalletConnect
只是 Http 桥接的一种形式。使用 Http 桥接将允许 DApp 通过 HTTP 请求通知钱包切换链。
以WalletConnect
为例,您可以如下初始化提供者:
import WalletConnectProvider from '@walletconnect/web3-provider'
import Web3 from 'web3'
// 1. 创建WalletConnect提供者
const provider = new WalletConnectProvider({
infuraId: 'YOUR_INFURA_ID', // 必需
rpc: {
8453: 'https://api.mycryptoapi.com/eth', // Base链
1: 'https://mainnet.infura.io/v3/YOUR_INFURA_ID', // 以太坊主网
// 添加更多网络RPC URL
},
})
// 2. 启动提供者
provider.enable().then(() => {
const web3 = new Web3(provider)
// 在此初始化DApp,例如获取账户、设置合约实例等。
web3.eth.getAccounts().then((accounts) => {
console.log('账户:', accounts)
})
})
用户将Bitget Wallet应用(支持 WalletConnect)连接到 DApp 后,后续步骤将与使用注入提供者的过程一致,因此在此跳过这些步骤。
总结
通过Bitget Wallet,开发者可以轻松实现对多链的支持,并通过灵活的链切换机制提供用户友好的多链交互体验。我们希望本教程能为您的多链 DApp 开发提供有价值的指导。