solidity 中的状态变量是什么?

what are state variables in solidity?

我阅读了一些关于 storagememoryviewpure 的文档,但我并不完全理解它们。我有以下代码:

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) 突变会起作用吗?说,我读到 pure 函数不能更改状态变量,并且会复制内存变量。将两者都标记为 storage 就足够了吗?如果 get_rand 改变了它的论点,我还应该声明 pure 吗?

谢谢

状态变量是永久存储在合约存储中的值。它们在契约范围内和函数范围外声明。像这样:

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData; // State variable
    // ...
}

所以合约的整体层次结构是这样的:

Contract
--/ State Variables
--/ Functions

除此之外,我真的不明白你在问什么。也许你应该问清楚,并在不同的问题中,而不是在一个问题中含糊地问所有问题。

viewpure 是函数修饰符,描述了该函数中的逻辑将如何与合约状态交互。如果你的合约要从存储中读取,而不是写入,你将使用 view (或 constant 完全相同)修饰符(参见 view functions documentation). If you're not going to read or write from contract state, and everything you do only works with memory variables, then it's a 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 变量,它会尝试将您的结构写入状态。这是你需要小心的地方,因为如果你在你应该使用 memory 的地方使用 storage 变量,你实际上可以覆盖你的状态。示例:

contract C {
  uint _var;

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

在这种情况下,r 是未初始化的存储指针,它导致变量指向存储槽 0。当您在结构 (r.state = 100;) 中设置一些变量时,它将写入该值到插槽 0,其中 覆盖 _var 处的值。

当你想创建一个新的结构作为局部变量时,你想使用memory修饰符,然后将其设置为状态变量(或将其添加到状态mapping/array) .当你想从 mapping/array 读取结构到局部变量时,使用 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?

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