此代码是否会在我的合约中创建一致的数据存储? + 如何正确使用内存
Will this code create consistent storage of data in my contract? + How to use memory properly
我正在编写一个简单的合同作为示例社交媒体帖子网站的“后端”。在使用 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
关键字 properly/as?我需要使用 storage
关键字吗?
当调用 getRegularPosts()
时(例如通过 web3),究竟会返回什么?我(我能)得到所有东西的 JSON 吗?我不确定我会收到什么。
非常感谢您的帮助:)
Will this persistently store an array of posts as pushed to?
是的。合约没有任何重写或删除项目的代码,并且存储是持久的。
What is the storage limit on something like this?
一个动态大小的存储数组最多可以有 2^256
个项目,这是索引数据类型的限制 (uint256
)。
EVM 存储中的实际存储槽位置是使用索引的散列和其他一些参数计算的(参见 docs),因此理论上存在散列冲突的可能性,但它没有'尚未在实践中得到证明。
Am I using the memory
keyword properly/as needed? Do I need to use the storage
keyword?
我假设你的意思是 RegularPost[] memory
作为 getRegularPosts()
return 语句的一部分(而不是 addNewPost()
函数参数中的 string memory
).
这是正确的用法,因为return
语句只能使用memory
或calldata
位置。因此脚本将 RegularPostArray
从存储器加载到内存,然后 return 从内存加载它。
当您指向存储变量时,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;
}
When getRegularPosts() is called (via e.g. web3), what exactly will be returned? Will I (can I) get a JSON of everything? I'm not sure what I will receive.
这取决于 web3 库的实现(例如 JavaScript 库可以 return 与 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'
]
]
我正在编写一个简单的合同作为示例社交媒体帖子网站的“后端”。在使用 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
关键字 properly/as?我需要使用storage
关键字吗?当调用
getRegularPosts()
时(例如通过 web3),究竟会返回什么?我(我能)得到所有东西的 JSON 吗?我不确定我会收到什么。
非常感谢您的帮助:)
Will this persistently store an array of posts as pushed to?
是的。合约没有任何重写或删除项目的代码,并且存储是持久的。
What is the storage limit on something like this?
一个动态大小的存储数组最多可以有 2^256
个项目,这是索引数据类型的限制 (uint256
)。
EVM 存储中的实际存储槽位置是使用索引的散列和其他一些参数计算的(参见 docs),因此理论上存在散列冲突的可能性,但它没有'尚未在实践中得到证明。
Am I using the
memory
keyword properly/as needed? Do I need to use thestorage
keyword?
我假设你的意思是 RegularPost[] memory
作为 getRegularPosts()
return 语句的一部分(而不是 addNewPost()
函数参数中的 string memory
).
这是正确的用法,因为return
语句只能使用memory
或calldata
位置。因此脚本将 RegularPostArray
从存储器加载到内存,然后 return 从内存加载它。
当您指向存储变量时,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;
}
When getRegularPosts() is called (via e.g. web3), what exactly will be returned? Will I (can I) get a JSON of everything? I'm not sure what I will receive.
这取决于 web3 库的实现(例如 JavaScript 库可以 return 与 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'
]
]