solidity测试脚本:小心js里坑爹的数值计算

版权声明:版权所有。转载请注明出处:扶风的博客 https://blog.csdn.net/JohnnyMartin/article/details/83023834

前天在调试solidity代码时,发现一个极为诡异的行为:solidity中存数的数值,当使用web3取出的时候,数值是错的——与solidity中的值对不上!
solidity中的代码大概是这样的:

mapping (uint => uint) public data;
...
data[0] = 9901538745632159654;
data[data[0]] = 5901538745632159654;
...

测试脚本是这样的:

let begin= await MyContract.data(0);
let next = await MyContract.data(begin.toNumber());
console.log("next :", next.toNumber());

结果发现next的值一直是0,而不是正确的5901538745632159654!

当我将begin这样打出来之后,一切都了然了:

console.log("begin toNumber:", begin.toNumber(), ", begin toString:", begin.toString());

输出:

begin toNumber: 9901538745632160000, begin toString:9901538745632159654 

在toNumber的过程中损失了精度!正确的测试代码应该这样写——避免使用toNumber:

let begin= await MyContract.data(0);
let next = await MyContract.data(begin);
console.log("next :", next.toString());

总结:

在需要nodejs与solidity有数据交互的时候,尽量避免使用toNumber,打日志的时候使用toString,js传参数给solidity的时候直接使用BigNumber,假如要在js中进行算数计算,应直接使用BigNumber的相关方法诸如plus进行算数计算。

后记:

之前solidity中使用的数据一直是比较整的,像这样

data[0] = 1000000000000000000;
data[data[0]] = 3000000000000000000;

这样的数据经过toNumber操作之后也是不会出问题的,只有零头比较长的数据才会如此,就像9901538745632159654这种。

猜你喜欢

转载自blog.csdn.net/JohnnyMartin/article/details/83023834
今日推荐