首页 > 解决方案 > 此代码是否会在我的合约中创建一致的数据存储?+ 如何正确使用内存

问题描述

我正在编写一份简单的合同作为示例社交媒体帖子网站的“后端”。从一个使用 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;
    }
        
}

所以有几个问题:

非常感谢您的帮助:)

标签: ethereumsolidityweb3

解决方案


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

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


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

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

EVM 存储中的实际存储槽位置是使用索引的散列和一些其他参数(请参阅文档)计算的,因此理论上存在散列冲突的可能性,但在实践中尚未得到证实。


memory是否正确/根据需要使用关键字?我需要使用storage关键字吗?

我假设您的意思是RegularPost[] memory作为getRegularPosts()return 语句的一部分(而不是string memoryaddNewPost()函数参数中)。

这是一个正确的用法,因为return语句只能使用memorycalldata位置。所以脚本RegularPostArray从存储加载到内存,然后从内存中返回。

storage当您指向存储变量时,位置的示例使用在函数内部:

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;
}

但是,如果您使用memory位置,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'
  ]
]

推荐阅读