Solidity测试中如何计算交易手续费并修正余额断言逻辑
拍卖合约测试余额断言修复方案
问题背景
用Solidity开发拍卖交易智能合约,通过Ganache本地链测试,测试脚本采用JavaScript编写。流程为卖家创建拍卖,买家1、买家2参与出价,卖家完成交易后获取最优出价金额。但测试中验证交易前后卖家余额的断言因Gas费用消耗失败,需修正余额计算逻辑以确保断言通过。
错误原因
原测试代码存在两处关键问题:
- 计算预期余额时,错误直接扣除
gasUsed(Gas使用数量),但实际Gas花费应为gasUsed * gasPrice(即gasCost,消耗的ETH金额) - 对BN对象的同步运算添加了多余的
await,导致计算逻辑异常
修正后的测试代码片段
it("should make transaction", async()=> { await auctionExchange.createAuction(auction.name, auction.description, auction.min); const bestOffer = web3.utils.toBN(auction.min + 10); // 创建买家出价 await auctionExchange.createOffer(1, {from: buyer1, value: auction.min}); await auctionExchange.createOffer(1, {from: buyer2, value: bestOffer}); // 获取交易前卖家余额 const balanceBefore = web3.utils.toBN(await web3.eth.getBalance(seller)); console.log("Seller's balance before:", balanceBefore.toString()); //执行交易 const tx = await auctionExchange.transaction(1, { from: accounts[0] }); // 获取交易回执计算Gas成本 const receipt = await web3.eth.getTransactionReceipt(tx.tx); const gasUsed = web3.utils.toBN(receipt.gasUsed); const gasPrice = web3.utils.toBN(await web3.eth.getGasPrice()); const gasCost = gasUsed.mul(gasPrice); console.log("Gas Cost:", gasCost.toString()); // 获取交易后卖家余额 const balanceAfter = web3.utils.toBN(await web3.eth.getBalance(seller)); console.log("Seller's balance after:", balanceAfter.toString()); // 修正预期余额计算:余额前值 + 最优出价 - 实际Gas成本,移除多余await const expectedPrice = balanceBefore.add(bestOffer).sub(gasCost); console.log("Expected Price:", expectedPrice.toString()); assert(balanceAfter.eq(expectedPrice)); });
关键修正点
- 将
sub(gasUsed)替换为sub(gasCost):实际消耗的ETH是Gas使用量乘以Gas价格,而非单纯的Gas数量 - 移除
expectedPrice计算中的await:balanceBefore和bestOffer均为已初始化的BN对象,其运算为同步操作,无需异步等待
验证说明
修正后,预期余额的计算逻辑与链上实际余额变化完全匹配:卖家最终余额 = 交易前余额 + 最优出价金额 - 交易消耗的Gas总成本,断言函数将成功验证余额一致性。
内容的提问来源于stack exchange,提问作者Huzaifa Ahmed
相关产品推荐
相关产品推荐

