無知

갈 길이 먼 공부 일기

기술 공부/블록체인

스마트 컨트랙트 (5-2) | Solidity(솔리디티) State Variable, Type

moozii 2022. 4. 16. 12:50

 

3. Contents

3-1. Contract

3-1-1. Variable

3-1-1-1. State Variable

State Variable은 EVM 내 스토리지에 저장된다. 메모리에 저장되는 임시 값들과 반대된다.

스토리지는 컨트랙트의 모든 함수가 접근할 수 있다. 즉, EVM의 storage 영역은 contract 내의 모든 function 이 접근할 수 있으며 function이 변경한 값은 계속해서 저장되어 다음 번 function에서 저장된 값을 사용할 수 있다.

컨트랙트의 함수 바깥에서 선언되었다.

 

State Variables

State variables are variables whose values are permanently stored in contract storage.
See the Types section for valid state variable types and Visibility and Getters for possible choices for visibility.

https://docs.soliditylang.org/en/v0.8.13/structure-of-a-contract.html 
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

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

 

 

 

 

3-1-2. Variable Visibility

State Variable Visibility

public
Public state variables differ from internal ones only in that the compiler automatically generates getter functions for them, which allows other contracts to read their values. When used within the same contract, the external access (e.g. this.x) invokes the getter while internal access (e.g. x) gets the variable value directly from storage. Setter functions are not generated so other contracts cannot directly modify their values.

internal
Internal state variables can only be accessed from within the contract they are defined in and in derived contracts. They cannot be accessed externally. This is the default visibility level for state variables.

private
Private state variables are like internal ones but they are not visible in derived contracts.

Warning : Making something private or internal only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain.

https://docs.soliditylang.org/en/v0.8.13/contracts.html#state-variable-visibility 

 

 

 

 

3-1-3. Data Type

2가지 데이터 타입이 존재한다. 값이 복사되는 방식에 따라 value type, reference type이 존재한다.

 

value type : bool, int, address, byte

변수가 다른 변수로 assign되거나 함수에 넘겨지면 그 값이 전달된다. Passing by Value. 원래 변수를 수정해도 넘겨진 값을 받은 새로운 변수는 값이 수정되지 않는다.

 

reference type : array, struct, string, mapping

변수가 다른 변수로 assign되거나 함수에 넘겨지면 그 저장소 위치가 전달된다. 데이터 값을 읽으려면 해당 메모리 위치로 가서 읽는다. 데이터가 크면 값을 복사하지 않아도 되는 효용이 있다. 함수 변수로 넘겨지면 함수 변형 결과가 원래 값에도 영향을 미친다. Passing by Reference.

https://medium.com/javarevisited/is-java-pass-by-value-or-pass-by-reference-513fa0c98ef

As the name says, pass by value simply means, we pass the value of an object and not the actual/original reference variable of an Object from the main function to the called function but the copy of the reference variable of this object is passed to the called function which ultimately points to the same object.
(...)
In the case of pass by reference, the calling method passes variables to the called function and the called function accepts the argument as the address of those variables which are passed thru the calling function

@Vikram Gubta 2020-08-31, Javarevisited(Medium)
https://medium.com/javarevisited/is-java-pass-by-value-or-pass-by-reference-513fa0c98ef 

 

Types

Solidity is a statically typed language, which means that the type of each variable (state and local) needs to be specified. Solidity provides several elementary types which can be combined to form complex types. In addition, types can interact with each other in expressions containing operators. For a quick reference of the various operators, see Order of Precedence of Operators. The concept of “undefined” or “null” values does not exist in Solidity, but newly declared variables always have a default value dependent on its type. To handle any unexpected values, you should use the revert function to revert the whole transaction, or return a tuple with a second bool value denoting success.

Value Types

The following types are also called value types because variables of these types will always be passed by value, i.e. they are always copied when they are used as function arguments or in assignments.

Reference Types

Values of reference type can be modified through multiple different names. Contrast this with value types where you get an independent copy whenever a variable of value type is used. Because of that, reference types have to be handled more carefully than value types. Currently, reference types comprise structs, arrays and mappings. If you use a reference type, you always have to explicitly provide the data area where the type is stored: memory (whose lifetime is limited to an external function call), storage (the location where the state variables are stored, where the lifetime is limited to the lifetime of a contract) or calldata (special data location that contains the function arguments). An assignment or type conversion that changes the data location will always incur an automatic copy operation, while assignments inside the same data location only copy in some cases for storage types.

https://docs.soliditylang.org/en/v0.8.13/types.html# 

 

 

 

 

3-1-3-1. Value Type Variables

Bools / Integers / Address / Byte / Enumerations

 

(1) Bools : bool (true/false)

bool variable_name = true; 

default=false

 

 

(2) Integers : (signed/unsigned) * (size)

signed = 부호 있음 / unsigned = 부호 없음

size = 8 ~ 256 bits (8,16,32,64,128,256) (no size = 256bit)

부호 유무 * 사이즈 = integer type

int8 = 8 bit signed integer (-128 ~ 127)

uint16 = 16 bit unsigned integer (0 ~ 65535)

uint = 256 but unsigned integer (0~2**256-1)

 

 

(3) Address (address)

20byte sized data type. Stores ETH address. 

* has balance property. (addr.balance)

* method : transfer, send

 

 

(4) Byte = Fixed-sized byte array

Supported data type for saving data in binary form.

bytes1 ~ bytes32 (bytes1 = byte)

bytes1 data_1 = 0xff;

bytes2 data_2 = 0xff; // Not implicitly convertible >> Compile Error

bytes2 data_3 = 0xffff;

bytes1 data_4 = 12345; // Not implicitly convertible. 10진수 값은 자동 전환되지 않는다. 

bytes1 data5 = 0; // 0은 사이즈 무관 바이트 어레이 선언 가능.

 

FYI : Bytes = Dynamically sized byte array = Reference Type

 

 

(5) Enumerations (열거형 타입)

사용자가 미리 정해진 상수 값을 이용해 선언 가능한 타입. 코드의 가독성 향상 목적.

enum State{    // Explicitly Convertible to/from integer
    Created, 
    Locked,
    Inactive
}

enum의 각 값들은 내부적으로 정수 값으로 구현됨. 

enum type을 contract 바깥에서 사용할 경우 enum명이 아닌 정수 값으로만 사용 가능.

(enum은 ABI, Application Binary Interface로 컴파일되지 않음)

 

 

 

 

3-1-3-2. Reference Type Variables

Array / String / Struct / Mappings

 

(1) Array (배열)

- 2 types of array : Fixed OR Dynamic

- Notation: {type}[size] array_name;

 

- Fixed Array : 선언 시 크기를 결정

uint8[5] fixed_array_1; // fixed array
uint8[5] fixed_array_2 = [1, 1, 2, 3, 5]; // can be initialized with array literals

- Dynmaic Array

uint8[] dynamic_array; // no fixed strorage allocated.

- Array as an element: 일반적인 Java, C++과는 인덱스 나열 순서가 반대인 것이 특징

uint8[ ][3] array_in_array;
// 3 uint8[ ] type arrays are in array_in_array.
// array_in_array[1][0] = first array_as_element's second element

- Data Location : Storage에 저장할지 Memory에 저장할지 명시할 수 있음

pragma solidity >=0.4.0 <0.7.0;

contract SimpleStorage {
    uint[ ] x;
    // x is state variable (out of function, in contract)
    // state variable stored in storage in default
    
    function f(uint[] memory input) public {
        // input is stored in memory as written.
        
        uint[] memory test;
        
        x = input
        // x and input all are arrays (reference type)
        // Assign input to x
        // But x is in storage and input is in memory
        // input data is copied from memory to storage (even though they are reference type)
        // then assign the copied reference to x
        
        input = test;
        // Both array and stored in memory
        // No copied data. Only copy the reference. 
        
        uint[] storage y = x;
        // Both array stored in storage
        // No copied data. Only copy the reference.
        
        y.length = 2;
        // x array length is also changed, since x and y has same reference. 
        
        g(x);
        // g(x) gets input stored in storage
        // x stored in storage
        // So Pass by Reference
        
        h(x);
        // h(x) gets input stored in memory
        // x stored in storage
        // So copy data which x refers
        // then make a new array with the data
        // And pass the array (stored in memory)
    }
    
    function g(uint[] storage) internal pure {}
    // function parameter is stored in memory as default
    // but we can make parameter stored in storage as above
    
    function h(uint[] memory) internal pure{}
}

 

 

(2) String (based on bytes array)

- String does not support index, push, length operations (unlike array)

- String also does not support concatenation

- Can make concatenation by changing the strings to bytes arrays, and copy those arrays to a new bytes array and change to string for the concatenation result. [이런 복잡한 연산의 구현은 많은 가스를 소모해 비효율적이므로 컨트랙트 바깥의 Javascript 코드에서 수행시키는 것이 바람직]

- For operation, dev should change string to bytes array

 

 

(3) Struct

- 서로 다른 종류의 타입을 하나로 묶어 사용하는 데에 활용하는 데이터 타입

- User-defined data container for grouping variables.

contract Sample {
	struct People {
    	string name;
        uint8 age;
        address[] accounts;
    }
    
    People james = People('James', 35. new address[](5));
    // struct can be initialized with the given value in the order defined
    
    People peter;
    
    function f_1(string memory name, uint8 age) public {
    	People memory temp = People({age: age, name: name, accounts: new address[](0)});
        // struct can be initialized with the give value in the different order from def
        
        peter = temp;
        // assign temp in memory to state variable in storage
    }
    
    function f_2(string memory name, uint8 age) public {
    	peter.name = name;
        peter.age = age;
        peter.accounts = new address[](0);
    }
}

 

 

(4) Mappings

- Data type used for key-value pairs

- Notation: mapping (key_type => value_type) mapping_name

(i.e. mapping (address => uint) balances;)

- Only stored in storage

- Unable to be used as function parameter or return type

- Data types unable for key type : complex data types (contract, mapping, struct)

- Keys are not stored in mapping. Access values by key-hash, not key. 

- Unable to get keys returned

- Can get value with key or update mapping with key

mapping (string => mapping (address => uint)) balances;
balances['James'][msg.sender] = newBalance; // store a value in the mapping

 

 

 

 

 

https://docs.soliditylang.org/en/v0.8.13/

 

Solidity — Solidity 0.8.13 documentation

1. Understand the Smart Contract Basics If you are new to the concept of smart contracts we recommend you to get started by digging into the “Introduction to Smart Contracts” section, which covers: 2. Get to Know Solidity Once you are accustomed to the

docs.soliditylang.org