在实际 DApp 开发中,很多 智能合约 的函数不仅接受普通参数,也期待“随消息一起汇来”的 以太币 (ETH)。例如:
NFT 拍卖行的
bid()函数质押协议的
deposit()GameFi 项目的
purchaseItem()
这些合约会在函数里校验 msg.value 是否足额,然后把以太币存储进合约或立即转给受益人。用 ethers.js 一行就能触发这类函数,但不少新手容易遗漏 : { value: … } 这一关键参数。
在 .env 中写:
PRIVATE_KEY=xxxxxxxx
INFURA_KEY=xxxxxxxx
为了安全,不要用明文私钥。
import { ethers } from 'ethers';
import dotenv from 'dotenv';
dotenv.config();
const provider = new ethers.providers.JsonRpcProvider(
`https://mainnet.infura.io/v3/${process.env.INFURA_KEY}`
);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
SEO 核心关键词:ethers.js, 以太坊主网, JsonRpcProvider
const CONTRACT_ADDRESS = '0x1234...ABCD';
const abi = [
'function deposit() external payable',
// 其他 ABI 片段
];
const contract = new ethers.Contract(CONTRACT_ADDRESS, abi, wallet);
小贴士:如果合约代码开源,可直接把完整 ABI JSON 扔进去;如果只公开接口,就把所需函数抽出即可。
const ethAmount = '0.23'; // 用户想存入 0.23 ETH
const tx = await contract.deposit({
value: ethers.utils.parseEther(ethAmount) // 关键!
});
console.log(`Tx hash: ${tx.hash}`);
await tx.wait(); // 等待确认
console.log('已完成!区块高度:', tx.blockNumber);
关键词自然嵌入:智能合约调用, parseEther
// 如果合约有 getter
const afterBalance = await provider.getBalance(CONTRACT_ADDRESS);
console.log('合约余额:', ethers.utils.formatEther(afterBalance), 'ETH');
Gas估算失败兼容多数合约的保险写法:
const gasLimit = await contract.estimateGas.deposit({ value })ethers.js 会基于最新区块状态给出合理预估。ABI 漏写 payable如果 ABI 里没有标注
"payable": true,ethers.js 会拒绝在调用时附带value。请核对源码重新生成 ABI。主网 / 测试网地址混用主网地址放到 Goerli 上调用必定失败,先从区块浏览器确认 智能合约 部署在哪一行链。
👉 一图看懂 ethers.js 高级用法,避坑更快更安全!
假设合约规定:
每个地址最多买 3 个
每个 NFT 0.08 ETH
需要附带
quantity参数
const amount = 2;
const totalValue = (0.08 * amount).toString();
const tx = await contract.mint(amount, {
value: ethers.utils.parseEther(totalValue)
});
await tx.wait();
链上完成后,用户钱包 NFT 页立刻出现 2 枚新资产,交易哈希可直接在浏览器验证。
Q1:不写 { value } 会如何?A:合约内部的 msg.value 为零,若逻辑强制检查则会 revert,提示错误 not enough eth sent。
Q2:用户用浏览器钱包 MetaMask,也需要写 value 吗?A:前端 ethers.js 调用 contract.populateTransaction.deposit({ value }) 生成交易体,再由 MetaMask 签名即可。语法不变。
**Q3:可否一次往合约打钱但不调用函数(纯转账)?**A:可以,用 wallet.sendTransaction({ to: contractAddress, value }),但这种普通交易会触发合约的 receive();若合约没有 receive() 或 fallback(),会失败回滚。
通过上述 五步流程 与 踩坑清单,你已能在任何 evm 链上快捷、安全地把 以太币 发送到 智能合约函数。牢记两点:ABI 需标 payable,调用参数里加 value。如果只想要更清爽的“一条龙”方案,也可以基于 腾讯云区块链服务 TBaaS 快速部署测试网节点,无运维烦恼。
