代码之家  ›  专栏  ›  技术社区  ›  JDS

该代码会在我的合同中创建一致的数据存储吗?+如何正确使用记忆

  •  0
  • JDS  · 技术社区  · 3 年前

    我正在写一份简单的合同,作为一个社交媒体帖子样本网站的“后台”。从使用web3的前端网站,我将允许用户添加帖子,然后当网页加载时,我理想情况下希望阅读合同中保存的所有帖子(并显示在网站上)。一切( RegularPosts )应该持续存储。

    这是我的示例代码,我走对了吗?对Solidity来说非常陌生-

    pragma solidity >=0.7.0 <0.9.0;
    
    contract Storage {
    
        struct RegularPost {
            uint256 category;
            string name; 
            string post;
            address addr;
            uint256 date;
        }
        
        RegularPost[] public RegularPostArray;
    
        function addNewPost(uint256 _category, string memory _name, string memory _post, uint256 _date) public {
            RegularPostArray.push(RegularPost({category: _category, name: _name, post: _post, addr: msg.sender, date: _date}));
        }    
    
        function getRegularPosts() public view returns (RegularPost[] memory) {
            return RegularPostArray;
        }
            
    }
    

    所以有几个问题:

    • 这会持续存储一系列推送到的帖子吗?

    • 这种东西的存储限制是多少?

    • 我是在用手机吗 memory 关键词正确/根据需要?我需要用电脑吗 storage 关键词?

    • 什么时候 getRegularPosts() 被调用(例如通过web3),将返回什么?我能得到所有东西的JSON吗?我不确定我会收到什么。

    非常感谢您的帮助:)

    0 回复  |  直到 3 年前
        1
  •  1
  •   Petr Hejda    3 年前

    这会持续存储一系列推送到的帖子吗?

    对合同中没有任何重写或删除项目的代码,并且存储是持久的。


    这种东西的存储限制是多少?

    一个动态大小的存储阵列最多可以有 2^256 项,这是索引数据类型的限制( uint256 ).

    EVM存储器中的实际存储插槽位置是使用索引哈希和其他几个参数计算的(请参阅 docs )因此,理论上存在哈希冲突的可能性,但尚未在实践中得到证明。


    我是在用手机吗 memory 关键词正确/根据需要?我需要用电脑吗 storage 关键词?

    我猜你指的是 RegularPost[] memory 作为 getRegularPosts() return语句(而不是 string memory addNewPost() 函数参数)。

    这是一个正确的用法,因为 return 语句只能使用 记忆力 calldata 地方所以脚本会加载 RegularPostArray 从存储器到存储器,然后从存储器返回。

    使用 存储 当指向存储变量时,位置位于函数内部:

    function updatePost(uint256 _postIndex, uint256 _newCategory) external {
        // any changes to the `post`
        // will be stored in the `RegularPostArray[_postIndex]`
        RegularPost storage post = RegularPostArray[_postIndex];
        post.category = _newCategory;
    }
    

    但是如果你使用 记忆力 位置,Solidity与变量的内存副本一起工作,不更新存储:

    function notUpdatePost(uint256 _postIndex, uint256 _newCategory) external {
        // any changes to `post`
        // will NOT affect `RegularPostArray[_postIndex]`
        RegularPost memory post = RegularPostArray[_postIndex];
        post.category = _newCategory;
    }
    

    当调用getRegularPosts()时(例如通过web3),将返回什么?我能得到所有东西的JSON吗?我不确定我会收到什么。

    这取决于web3库实现(例如JavaScript库可以以与Python不同的结构返回数据)及其版本。但具体来说,如果 web3js@1.4.0 ,它是一个数组数组,其中每个内部数组都表示结构(其值被复制为数字索引和关联索引):

    [
      [
        '1',
        'a',
        'a',
        '0x86beB187A30265Ce437C0BB55f38aF21554659Ae',
        '1',
        category: '1',
        name: 'a',
        post: 'a',
        addr: '0x86beB187A30265Ce437C0BB55f38aF21554659Ae',
        date: '1'
      ],
      [
        '2',
        'b',
        'b',
        '0x86beB187A30265Ce437C0BB55f38aF21554659Ae',
        '2',
        category: '2',
        name: 'b',
        post: 'b',
        addr: '0x86beB187A30265Ce437C0BB55f38aF21554659Ae',
        date: '2'
      ]
    ]