-
접근 제한자와 생성자Solidity 2022. 5. 11. 00:32
조금씩 코드들이 어떤 의도로 쓰였고 어떤 방식으로 동작하는지 보이기 시작하는 것 같아서
많이 사용된다는 OpenZeppelin의 Ownable contract 코드를 들여다보고자 합니다.
이해하고 있는 부분에 대해 설명 쓰고 이해가 되지 않는 부분은 따로 적어뒀다가 해결되면 이에 대한 답도 남기겠습니다.
// 컴파일러 버전 명시 pragma solidity >=0.5.0 <0.6.0; contract Ownable { address private _owner; // 해당 컨트랙트에서만 _owner에 접근 가능하도록 설정 event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); // constructor(생성자)는 배포시에 단 한번만 실행 // deploy(배포)한 사람이 owner 임을 명시 constructor() internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } // owner 함수를 호출하면 address 타입의 _owner를 리턴 // owner 함수 밖의 변수인 _owner을 읽을 수 있어야 하기에 view 사용 function owner() public view returns(address) { return _owner; } // modifier 활용하여 조건 체크 modifier onlyOwner() { require(isOwner()); _; } function isOwner() public view returns(bool) { return msg.sender == _owner; } function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
Q1. private (접근 제한자 중 하나)에 대한 명확하지 않은 이해 [Done]
위의 Ownable 컨트랙트는 다른 컨트랙트에서 상속받아 사용하는 경우가 많다고 알고 있는데 address private _owner 부분을 보면 private이 명시되어 있는데 그러면 상속받은 컨트랙트에서 해당 값에 대해 접근(?)이 불가능한데 어떻게 사용한다는 의미일까?라고 생각을 하면서 글을 쓰다 보니 분명 접근이 안 되는 게 맞고 그렇게 했다면 이유가 있을 텐데라고 생각하며 조금 더 다시 내려가 봤습니다.
private이라는 접근 제한자에만 너무 신경 써서 _owner가 address 타입의 변수란 점을 망각하고 있었습니다.
접근 제한자를 배운 이후에도 어떤 상황에서 쓰는 것인지 애매모호했는데 private을 어떤 상황에서 사용하는지 이제 정확하게 알겠습니다.
컨트랙트를 상속받아 사용하는 경우가 많으므로 public처럼 어디서나 접근이 가능하게 하면 Ownable 컨트랙트에서 가장 중요한 _owner의 값이 의도치 않게 설정될 수 있습니다. 그렇기에 해당 컨트랙트에서 의도한 대로 _owner은 constructor에서 msg.sender 값으로만 설정되도록 한 것입니다.
Q2. constructor(생성자)에 왜 internal을 사용했을까?
관련 글을 찾아보니 constructor 접근 제한자를 public이나 internal로 안 했을 경우에 아래와 같은 에러 메시지가 뜬다고 하여 확인해봤습니다.
TypeError: Constructor must be public or internal.
그런데 기존에 제가 작성했던 constructor에는 접근 제한자를 쓰지 않았었고 썼더니 다른 에러가 발생했습니다.
constructor에 접근 제한자 명시했을 때 발생한 ParserError 혹시나 하여 봤더니 해당 글은 4년 6개월 전의 글이었고 0.7.0 버전부터는 constructor에 접근 제한자를 명시하지 않는다는 것을 확인했습니다.
constructor에 public 또는 external을 쓰지 않는 이유 위 문장이 정확히 어떤 의미인지 감이 오지 않아서 이 부분 파악해서 남기도록 하겠습니다.
위의 컨트랙트 중간쯤에 modifier와 '_' 부분에 대해 찾아보니 정리할 분량이 꽤 되는 것 같아서 다음에 따로 정리하도록 하겠습니다.
그리고 참고 자료 가장 아래에 있는 사이트에서도 설명을 잘해주고 있어서 함께 읽어보고 진행해보시면 좋을 것 같아 공유드립니다.
< 참고 자료 >
저와 비슷한 궁금증을 가지고 있는 사람이 있었기에 참고 링크 공유드립니다.
https://ethereum.stackexchange.com/questions/30223/should-the-constructor-function-be-public
Should the constructor function be public?
In all the tutorials I'm watching nobody specifies public, but remix presents warnings that function visibility has not been specified, and public is assumed. Since I don't like warnings if possi...
ethereum.stackexchange.com
https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html#functions-and-events
Solidity v0.7.0 Breaking Changes — Solidity 0.7.0 documentation
Solidity v0.7.0 Breaking Changes This section highlights the main breaking changes introduced in Solidity version 0.7.0, along with the reasoning behind the changes and how to update affected code. For the full list check the release changelog. Silent Chan
docs.soliditylang.org
https://cryptozombies.io/en/course
#1 Solidity Tutorial & Ethereum Blockchain Programming Course | CryptoZombies
CryptoZombies is The Most Popular, Interactive Solidity Tutorial That Will Help You Learn Blockchain Programming on Ethereum by Building Your Own Fun Game with Zombies — Master Blockchain Development with Web3, Infura, Metamask & Ethereum Smart Contracts
cryptozombies.io
'Solidity' 카테고리의 다른 글
구조체(struct)와 가스(gas) 관계 (0) 2022.05.11 Struct (구조체) - Mapping & Array (0) 2022.04.24 Solidity의 Array (배열) 사용법과 주의사항 (0) 2022.04.23