【问题标题】:what are state variables in solidity?什么是solidity中的状态变量?
【发布时间】:2018-04-02 14:56:53
【问题描述】:

我阅读了一些关于storage、memory 和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) 我应该将storage 或memory 标记为main 中的局部变量吗?我应该为get_rand 中的论点标记什么?

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

谢谢

【问题讨论】:

    标签: solidity


    【解决方案1】:

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

    我应该在 main 中为局部变量标记存储还是内存? get_rand 中的参数我应该标记什么?

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

    contract C {
      uint _var;
    
      function f() public {
        Random r;
        ...
      }
    }
    

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

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

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

    突变会起作用吗?说,我读到纯函数不能更改状态变量,并且复制了内存变量。将两者都标记为存储是否足够?如果 get_rand 改变了它的论点,我还应该为它声明 pure 吗?

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

    【讨论】:

      【解决方案2】:

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

      pragma solidity ^0.4.0;
      
      contract SimpleStorage {
          uint storedData; // State variable
          // ...
      }
      

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

      Contract
      --/ State Variables
      --/ Functions
      

      除此之外,我无法理解您真正在问什么。也许你应该清楚地提出不同的问题,而不是模糊地在一个问题中提出所有问题。

      【讨论】:

      • 有时当用户对一段代码提出两个不同的问题时,问题往往会被标记为重复。
      猜你喜欢
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 2022-11-30
      • 2022-12-19
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多