Encode-Club-Solidity-Foundations / Lesson-03

4 stars 7 forks source link

2 questions: constants not state, but immutables declared when assigned are state: why? #11

Closed conors-code closed 2 years ago

conors-code commented 2 years ago

Hi Matheus. I was looking through enums in the types reference, there's an example of a constant there. In the example, there's an enum and two variables, each of the enum type, one constant and the other not. Any function using the non-constant variable needs the view modifier. That is a state variable and can change so I expect it to act like that. I see that the constant variable can be used in a function with the pure modifier. Q1: Is the constant not considered a state variable because it cannot change?

I added an immutable variable of the same enum type. Here, I assigned the value at declaration. (I understand immutable can be written to be assigned in a constructor, but I didn't do that here.) However, for a function to use this immutable, it too must have the view modifier, even just like a constant it cannot be changed.

Q2: why is an immutable variable assigned a value at declaration - and so constant - considered a state variable when a constant is not? example code:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract Lesson3Test6 {

  enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
  ActionChoices choice;

  ActionChoices constant defaultChoice = ActionChoices.GoStraight;

  ActionChoices immutable immutableChoice = ActionChoices.GoStraight;

  function getChoice() public view returns (ActionChoices) {
      return choice;
  }

  function getDefaultChoice() public pure returns (uint) {
      return uint(defaultChoice);
  }

  //immutable assigned at declaration won't compile as pure, even though it can't be changed.
  function getImmutableChoice() public view returns (uint) {
      return uint(immutableChoice);
  }
}

Thanks as always, Conor

MatheusDaros commented 2 years ago

Hello Conor This is a great way to understand the major differences between constant and immutable variables. The constant variable is not even stored at the account storage of that contract address. It is simply "copied" over and over by the compiler, as if you hardcoded it in your code over and over. For example:

contract Foo {
  string constant foo = "bar";

  function getFoo() public pure returns (string memory) {
    return foo;
  }
}

Is the same as:

contract Foo {
  function getFoo() public pure returns (string memory) {
    return "bar";
  }
}

(when considering the compiled output)

As for the immutable, it indeed consumes a storage location in the contract's account, but can only be assigned once and never changed again.

conors-code commented 2 years ago

That explains it beautifully, thanks once again Matheus!