solidity - Solidity 中的状态变量是什么?

标签 solidity

我读了一些关于存储内存 View pure的文档,但我不完全了解理解他们。我有以下代码:

contract {
    struct Random {
        uint32 state;
        uint8 i;
    }

    function main() pure internal {
        Random rand = Random(seed, 0);
        ...
    }

    function get_rand(Random rand, uint8 n) pure internal returns (uint16) {
        assert(n <= 16)
        while (true) {
            if (rand.i >= 8) {
                rand.state = xorshift32(rand.state);
                rand.i = 0;
            }

            uint8 r = uint8(rand.state >> (rand.i << 4)) & 0x0f;
            rand.i += 1;

            if (r < n) {
                return r;
            }
        }
    }
}

我的问题是:

1) 我应该在 main 中为局部变量标记 storage 还是 memory 吗?我应该为 get_rand 中的参数标记什么?

2)突变会起作用吗?比如说,我读到纯函数无法更改状态变量,并且内存变量会被复制。将两者标记为存储就足够了吗?如果 get_rand 改变了参数,我还应该声明 pure 吗?

谢谢

最佳答案

viewpure 是函数修饰符,描述该函数中的逻辑如何与合约状态交互。如果您的合约要从存储中读取,但不写入,则可以使用 view (或 constant 完全相同)修饰符(请参阅 view functions documentation )。如果您不打算从合约状态读取或写入,并且您所做的一切仅适用于内存变量,那么它就是 pure function

Should I mark storage or memory for the local variable in main? And what should I mark for the argument in get_rand?

默认情况下,结构是 storage 变量,它将尝试将您的结构写入状态。这是你需要小心的地方,因为如果你在应该使用 storage 的地方使用 memory 变量,你实际上可以覆盖你的状态。示例:

contract C {
  uint _var;

  function f() public {
    Random r;
    ...
  }
}

在本例中,r 是未初始化的存储指针,这导致变量指向存储槽 0。当您在结构体中设置某个变量 ( r.state = 100; ) 时,它会将该值写入槽 0,覆盖 _var 处的值。

当您想要创建一个新结构体作为局部变量时,您需要使用 memory 修饰符,然后将其设置为状态变量(或将其添加到状态映射/数组)。当您想要将结构从映射/数组读取到局部变量中时,请使用 storage

根据您提供的示例,您希望将其设置为 memory 变量。 非常仔细阅读 Solidity 文档的 this section

Will the mutation work? Say, I read that a pure function cannot change state variables, and memory variables are copied. Is marking both as storage enough? Should I still declare pure for get_rand if it changes its argument?

不,它不会改变您的契约(Contract)状态。虽然局部结构变量默认为 storage,但函数参数默认始终为 memory(即使是结构)。修改rand内部的get_rand不会修改任何状态。如果您将函数更改为访问状态,则会因 pure 修饰符而收到编译错误。

关于solidity - Solidity 中的状态变量是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49613580/

相关文章:

solidity - Remix 上没有自动完成/代码完成功能?

solidity - 当我有回退功能时,为什么 Solidity 建议我实现接收以太功能?

Solidity 错误 : Expected identifier, 得到 'LParen'

blockchain - 如何删除保存在 IPFS 区 block 链中的图像?

ethereum - 如何检查从地址到智能合约的eth转移

c++ - 从 Ethereum solidity 合约运行 C++ 脚本

random - Solidity - 生成不依赖于输入的不可预测的随机数

solidity - solidity 函数中的大括号

reactjs - 警告 : Do not use <img> element. 使用 next/image 中的 <Image/> 代替

ethereum - 只读函数迭代成本