此代码是不是会在我的合约中创建一致的数据存储? + 如何正确使用内存
Posted
技术标签:
【中文标题】此代码是不是会在我的合约中创建一致的数据存储? + 如何正确使用内存【英文标题】:Will this code create consistent storage of data in my contract? + How to use memory properly此代码是否会在我的合约中创建一致的数据存储? + 如何正确使用内存 【发布时间】:2021-12-12 09:26:28 【问题描述】:我正在编写一个简单的合同作为示例社交媒体帖子网站的“后端”。从一个使用 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 吗?我不确定我会收到什么。
非常感谢您的帮助:)
【问题讨论】:
【参考方案1】:这会持久存储推送到的帖子数组吗?
是的。合约没有任何代码会重写或删除项目,并且存储是持久的。
这样的存储限制是多少?
动态大小的存储数组最多可以有2^256
项,这是索引数据类型的限制 (uint256
)。
EVM 存储中的实际存储槽位置是使用索引的哈希和一些其他参数计算的(请参阅docs),因此理论上存在哈希冲突的可能性,但尚未在练习。
我是否正确/根据需要使用了
memory
关键字?我需要使用storage
关键字吗?
我假设您的意思是 RegularPost[] memory
作为 getRegularPosts()
返回语句的一部分(而不是 addNewPost()
函数参数中的 string memory
)。
这是一个正确的用法,因为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'
]
]
【讨论】:
以上是关于此代码是不是会在我的合约中创建一致的数据存储? + 如何正确使用内存的主要内容,如果未能解决你的问题,请参考以下文章
如何将在我的 Javascript 中创建的字符串数组传递给 C# 代码隐藏文件?
我正在尝试在 phpmyadmin 中创建一个 sql 表,但出现 4 个错误。此代码在我工作时在我的电脑上的 phpmyadmin 中有效,但在家里的电脑上无效[关闭]