useDapp 和 hardhat 从智能合约返回不同的值
useDapp and hardhat returning different values from smart contract
我有一个使用 Hardhat 的本地测试网节点。我可以使用普通 javascript、async await
和 const { ethers, upgrades } = require("hardhat");
.
成功部署和测试我的合约
我正确地返回并打印到控制台,一个 BigNumber 数组,其中包含来自合约函数的 2 个元素。
但是 useDapp 函数调用 returns 不同的值。
我什么都试过了:JSON.stringify(array)
returns [[]]
, array[0]
returns undefined, BigNumber.from(array).toNumber
有点疯狂 BigNumber
错误等。但我知道合同给了它正确的值。
为什么我在 2 个不同的 javascript 文件中得到 2 个不同的值?我假设安全帽测试文件检索值的方式与 useDapp 相比存在问题。
我的 useDapp 前端钩子看起来像这样 returns [Array(0)]
和 length: 1
:
export function useGetArray(): BigNumber[] | undefined {
const {value,error}: any = useCall({
contract: new Contract(myContract, myInterface),
method: "getArray",
args: [],
}) ?? [];
if(error) {
return error;
} else {
return value;
};
}
我的安全帽 javascript 测试看起来像这样 returns [ BigNumber { value: "50" }, BigNumber { value: "129" } ]
:
CONTRACT = await ethers.getContractFactory("CONTRACT");
const contract = await CONTRACT.attach("0x109d198fca64d33Bd9F33E60333A544412cfAC7D");
array = await contract.getArray();
console.log(array);
请注意,另外 2 个使用 useDapp 的几乎相同的函数调用,其中一个甚至将数据传递给合同,工作完全正常。所以问题不在于正在使用的地址或导入的 ABI。
感谢任何帮助,谢谢。
对于任何对此感到非常困惑的人,我相信这在未来 EVM 智能合约开发人员中会很常见,hardhat 默认网络测试与针对主网分叉的测试将 return 不同的数字类型合同。
例如,使用默认网络的常规 .js
测试文件,return从合同中获取 uint256[]
将是常规整数外观数字。
但是对于主网分支,returning uint256[]
将 return 一个 BigNumber
数组,javascript 很难分解。您将需要一个 BigNumber 包来使用它。似乎主网分支 .js
交互需要获取数组的第一个元素 Array[0]
,并且该元素内部将是每个 BigNumber
对象,进一步需要用 [=17] 之类的东西解码=].
注意:关于将数字发送到合约中,您需要确保在处理任何代币值时注意代币的小数位。例如,如果一个令牌在合约中编程了 6 个小数位,并且你想向合约发送一个代表 600 个硬币的值,你需要发送 600000000(600 添加 6 个 0)或 BigNumber.from(600000000)
。我不确定在将其发送到合约之前将其转换为 BigNumber
类型是否可以节省 gas 或其他东西,因为转换是链下的,但似乎您可以将任何一个数字发送到合约中。您只需要确保根据您正在使用的令牌将 0 添加到数字的末尾。
我有一个使用 Hardhat 的本地测试网节点。我可以使用普通 javascript、async await
和 const { ethers, upgrades } = require("hardhat");
.
我正确地返回并打印到控制台,一个 BigNumber 数组,其中包含来自合约函数的 2 个元素。
但是 useDapp 函数调用 returns 不同的值。
我什么都试过了:JSON.stringify(array)
returns [[]]
, array[0]
returns undefined, BigNumber.from(array).toNumber
有点疯狂 BigNumber
错误等。但我知道合同给了它正确的值。
为什么我在 2 个不同的 javascript 文件中得到 2 个不同的值?我假设安全帽测试文件检索值的方式与 useDapp 相比存在问题。
我的 useDapp 前端钩子看起来像这样 returns [Array(0)]
和 length: 1
:
export function useGetArray(): BigNumber[] | undefined {
const {value,error}: any = useCall({
contract: new Contract(myContract, myInterface),
method: "getArray",
args: [],
}) ?? [];
if(error) {
return error;
} else {
return value;
};
}
我的安全帽 javascript 测试看起来像这样 returns [ BigNumber { value: "50" }, BigNumber { value: "129" } ]
:
CONTRACT = await ethers.getContractFactory("CONTRACT");
const contract = await CONTRACT.attach("0x109d198fca64d33Bd9F33E60333A544412cfAC7D");
array = await contract.getArray();
console.log(array);
请注意,另外 2 个使用 useDapp 的几乎相同的函数调用,其中一个甚至将数据传递给合同,工作完全正常。所以问题不在于正在使用的地址或导入的 ABI。
感谢任何帮助,谢谢。
对于任何对此感到非常困惑的人,我相信这在未来 EVM 智能合约开发人员中会很常见,hardhat 默认网络测试与针对主网分叉的测试将 return 不同的数字类型合同。
例如,使用默认网络的常规 .js
测试文件,return从合同中获取 uint256[]
将是常规整数外观数字。
但是对于主网分支,returning uint256[]
将 return 一个 BigNumber
数组,javascript 很难分解。您将需要一个 BigNumber 包来使用它。似乎主网分支 .js
交互需要获取数组的第一个元素 Array[0]
,并且该元素内部将是每个 BigNumber
对象,进一步需要用 [=17] 之类的东西解码=].
注意:关于将数字发送到合约中,您需要确保在处理任何代币值时注意代币的小数位。例如,如果一个令牌在合约中编程了 6 个小数位,并且你想向合约发送一个代表 600 个硬币的值,你需要发送 600000000(600 添加 6 个 0)或 BigNumber.from(600000000)
。我不确定在将其发送到合约之前将其转换为 BigNumber
类型是否可以节省 gas 或其他东西,因为转换是链下的,但似乎您可以将任何一个数字发送到合约中。您只需要确保根据您正在使用的令牌将 0 添加到数字的末尾。