我有一个智能契约,定义了3到5个字符长的固定长度变量。
对于来自其他语言的变量来说,将这些变量定义为string更直观。此外,创建单元测试也更容易,因为我只需在调用契约函数时传递普通字符串。
function deposit(string memory _name, uint256 _amount) internal { ... }
await contract.deposit('John', 10);然而,我读到,正如我所知道的,这些是5个字符的固定长度变量,我们也可以将它们定义为bytes5而不是字符串。这使得测试更加冗长,因为您必须在比较时使转换字符串->bytes5和bytes5->字符串。
function deposit(bytes5 _name, uint256 _amount) internal { ... }
let stringToBytes5 = function (str: string) {
return ethers.utils.hexZeroPad(ethers.utils.toUtf8Bytes(str), 5);
}
let bytes5ToString = function (hexString: string) {
return ethers.utils.toUtf8String(hexString);
}
await contract.deposit(stringToBytes5('John'), 10);所以我想知道在气体/性能/尺寸方面,使用bytes5是否真的值得.与使用字符串相比。
发布于 2022-12-11 01:38:39
根据可靠的文件:
您应该在bytes1[]上使用字节,因为它更便宜,因为在内存中使用bytes1[]会在元素之间添加31个填充字节。请注意,在存储中,由于包装紧凑,没有填充,请参阅字节和字符串。通常情况下,对任意长度的原始字节数据使用字节,对任意长度的字符串(UTF-8)使用字符串.如果可以将长度限制为一定数量的字节,请始终使用bytes1到bytes32的值类型之一,因为它们要便宜得多。类型字节和字符串的变量是特殊的数组。字节类型类似于bytes1[],但它被紧密地封装在回调数据和内存中。字符串等于字节,但不允许长度或索引访问。
因此,如果可以的话,您应该使用bytes5而不是string,只要您确定这样定义的固定长度变量不会超过5个字符长。
发布于 2022-12-11 03:11:49
使用字节比使用字符串更有效,因为它们在内存中被打包得更密集,从而减少了气体的使用,减少了契约大小。因为字符串是动态大小的,字节有固定的大小.
但是在您的情况下,无论您使用字符串还是bytes5,对于一个总长度为5个字符的变量来说,可能没有什么大的区别。气体使用量和合同大小的差异很可能很小,如果您使用字符串而不是字节,其他人可能会更直观地阅读和处理您的合同。
在合同中是使用字符串还是使用bytes5的决定将取决于您的特定用例和需求。您可能需要考虑使用这两种类型的变量对您的合同进行基准测试,看看哪一种在气体使用和合同大小方面表现得更好。
在决定是否在契约中使用字符串或字节时,应考虑以下几点:
一个示例对不同的变量同时使用字符串和字节:
pragma solidity ^0.5.0;
contract Example {
// Use a string to store a user's name
string name;
// Use bytes32 to store a fixed-size hash
bytes32 hash;
// Use address to store an Ethereum address
address owner;
function setName(string memory _name) public {
name = _name;
}
function setHash(bytes32 _hash) public {
hash = _hash;
}
function setOwner(address _owner) public {
owner = _owner;
}
function getName() public view returns (string memory) {
return name;
}
function getHash() public view returns (bytes32) {
return hash;
}
function getOwner() public view returns (address) {
return owner;
}
}希望我能解释清楚。
https://ethereum.stackexchange.com/questions/140977
复制相似问题