Solidity 솔리디티 강좌 5강 : public, private, internal, external

flowing1ife·2023년 7월 6일
0

[ Solidity 깨부수기 ]

목록 보기
5/29
post-thumbnail

Solidity 솔리디티 강좌 5강 : public, private, internal, external
이번엔 solidity의 접근 제한자에 대해 알아보도록 하자.


접근 제한자

📌 Solidity

public : 완전히 오픈되어서 모든 곳에서 접근 가능
external : public 처럼 모든 곳에서 접근 가능하나 external이 정의된 자기 자신 컨트랙트 내에서 접근 불가
private : 오직 private이 정의된 자기 컨트랙트 내에서만 가능, 상속 받은 컨트랙도 불가능
internal : private처럼 오직 internal이 정의된 자기 컨트랙트 내에서만 가능, internal이 정의된 컨트랙트를 상속 받은 컨트랙트도 접근 가능

solidity 내에는 public, private, external, internal, 이렇게 총 4가지의 접근 제한자가 존재한다.

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

contract lec5{
    //public
    uint256 public a = 5;

    //private
    uint256 private a2 = 5;
}

👉 결과

이처럼 public으로 정의한 a는 보이지만 private으로 정의한 a2는 보이지 않는다. a2는 오로지 a2가 정의된 lec5 내에서만 접근 가능하다.

1. public

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

contract lec5{
    //public
    uint256 public a = 5;

    //private
    uint256 private a2 = 5;
}

//추가
contract Public_example {
    uint256 public a = 3;

    function changeA(uint256 _value) public {
        a = _value;
    }
    function get_a() view public returns (uint256) {
        return a;
    }
}

contract Public_example_2 {
    Public_example instance = new Public_example();

    function changeA_2(uint256 _value) public {
        instance.changeA(_value);
    }
    function use_public_example_a() view public returns (uint256) {
        return instance.get_a();
    }
}

solidity 내에는 view, pure, instance라는 것도 존재하는데, 이는 추후 자세히 살펴보도록 하겠다.

👉 결과
📍 위의 3개의 contract를 모두 배포해야 한다.

-- 배포 후 →

Process
1. Public_examplea는 3
2. Public_example_2changeA_2 (10) 실행
3. Public_examplechangeA가 실행됨
4. Public_examplea가 10으로 변경
5. Public_example_2use_public_example_a 실행
6. Public_example 컨트랙트의 get_a가 실행됨
7. Public_examplea가 return

Public_example_2 에서 changeA_2 함수를 통해 Public_example 컨트랙트의 changeA 함수를, use_public_example_a 함수를 통해 Public_example 컨트랙트의 get_a 함수를 실행했다. 이것이 가능한 이유는changeA 함수, get_a 함수 모두 접근 제한자가 public으로 정의되었기 때문이다.

2. private

만약 이를 private으로 변경한다면

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

contract lec5{
    //public
    uint256 public a = 5;

    //private
    uint256 private a2 = 5;
}

contract Public_example {
    uint256 public a = 3;

  	//변경
    function changeA(uint256 _value) private {
        a = _value;
    }
  	//변경
    function get_a() view private returns (uint256) {
        return a;
    }
}

contract Public_example_2 {
    Public_example instance = new Public_example();

    function changeA_2(uint256 _value) public {
        instance.changeA(_value);
    }
    function use_public_example_a() view public returns (uint256) {
        return instance.get_a();
    }
}

👉 결과

다음과 같이 instance.changeA(_value)를 불러올 수 없다는 에러가 발생한다.

3. external

이번엔 external로 변경한다면

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

contract lec5{
    //public
    uint256 public a = 5;

    //private
    uint256 private a2 = 5;
}

contract Public_example {
    uint256 public a = 3;
	
  	//변경
    function changeA(uint256 _value) external  {
        a = _value;
    }
  	//변경
    function get_a() view external returns (uint256) {
        return a;
    }
}

contract Public_example_2 {
    Public_example instance = new Public_example();

    function changeA_2(uint256 _value) public {
        instance.changeA(_value);
    }
    function use_public_example_a() view public returns (uint256) {
        return instance.get_a();
    }
}

👉 결과

당연히 제대로 기능한다. 왜냐하면 external이 선언된 컨트랙트인 Public_example 내에서가 아닌 외부 컨트랙트인 Public_example_2 에서 changeA 함수, get_a 함수를 호출하였기 때문이다.

만약 public으로 선언된 변수 aexternal로 변경하면

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

contract lec5{
    //public
    uint256 public a = 5;

    //private
    uint256 private a2 = 5;
}

contract Public_example {
  	//변경
    uint256 external a = 3;
	
    function changeA(uint256 _value) external  {
        a = _value;
    }

    function get_a() view external returns (uint256) {
        return a;
    }
}

contract Public_example_2 {
    Public_example instance = new Public_example();

    function changeA_2(uint256 _value) public {
        instance.changeA(_value);
    }
    function use_public_example_a() view public returns (uint256) {
        return instance.get_a();
    }
}

👉 결과

external이 선언된 컨트랙트인 Public_example 내에서 변수 a를 사용했기 때문에 다음과 같이 오류가 발생한다.

4. internal

internal의 경우, 위에서 표기한 대로 internal contract를 상속받은 contract는 internal이 선언된 컨트랙트에 접근이 가능한데, 이는 상속에 대해 배운 뒤 더 자세히 살펴보도록 하자.


출처 및 참고 자료

profile
👩🏻‍💻 Backend Engineer, Contract Developer

0개의 댓글