이더리움/솔리디티

[솔리디티] 4. 생성자, 매개변수, 값 타입과 참조 타입, immutable

라이튼 2023. 7. 10. 23:31

이전글

 

[솔리디티] 3. 자료형, 배열, 상수, 상태 변수

이전글 [솔리디티] 2. 리믹스 IDE 이전글 [솔리디티] 1. 솔리디티와 EVM 이전글 [솔리디티] 0. 들어가기 전에 앞으로 이어지는 솔리디티 글은 다음과 같은 내용이 미리 선행되어야 합니다. 1. 프로그

kwjdnjs.tistory.com

 

생성자, 매개변수, 값 타입과 참조 타입, immutable

 이번 글에서는 솔리디티 컨트랙트의 생성자, 매개변수, 값 타입과 참조 타입 그리고 immutable과 constant의 차이에 대해 알아보겠습니다.

 

1. 생성자

 이전 글에서 컨트랙트가 객체와 유사하다고 했었습니다. 따라서 컨트랙트에는 객체와 비슷하게 생성자를 사용할 수 있습니다.

 

 생성자는 컨트랙트가 처음 배포되는 과정에서 단 한 번 실행됩니다. 다음과 같이 constructor()로 생성자를 작성할 수 있습니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Constructor {
    constructor() {
        
    }
}

 

 생성자를 이용하여 변수를 초기화할 수 있습니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Constructor {
    uint8 public a;

    constructor() {
        a = 3;
    }
}

 위 컨트랙트를 배포한 후 변수 a의 게터 함수를 실행하면 변수 a에 3이 할당된 것을 확인할 수 있습니다.

 

2. 매개변수

 생성자에는 다음과 같이 매개변수를 사용할 수 있습니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Constructor {
    uint8 public a;
    uint8 public b;

    constructor(uint8 _a, uint8 _b) {
        a = _a;
        b = _b;
    }
}

 생성자는 컨트랙트가 최초로 배포되는 과정에서 단 한 번만 실행되므로, 컨트랙트 배포 트랜잭션에 매개변수를 함께 포함시켜야 합니다. 컨트랙트를 컴파일하면 Deploy 버튼 옆에 매개변수를 입력할 수 있는 칸이 추가된 것을 확인할 수 있습니다.

 

 

 맨 오른쪽 'v' 버튼을 눌러 펼치면 보다 정확하게 값을 입력할 수 있습니다.

 

 

 값을 입력한 후 transact 버튼을 클릭하면 컨트랙트가 배포됩니다. 게터 함수를 통해 값이 제대로 할당된 것을 확인할 수 있습니다.

 

 

3. 값 타입과 참조 타입

 매개변수를 사용할 때에는 값 타입과 참조 타입을 구별해서 사용해야 합니다. uint, int, address와 숫자와 함께 사용하는 정적 크기의 bytes(bytes2처럼 사용하는 bytes)는 값 타입입니다.

 

 동적 크기의 bytes, string 그리고 모든 배열은 참조 타입입니다.

 

 두 타입의 차이를 알아보기 전에 EVM의 구조를 다시 한번 보겠습니다.

 

 

 EVM에서 사용하는 데이터 저장공간에는 스택, 메모리, 스토리지(블록체인)가 있습니다. 여기에 추가로 콜데이터가 있습니다. 콜데이터는 트랜잭션을 통해 들어온 매개변수가 저장되는 저장공간입니다.

 

 값 타입 매개변수는 콜데이터에만 저장됩니다. 하지만 참조 타입 매개변수는 콜데이터 외에 메모리에도 값을 저장할 수 있습니다.

 

 콜데이터와 메모리의 차이는 값 변경 가능 여부입니다. 콜데이터에 저장된 값은 변경할 수 없습니다. 하지만 메모리에 저장된 값은 변경할 수 있습니다.

 

 배열을 매개변수로 받을 때에는 콜데이터에 값을 저장할 것인지 아니면 메모리에 값을 저장할 것인지를 명시해야 합니다. 매개변수 자료형 뒤에 calldata와 memory 키워드를 사용하여 저장할 위치를 명시할 수 있습니다.

 

 생성자의 경우 calldata로는 매개변수를 받을 수 없습니다. 따라서 memory 키워드만을 사용해야 합니다. 다음은 예시 코드입니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Constructor {
    uint8[] public a;
    string public b;

    constructor(uint8[] memory _a, string memory _b) {
        a = _a;
        b = _b;
    }
}

 

4. immutable vs constant

 마지막으로 immutable에 대해 알아보겠습니다. 이전에 상수를 선언할 때에는 constant를 사용한다고 했습니다. 하지만 immutable을 사용해도 상수를 선언할 수 있습니다.

 

 constant로 선언된 상수는 선언 과정에서 값을 할당해야 합니다. 이후에는 어떤 방식으로도 변경할 수 없습니다.

 

 immutable로 선언된 상수는 선언 과정에서 값을 할당하지 않아도 됩니다. 대신에 constructor 내부에서 값을 할당해야 합니다. 값 할당 이후에는 constant와 마찬가지로 값을 변경할 수 없습니다. 다음은 예시 코드입니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Constructor {
    uint8 public constant A = 5;
    uint8 public immutable B = 5;
    uint8 public immutable C;

    constructor(uint8 _c) {
        C = _c;
    }
}

 

지금까지 생성자, 매개변수, 값 타입과 참조 타입 그리고 immutable에 대해 알아봤습니다. 감사합니다.

 

 

다음글

 

[솔리디티] 5. 연산자, 전역 변수, 단위

이전글 [솔리디티] 4. 생성자, 매개변수, 값 타입과 참조 타입, immutable 이전글 [솔리디티] 3. 자료형, 배열, 상수, 상태 변수 이전글 [솔리디티] 2. 리믹스 IDE 이전글 [솔리디티] 1. 솔리디티와 EVM 이

kwjdnjs.tistory.com