:2026-04-03 4:12 点击:9
随着区块链技术的飞速发展,去中心化应用(DApps)正逐渐成为互联网领域的新热点,而 UniApp 凭借其“一次开发,多端发布”的优势,成为了许多开发者构建跨平台应用的首选,将 UniApp 与以太坊这样的主流区块链平台相结合,可以让我们轻松构建能够与区块链交互的跨平台 DApps,本文将详细介绍如何在 UniApp 项目中调用以太坊,包括环境搭建、钱包连接、数据交互及智能合约调用等关键步骤。
在开始之前,我们需要准备以下环境和工具:

在 UniApp 中调用以太坊,通常依赖于 JavaScript 库,目前最主流和推荐的是 web3.js (v4.x+) 或 ethers.js,两者功能强大,但 ethers.js 以其更现代的 API、更小的体积和更好的 TypeScript 支持逐渐受到青睐,本文将以 ethers.js 为例进行讲解。
安装 ethers.js:
在你的 UniApp 项目根目录下,打开终端,运行以下命令安装 ethers.js:
npm install ethers # 或者 yadd add ethers
配置 uni-app 项目以支持 npm:
在 HBuilderX 中,右键点击项目根目录,选择“显示 npm 模块”,然后确保 ethers 已正确显示,如果项目没有 node_modules 文件夹,HBuilderX 可能会提示你构建 npm。
DApp 与区块链交互的第一步通常是连接用户的钱包,在 UniApp 的 H5 端,我们可以通过 window.ethereum 对象(由 MetaMask 注入)来实现。
检查并请求账户授权: 在页面的 JavaScript 代码中,你可以编写如下函数来连接钱包:
// 在 pages/index/index.vue 或其他页面中
async connectWallet() {
try {
// 检查浏览器是否安装了以太坊提供者(如 MetaMask)
if (window.ethereum) {
// 请求用户授权连接钱包
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
if (accounts.length > 0) {
this.currentAccount = accounts[0];
console.log('已连接钱包:', this.currentAccount);
// 可以在这里初始化 web3 或 ethers provider
this.initProvider();
}
} else {
uni.showToast({
title: '请安装 MetaMask 钱包',
icon: 'none'
});
}
} catch (error) {
console.error('连接钱包失败:', error);
uni.showToast({
title: '连接钱包失败',
icon: 'none'
});
}
},
初始化 Ethers Provider:
连接成功后,我们可以使用 window.ethereum 创建一个 Ethers.js 的 Provider 对象,这是与以太坊网络交互的入口。
initProvider() {
if (window.ethereum) {
// 使用 Ethers.js 的 BrowserProvider 包装 window.ethereum
this.provider = new ethers.BrowserProvider(window.ethereum);
console.log('Ethers Provider 初始化成功:', this.provider);
}
},
注意:
在 App 端和小程序端,由于浏览器环境的限制,直接使用 window.ethereum 是不可行的,通常需要集成第三方 SDK(如 uni-web3-sdk 或 uni-ethers,这类 SDK 可能需要封装原生插件或提供特定的适配方案)或引导用户使用外部浏览器(如 DAppBrowser)打开链接进行交互,这部分相对复杂,可能需要根据具体平台进行适配。
处理账户变化:监听 accountsChanged 事件,以便在用户切换账户时更新应用状态。
// 在 initProvider 中或连接成功后添加
if (window.ethereum) {
window.ethereum.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
// 用户断开了连接
this.currentAccount = null;
console.log('用户已断开钱包连接');
} else {
// 用户切换了账户
this.currentAccount = accounts[0];
console.log('用户切换账户至:', this.currentAccount);
}
});
}
有了 Provider 对象,我们就可以轻松读取以太坊链上的数据,例如获取账户余额、查询区块信息、调用只读的智能合约方法等。
获取账户余额:
async getBalance() {
if (!this.provider || !this.currentAccount) {
uni.showToast({
title: '请先连接钱包',
icon: 'none'
});
return;
}
try {
const balance = await this.provider.getBalance(this.currentAccount);
// ethers.js 的 BigNumber 需要转换为可读格式,如 Ether
const balanceInEther = ethers.formatEther(balance);
this.balance = balanceInEther;
console.log('账户余额:', balanceInEther, 'ETH');
} catch (error) {
console.error('获取余额失败:', error);
}
},
查询智能合约只读方法:
假设我们有一个已部署的智能合约,我们可以使用 Contract 对象来调用其只读(view 或 pure)方法。
// 假设这是你的智能合约 ABI(Application Binary Interface)的一部分
const contractABI = [
// 一个获取某个地址代币余额的函数
"function balanceOf(address owner) view returns (uint256)"
];
// 合约地址
const contractAddress = "0x...YourContractAddress...";
async queryContractReadMethod() {
if (!this.provider) {
uni.showToast({
title: 'Provider 未初始化',
icon: 'none'
});
return;
}
try {
const contract = new ethers.Contract(contractAddress, contractABI, this.provider);
const balance = await contract.balanceOf(this.currentAccount);
const formattedBalance = ethers.formatEther(balance);
console.log('合约查询结果:', formattedBalance);
uni.showToast({
title: `查询成功,余额: ${formattedBalance}`,
icon: 'success'
});
} catch (error) {
console.error('合约查询失败:', error);
}
},
与区块链进行写交互(如转账、调用智能合约的修改方法)需要用户使用钱包签名并支付 Gas 费。
获取签名者 (Signer):
发送交易需要 Signer 对象,它代表一个能够签名的账户。
async getSigner() {
if (!this.provider) {
uni.showToast({
title: 'Provider 未初始化',
icon: 'none'
});
return null;
}
try {
const signer = await this.provider.getSigner();
console.log('Signer 获取成功:', signer);
return signer;
} catch (error) {
console.error('获取 Signer 失败:', error);
return null;
}
},
发送以太坊转账:
async sendTransaction(toAddress, amountInEther) {
if (!this.currentAccount) {
uni.showToast({
title: '请先连接钱包',
icon: 'none'
});
return;
}
try {
const signer = await this.getSigner();
if (!signer) return;
const tx = {
to: toAddress,
value: ethers.parseEther(amountInEther) // 将 ETH 转换为 wei
};
const txResponse = await signer.sendTransaction(tx);
console.log('交易已发送,等待确认:', txResponse.hash);
uni.showLoading({
title: '交易中,请稍候...'
});
// 等待交易被确认
const txReceipt
本文由用户投稿上传,若侵权请提供版权资料并联系删除!