使用Hardhat Ethers.js调用带参数Payable函数报错求助
Solidity Payable函数调用问题:同时传参和ETH金额报错解决
问题场景
Solidity合约代码
function Deposit(uint256 StopLoss) public payable {//Deposita quantity i es registre //Pay subscription if (msg.value == 0){ revert Quantity_zero(); } //Add wallet to the s_Wallets s_Wallets.push(payable(msg.sender)); //Start subscription time Dades storage dades = s_Registre[msg.sender]; dades.Quantity += msg.value; dades.Stop = StopLoss; }
Hardhat测试代码
describe("Subscription", async function () {//PriceConversion it("Subscribes the deployer", async function () { await MarketOrder.Deposit(1850, {value: ethers.utils.parseEther("5")}) const Quantity = await MarketOrder.CallQuantity() console.log(`Q: ${Quantity}`) const Stop = await MarketOrder.CallStop() console.log(`S: ${Stop}`) assert.equal(Quantity.toString(), 1850) assert.equal(Stop.toString(), 5) } })
触发的错误信息
1) MarketOrder Unit Tests Subscription Subscribes the deployer: Error: invalid BigNumber value (argument="value", value=[1850], code=INVALID_ARGUMENT, version=bignumber/5.6.2) at Logger.makeError (node_modules/@ethersproject/logger/src.ts/index.ts:261:28) at Logger.throwError (node_modules/@ethersproject/logger/src.ts/index.ts:273:20) at Logger.throwArgumentError (node_modules/@ethersproject/logger/src.ts/index.ts:277:21) at Function.BigNumber.from (node_modules/@ethersproject/bignumber/src.ts/bignumber.ts:289:23) at NumberCoder.encode (node_modules/@ethersproject/abi/src.ts/coders/number.ts:25:27) at /home/oriok/hh-ff/1.uniswapV3/node_modules/@ethersproject/abi/src.ts/coders/array.ts:71:19 at Array.forEach (<anonymous>) at pack (node_modules/@ethersproject/abi/src.ts/coders/array.ts:54:12) at TupleCoder.encode (node_modules/@ethersproject/abi/src.ts/coders/tuple.ts:54:20) at AbiCoder.encode (node_modules/@ethersproject/abi/src.ts/abi-coder.ts:111:15) error Command failed with exit code 1.
错误原因与解决方案
1. 参数编码类型不匹配
错误提示显示参数编码时BigNumber类型无效,核心原因是uint256类型参数最好显式转换为ethers的BigNumber格式,同时要确保合约函数名大小写完全匹配(Solidity大小写敏感)。
2. 测试断言逻辑完全反转
从Solidity代码逻辑可知:
dades.Quantity存储的是存入的ETH金额(msg.value对应的wei值),而非StopLoss参数1850dades.Stop存储的是传入的StopLoss参数1850,而非ETH金额5
修正后的测试代码
describe("Subscription", async function () { it("Subscribes the deployer", async function () { // 显式转换参数为BigNumber,适配Solidity的uint256类型 const stopLoss = ethers.BigNumber.from(1850); const depositAmount = ethers.utils.parseEther("5"); // 调用payable函数,参数在前,交易选项(value)在后 await MarketOrder.Deposit(stopLoss, { value: depositAmount }); const Quantity = await MarketOrder.CallQuantity(); console.log(`Q: ${Quantity}`); const Stop = await MarketOrder.CallStop(); console.log(`S: ${Stop}`); // 修正断言逻辑,匹配合约存储规则 assert.equal(Quantity.toString(), depositAmount.toString()); assert.equal(Stop.toString(), stopLoss.toString()); }); });
额外检查点
- 确认合约中
Quantity_zero自定义错误已正确声明,避免隐性报错 - 验证
CallQuantity和CallStop函数的实现,确保它们正确返回对应存储值
内容的提问来源于stack exchange,提问作者Oriok
相关产品推荐
相关产品推荐

