使用Ethers.js调用智能合约receive函数转账ETH的方法疑问
你遇到的报错是因为 Ethers.js 的 Contract 实例本身没有内置的 send 方法,该写法不符合 Ethers.js 的 API 规范。
要触发合约的 receive 函数,本质是向合约地址发起一笔不携带任何调用数据的ETH转账,有两种常用实现方式:
方案1:直接使用签名者发起转账(最常用)
receive 函数会在合约收到普通ETH转账时自动触发,你直接用当前连接的签名者向合约地址转ETH即可,修改你的转账逻辑代码如下:
async function transfer() { if(typeof window.ethereum !== 'undefined') { const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); // 不需要调用合约方法,直接用签名者向合约地址转ETH const transaction = await signer.sendTransaction({ to: WalletAddress, // 你的合约地址 // 注意:value单位是wei,如果你的amount是ETH为单位的数值,需要转成wei value: ethers.utils.parseEther(amount.toString()) }) await transaction.wait(); alert('ok'); setAmount(''); getBalance(); } }
方案2:使用Contract实例的sendTransaction方法
Ethers.js 的 Contract 实例提供了专门的 sendTransaction 方法,用来触发合约的 receive 或 fallback 函数,修改代码如下:
async function transfer() { if(typeof window.ethereum !== 'undefined') { const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); const contract = new ethers.Contract(WalletAddress, Wallet.abi, signer); const transaction = await contract.sendTransaction({ value: ethers.utils.parseEther(amount.toString()) }) await transaction.wait(); alert('ok'); setAmount(''); getBalance(); } }
注意事项
- 单位转换:Ethers.js 中交易的
value字段单位为wei,如果你前端输入的amount是以ETH为单位的数值,必须通过ethers.utils.parseEther转换为wei单位,否则会出现转账金额错误的问题 - 不需要额外传入
from参数,你使用signer发起交易时,from会默认使用签名者对应的钱包地址
内容的提问来源于stack exchange,提问作者Ben BK
相关产品推荐
相关产品推荐

