ethereum - 此代码是否会在我的合约中创建一致的数据存储?+ 如何正确使用内存
问题描述
我正在编写一份简单的合同作为示例社交媒体帖子网站的“后端”。从一个使用 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 吗?我不确定我会收到什么。
非常感谢您的帮助:)
解决方案
这会持续存储推送到的一系列帖子吗?
是的。合约没有任何可以重写或删除项目的代码,并且存储是持久的。
像这样的东西的存储限制是多少?
一个动态大小的存储数组最多可以有2^256
多个项目,这是索引数据类型 ( uint256
) 的限制。
EVM 存储中的实际存储槽位置是使用索引的散列和一些其他参数(请参阅文档)计算的,因此理论上存在散列冲突的可能性,但在实践中尚未得到证实。
我
memory
是否正确/根据需要使用关键字?我需要使用storage
关键字吗?
我假设您的意思是RegularPost[] memory
作为getRegularPosts()
return 语句的一部分(而不是string memory
在addNewPost()
函数参数中)。
这是一个正确的用法,因为return
语句只能使用memory
或calldata
位置。所以脚本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'
]
]
推荐阅读
- ios - 设备无法使用 Firebase 身份验证电话号码
- r - 将日期变成有序变量
- tensorflow - 我已经安装了 tensorflow,但在导入 tensorflow 时仍然遇到错误
- python - 如何在不使用表单的情况下通过 django 中的 html 模板将数据发布到数据库中
- javascript - 如何让 css 影响最终结果?
- prolog - 如何获得所需的输出
- java - 当用户触摸屏幕上的任意位置时,如何一一填充回收站视图?
- pdf - Ghostscript PDF to PCL 将像素推到顶部
- javascript - 为什么 "\a" 和 "a" 在 JavaScript 中是一样的?
- corda - java.lang.IllegalArgumentException:未为以下事务参与者提供流会话: