什么是稳态的状态变量?

时间:2018-04-02 14:56:53

标签: 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)我应该在storage中为memorymain标记本地变量吗?我应该在get_rand

中标记出什么

2)突变是否有效?说,我读到pure函数不能更改状态变量,并且复制了内存变量。是否标记为storage足够?如果pure更改其参数,我是否还应声明get_rand

由于

2 个答案:

答案 0 :(得分:0)

状态变量是永久存储在合同存储中的值。它们在合同范围内和外部功能范围内声明。像这样:

pragma solidity ^0.4.0;

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

因此合同的整体层次结构如下:

Contract
--/ State Variables
--/ Functions

除此之外,我无法理解你的要求。也许你应该在单独的问题中清楚地问清楚,而不是在一个问题中模糊地问他们。

答案 1 :(得分:0)

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

  

我应该在main中为本地变量标记存储空间还是内存?我应该在get_rand中为参数标记什么?

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

contract C {
  uint _var;

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

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

如果要将新结构创建为局部变量,则需要使用memory修饰符,然后将其设置为状态变量(或将其添加到状态映射/数组)。如果要将映射/数组中的结构读取到局部变量中,请使用storage

使用您提供的示例,您希望将其设置为memory变量。请仔细阅读Solidity docs very this section

  

突变是否有效?说,我读到一个纯函数不能改变状态变量,并且复制了内存变量。是否足够标记存储?如果它改变了参数,我还应该为get_rand声明pure吗?

不,它不会改变合同的状态。虽然本地结构变量默认为storage,但默认情况下函数参数始终为memory(甚至是结构)。在rand内修改get_rand不会修改任何州。如果您将函数更改为访问状态,则由于pure修饰符而导致编译错误。