Solidity Minimalist #5. Variable data storage and scope

Reference types in Solidity

Reference type (Reference Type) : including array (array), structure (struct) and mapping (mapping), this type of variable takes up a lot of space, and the address is directly passed when assigning (similar to a pointer). Since this type of variable is more complicated and takes up a lot of storage space, we must declare the location of the data storage when using it.

data location

There are three types of solidity data storage locations: storage, memory, and calldata. Different storage locations have different gas costs. The data of the storage type exists on the chain, which is similar to the hard disk of a computer, and consumes more gas; the data of the memory and calldata types are temporarily stored in the memory, and consume less gas. General usage:

  1. storage: The state variables in the contract default to storage, which is stored on the chain.
  2. memory: The parameters and temporary variables in the function generally use memory, which is stored in memory and not linked to the chain.
  3. calldata: Similar to memory, it is stored in memory and not linked to the chain. The difference from memory is that the calldata variable cannot be modified (immutable), and is generally used as a parameter of a function. example:
function fCalldata(uint[] calldata _x) public pure returns(uint[] calldata){
  //参数为calldata数组,不能被修改
  // _x[0] = 0 //这样修改会报错
  return(_x);
}

Example:

Solidity Minimalist #5. Variable data storage and scope_ethereum

Data location and assignment rules

When different storage types assign values ​​to each other, sometimes an independent copy is generated (modifying the new variable will not affect the original variable), and sometimes a reference is generated (modifying the new variable will affect the original variable). The rules are as follows:

  1. When the storage (state variable of the contract) is assigned to the local storage (in the function), a reference will be created, and changing the new variable will affect the original variable. example:
uint[] x = [1,2,3]; // 状态变量:数组 x

function fStorage() public{
  //声明一个storage的变量 xStorage,指向x。修改xStorage也会影响x
  uint[] storage xStorage = x;
  xStorage[0] = 100;
}

Example:

Simple Introduction to Solidity#5. Variable data storage and scope_Solidity_02

  1. Assigning storage to memory will create independent copies, and modifying one will not affect the other; and vice versa. example:
uint[] x = [1,2,3]; // 状态变量:数组 x

function fMemory() public view{
  //声明一个Memory的变量xMemory,复制x。修改xMemory不会影响x
  uint[] memory xMemory = x;
  xMemory[0] = 100;
  xMemory[1] = 200;
  uint[] memory xMemory2 = x;
  xMemory2[0] = 300;
}

Example:

Solidity minimalist introduction #5. Variable data storage and scope_smart contract_03

  1. Assigning memory to memory will create a reference, and changing the new variable will affect the original variable.
  2. In other cases, assigning a variable to storage will create independent copies, and modifying one will not affect the other.

variable scope

There are three types of variables in Solidity, which are state variables, local variables and global variables.

1. State variables

The state variable is a variable whose data is stored on the chain, which can be accessed by all functions in the contract, and the gas consumption is high. State variables are declared inside the contract and outside the function:

contract Variables {
  uint public x = 1;
  uint public y;
  string public z;
}

We can change the value of a state variable inside a function:

function foo() external{
  // 可以在函数里更改状态变量的值
  x = 5;
  y = 2;
  z = "0xAA";
}

2. Local variables

Local variables are variables that are valid only during function execution, and are invalid after the function exits. The data of local variables is stored in the memory, not linked to the chain, and the gas is low. Local variables are declared inside a function:

function bar() external pure returns(uint){
  uint xx = 1;
  uint yy = 3;
  uint zz = xx + yy;
  return(zz);
}

3. Global variables

Global variables are variables that work in the global scope, and they are solidity reserved keywords. They can be used directly without declaration inside the function:

function global() external view returns(address, uint, bytes memory){
  address sender = msg.sender;
  uint blockNum = block.number;
  bytes memory data = msg.data;
  return(sender, blockNum, data);
}

In the above example, we used three commonly used global variables: msg.sender, block.number and msg.data, which respectively represent the request initiation address, current block height, and request data. The following are some commonly used global variables. For a more complete list, please see this link :

  • blockhash(uint blockNumber): (bytes32) Hash of the given block - only for the 256 most recent blocks, not including the current block.
  • block.coinbase: (address payable) the address of the current block miner
  • block.gaslimit: (uint) the gaslimit of the current block
  • block.number: (uint) the number of the current block
  • block.timestamp: (uint) The timestamp of the current block, in seconds since the unix epoch
  • gasleft(): (uint256) remaining gas
  • msg.data: (bytes calldata) complete call data
  • msg.sender: (address payable) message sender (current caller)
  • msg.sig: (bytes4) the first four bytes of calldata (function identifier)
  • msg.value: (uint) the wei value sent by the current transaction

Example:

Solidity Minimalist #5. Variable Data Storage and Scope_ethereum_04

Summarize

In this lecture, we introduced the reference type, data location and variable scope in solidity. The focus is on the usage of the three keywords storage, memory and calldata. The reason for their appearance is to save the limited storage space on the chain and reduce gas. In the next lecture we will introduce arrays in reference types.

Guess you like

Origin blog.csdn.net/u010359479/article/details/128870334