在ethers.js中,为什么函数的返回值是包含值的数组而不是值本身?

huangapple go评论137阅读模式
英文:

In ethers.js, why does the return value of a function return an array containing the value instead of the value?

问题

以下是要翻译的内容:

The assertion for the following test fails:
以下测试的断言失败:

    it('should access MAX_COUNT', async () => {
        const maxCount = await myContract.functions.MAX_COUNT();
        expect(maxCount).to equal(64);
    });

With the following error:
出现以下错误:

AssertionError: expected [ BigNumber { value: "64" } ] to equal 64

This is the solidity code for (the concise version of) the smart contract being tested:
这是被测试的智能合约(简化版本)的Solidity代码:

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

contract MyContract
{
    uint256 public constant MAX_COUNT = 64;
}

Why is the return value [ BigNumber { value: "64" } ] instead of just BigNumber { value: "64" }?
为什么返回值是 [ BigNumber { value: "64" } ] 而不只是 BigNumber { value: "64" }

英文:

The assertion for the following test fails:

    it('should access MAX_COUNT', async () => {
        const maxCount = await myContract.functions.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

With the following error:

AssertionError: expected [ BigNumber { value: "64" } ] to equal 64

This is the solidity code for (the concise version of) the smart contract being tested:

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;

contract MyContract
{
    uint256 public constant MAX_COUNT = 64;
}

Why is the return value [ BigNumber { value: "64" } ] instead of just BigNumber { value: "64" }?


For context, this question was originally created while trying to figure out this one:
How to correctly import @nomicfoundation/hardhat-chai-matchers into hardhat project? ...
However turns out to be completely unrelated.

答案1

得分: 2

这个测试应该失败:

    it('应该访问MAX_COUNT', async () => {
        const maxCount = await multiSend.functions.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

然而,这个应该通过:

    it('应该访问MAX_COUNT', async () => {
        const maxCount = await multiSend.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

而且这个测试也应该通过:

    it('应该访问MAX_COUNT', async () => {
        const [maxCount] = await multiSend.functions.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

线索在文档中,具体来说是通过Contract.functions.XYZ()Contract.XYZ()调用时返回类型之间的差异:

用于Contract.functions调用的文档

总结一下,Contract.XYZ()返回的是Promise<any>Promise<Result>;而Contract.functions.XYZ()始终返回Promise<Result>

用于Result返回类型的文档

Result对象设计用于可以返回多个值等的函数,这就是为什么需要对其进行数组解构。

英文:

This test should fail:

    it(&#39;should access MAX_COUNT&#39;, async () =&gt; {
        const maxCount = await multiSend.functions.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

However, this should pass:

    it(&#39;should access MAX_COUNT&#39;, async () =&gt; {
        const maxCount = await multiSend.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

And this test should pass too:

    it(&#39;should access MAX_COUNT&#39;, async () =&gt; {
        const [maxCount] = await multiSend.functions.MAX_COUNT();
        expect(maxCount).to.equal(64);
    });

The clue is in the documentation,
specifically the difference between the return types
when called via Contract.functions.XYZ() vs Contract.XYZ():

docs for Contract.functions call

In summary Contract.XYZ() returns either Promise&lt; any &gt; or Promise&lt; Result &gt;;
whereas Contract.functions.XYZ() always returns Promise&lt; Result &gt;

docs for Result return type

The Result object is designed for functions that can return multiple values etc, so that's why it it needs to be array-destructured.

huangapple
  • 本文由 发表于 2023年3月9日 15:28:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75681555.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定