Solidity - 为啥公共 Struct 变量的默认 getter 不会返回 Struct 中的每个变量

Posted

技术标签:

【中文标题】Solidity - 为啥公共 Struct 变量的默认 getter 不会返回 Struct 中的每个变量【英文标题】:Solidity - Why default getter of a public Struct variable doesn't return every variable inside StructSolidity - 为什么公共 Struct 变量的默认 getter 不会返回 Struct 中的每个变量 【发布时间】:2021-08-16 19:35:03 【问题描述】:

我目前正在学习 Solidity 语言,我注意到当我试图在我的 JS 代码中获取 Struct 的值时,Solidity 返回的每个变量都没有数组。 我必须创建自定义 getter 才能访问结构中的所有数据。

我制作了一个非常简单的合同示例,其中包含在构造函数中初始化的 Struct。

我正在使用我的自定义 getter 访问变量并在 JS 代码中生成一个。

Test.sol

pragma solidity ^0.8.4;

contract Test 

    struct Data 
        string foo;
        address[] bar;
        address ctrt;
    

    Data public d;

    constructor() 
        d.foo = "HELLO WORLD";
        d.bar.push(msg.sender);
        d.ctrt = address(this);
    

    function getD() public view returns (Data memory) 
        return d;
    

Test.js

const ethers = require('hardhat');

describe('Test', function () 
  it('should test something', async function() 
    const factory = await ethers.getContractFactory('Test')
    const test = await factory.deploy();
    console.log("Result from var:");
    console.log(await test.d());
    console.log("Result from getter:");
    console.log(await test.getD());
  )
);

控制台中的结果:

Result from var:
[
  'HELLO WORLD',
  '0x5FbDB2315678afecb367f032d93F642f64180aa3',
  foo: 'HELLO WORLD',
  ctrt: '0x5FbDB2315678afecb367f032d93F642f64180aa3'
]
Result from getter:
[
  'HELLO WORLD',
  [ '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ],
  '0x5FbDB2315678afecb367f032d93F642f64180aa3',
  foo: 'HELLO WORLD',
  bar: [ '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' ],
  ctrt: '0x5FbDB2315678afecb367f032d93F642f64180aa3'
]

如果数据的某些部分不可见,那么明确说变量是公共的有什么意义?

【问题讨论】:

【参考方案1】:

引用docs:

如果您有一个数组类型的公共状态变量,那么您只能通过生成的 getter 函数检索数组的单个元素。这种机制的存在是为了避免在返回整个数组时产生高gas成本。

这就是为什么当您使用 ethers.js 进行调用时看不到该值的原因。

解决方案是创建一个返回栏内容的getDataBar(uint i) 函数。

【讨论】:

以上是关于Solidity - 为啥公共 Struct 变量的默认 getter 不会返回 Struct 中的每个变量的主要内容,如果未能解决你的问题,请参考以下文章

智能合约实战 solidity 语法学习 03 [ 数据类型 bool uint address bytes enum mapping struct string ] 附代码

Solidity极简入门#5. 变量数据存储和作用域

solidity笔记(11)——struct用法——2021.5.19

Solidity极简入门#6. 引用类型

区块链实战如何创建一个带参数的智能合约

区块链实战如何创建一个带参数的智能合约