无法以大数字作为参数从 web3 调用合约函数
Posted
技术标签:
【中文标题】无法以大数字作为参数从 web3 调用合约函数【英文标题】:Unable to call contract function from web3 with big number as parameter 【发布时间】:2020-09-29 18:33:24 【问题描述】:您好,我正在尝试调用需要 unit256 参数的合同的自定义函数。
我用这个值作为参数从 web3 调用这个函数:10000000000000000000(10 有 18 个零) 一旦这个调用被 web3 击中,我就会遇到以下 Big number 错误:
错误:溢出(fault="overflow", operation="BigNumber.from", value=10000000000000000000, code=NUMERIC_FAULT, version=bignumber/5.0.0-beta.138)
有人知道原因吗?
这是我正在调用的合约的功能:
function lock(
address tokenAddress,
uint256 amount
)
这里是 web3 代码 sn-p:
Contract.methods.lock(0x57AA33D53351eA4BF00C6F10c816B3037E268b7a, 10000000000000000000,
).send(
from: accounts[0],
gasLimit: 500000,
value: 0
);
我尝试了相同的功能,但金额较小,它可以工作,例如1(有 18 个零)
【问题讨论】:
【参考方案1】:我尝试将参数作为字符串发送,它成功了。
发布此答案,因此可能对某人有所帮助。
【讨论】:
我在运行华夫饼测试时遇到了这个错误:expect(await vrfContract.getHardcodedUintNumber()).to.be.equal(18446205110165755834005948204546580960626098221936403173208959885300094367089);
,我对答案有点困惑,因为我认为(并认为)它暗示:“将 uint256
作为字符串返回函数”,即使在我的情况下,它应该返回一个 uint256。但是,将预期的数字放在双引号中解析(作为字符串):expect(await vrfContract.getHardcodedUintNumber()).to.be.equal("18446205110165755834005948204546580960626098221936403173208959885300094367089");
【参考方案2】:
我在 Truffle UnitTest 中使用 BigInt
it('should return correct balances when transfer', async () =>
const receiver = accounts[2];
const balanceOfOwner = await contractInstance.balanceOf.call(owner);
assert.equal(balanceOfOwner, totalSupply * 10 ** decimals, 'Total balance');
const sendAmount = 69 * 10 ** decimals;
await contractInstance.transfer(receiver, BigInt(sendAmount),
from: owner,
);
const balanceOfReceiver = await contractInstance.balanceOf.call(receiver);
assert.equal(balanceOfReceiver, sendAmount, 'Received sendAmount');
assert.equal(
await contractInstance.balanceOf.call(owner),
balanceOfOwner - sendAmount,
'Decreased to'
);
);
【讨论】:
【参考方案3】:原因可以在ethers包的文档中找到:
为什么我不能只使用数字? 许多人在处理以太坊时遇到的第一个问题是数字的概念。大多数常见货币的细分粒度很小。例如,一美元只有 100 美分。但是,一个以太币中有 1018 个wei。 javascript 使用 IEEE 754 双精度二进制浮点数来表示数值。结果,在9,007,199,254,740,991之后的整数集中有空洞;这对以太坊来说是有问题的,因为它只有大约 0.009 以太(以 wei 为单位),这意味着任何超过该值的值都将开始出现舍入错误。 (...) 为了解决这个问题,所有数字(可能很大)都作为大数字进行存储和操作。
【讨论】:
以上是关于无法以大数字作为参数从 web3 调用合约函数的主要内容,如果未能解决你的问题,请参考以下文章