[Solidity] 변수

Alexandria·2024년 3월 4일

Solidity

목록 보기
5/11
post-thumbnail

1. 변수 형

solidity는 컴파일 시 변수의 타입이 명시되어야 하는 정적 타입 언어이다.

지원되는 타입은 다음과 같이 존재한다.

고정 소수점은 아직 완벽하게 지원되지 않는다고 한다.

| Type | Values |
| bool | true/false |
| int8~256/uint8~256 | 8 bits to 256 bits Integer |
| int/uint | int256/uint256 |
| bytes1~32 | 1 bytes to 32 bytes byte |
| bytes | bytes32 |
| string | string |

1.1. address

다른 언어와 비교하여 solidity에서 사용하는 address라는 생소한 타입이 존재한다.

address는 20byte 크기를 가지며, 해당 주소의 잔고를 확인할 수 있는 balance

송금을 할 수 있는 transfer 등 여러 멤버 함수를 가지고 있다.

1.2. mapping

의 쌍으로 이루어진 참조 유형이며

키는 매핑, 동적 배열, 컨트랙트, 열거형, 구조체를 제외한 내장 변수 타입 등 거의 모든 유형이 될 수 있다.

반면에 값은 어떤 타입이든 될 수 있다.

C++의 map, Python의 dictionary과 유사하지만 iterable 하진 않는다.

1.3. Struct

다른 언어에서 사용하는 구조체처럼 사용할 수 있다.

contract HelloWorld {
    struct User {
        string name;
        uint age;
   }
   User[] users;

   function setUser() public {
      users.push(User("John Doe", 20));
   }

   function getUser(uint index) public view returns (User memory user) {
      return users[index];
   }
}

1.4. Enum

C와 같은 열거형 변수 타입이다.

마찬가지로 0 부터 시작한다.

contract HelloWorld {
    enum Fruits { APPLE, BANANA, ORANGE }

    function getFruits() public pure returns (Fruits) {
        return Fruits.BANANA; // return 1
    }
}

2. 변수

영구적으로 저장되는 상태 변수(State Variable), 함수 내에서만 존재하는 지역 변수(Local Variable)와

어디서든 사용이 가능한 전역 변수(Global Variable)가 존재한다.

2.1. 상태 변수

다음과 같이 컨트랙트에서 선언한 상태 변수는 영구적으로 저장된다.

contract HelloWorld {
    uint _myVariable1;
    string _myVariable2;
}

2.2. 지역 변수

함수 내에서만 사용할 수 있으며, 함수의 매개변수도 지역 변수이다.

함수 내에서 선언된 변수는 밖에서 접근할 수 없다.

contract HelloWorld {
    function mySum(uint256 a) public pure returns (uint256) {
        uint256 b = 4;
        return a + b;
    }
}

2.3. 전역 변수

블록체인 및 트랜잭션을 접근할 수 있도록 어디서든 접근할 수 있는 변수 및 함수이다.

block 변수는 트랜잭션이 담기는 블록에 대한 정보이다.

msg는 함수를 호출한 주소 값을 얻을 수 있는 msg.sender, 송금하는 코인의 양이 저장된 msg.value 등 사용된다.

contract HelloWorld {
    function currentBlockHash() public view returns (bytes32) {
        // 현재 블록 번호
        uint256 bNumber = block.number;
        // 블록의 해시 값
        bytes32 bHash   = blockhash(bNumber);
        return bHash;
    }

    function getBlockMiner() public view returns (address) {
        // 블록 채굴자의 주소
        return block.coinbase;
    }

    function getBlockTimestamp() public view returns (uint) {
        // 블록의 timestamp 값
        return block.timestamp;
    }

    function msgTest(address _address) public payable {
        // _address한테 value만큼 송금
        payable(_address).transfer(msg.value);
    }
}

3. Visibility

상태 변수 및 함수 등 정의된 범위에 따라 접근을 제어할 수 있다.

public으로 지정된 변수는 getter를 별도로 지정하지 않아도 자동으로 생성된다.

접근 제어자내부에서 호출외부에서 호출상속된 컨트랙트에서 호출
publicOOO
privateOXX
externalXOX
internalOXO

4. 함수

함수 타입 제어자읽기쓰기가스
viewOXX
pureXXX
payableOOO

pure의 용도는 저장된 데이터를 읽고 쓸수 없지만,

함수 내 정의된 지역 변수나 인자로 받은 변수를 연산하는 등 결과를 반환하는데에 사용한다.

contract HelloWorld {
    function mySum(uint256 a, uint256 b) public pure returns (uint256 result) {
        return a + b;
    }
}

함수의 오버로딩도 지원된다.

contract HelloWorld {
    function sum(uint a) public pure returns (uint256) {
        return a + 3;
    }
    function sum(uint a, uint b) public pure returns (uint256) {
        return a + b + 3;
    }
}

5. Modifiers

특정 함수를 실행시키기 전과 후에 특정 기능을 수행할 수 있도록 정의할 수 있다.

modifier 내 _를 기점으로 함수가 실행되기 전과 후의 기능을 수행한다.

다음의 예제에서 testFunction을 수행하면 decoded output이 6으로 찍히지만,

함수가 끝난 후 myVar getter를 호출하면 7이 된것을 확인할 수 있다.

contract HelloWorld {
    uint public myVar = 5;
    modifier testModifier {
        myVar ++; // 함수가 실행되기 전 수행
        _;
        myVar ++; // 함수가 실행된 후 수행
    }
    function testFunction() public testModifier returns (uint256) {
        return myVar;
    }
}

컨트랙트의 소유주를 판별할 때 자주사용된다.

생성자를 이용하여 컨트랙트를 배포시 _owner에 배포자의 주소가 저장되며,

onlyOwner가 지정된 함수를 실행할 때

호출자가 배포자의 주소가 아니면 Error가 발생되는 원리이다.

contract HelloWorld {
    uint public _myVar = 5;
    address private immutable OWNER;

    constructor() {
        OWNER = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == OWNER, "Only Owner can call this.");
        _;
    }

    function testFunction() public onlyOwner {
        _myVar ++;
    }
}

6. Events

함수의 반환 값받을 수 없는 구조일 때, 로깅을 이용하여 데이터를 확인하는 방법을 쓰기도 한다.

이벤트를 발생 시 가스가 소비되니 무분별한 로깅은 자제한다.

contract HelloWorld {
    uint public _myVar = 5;

    event MyEvent(address indexed _from, uint _Var);

    function testFunction() public {
        _myVar ++;
        emit MyEvent(msg.sender, _myVar);
    }
}
profile
IT 도서관

0개의 댓글