시작하며
오늘은 솔리디티에서 클래스를 다루는 것처럼 contract를 다루는 기능들에 대해 설명하겠다. 사실상 이해를 쉽게하면 contract는 다른 객체지향언어에서 클래스라고 부르는 것과 거의 똑같다고 봐도 무방하다. 때문에 생성자나 상속과 같은 기능을 제공하며 오늘은 예시를 통해 이러한 요소들에 대해 알아보겠다.
1. 생성자
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract constructorEx{
event Info(string text, uint num);
uint public num;
constructor(uint pNum){
num = pNum;
}
}
지난 글에서 생성자를 사용하였는데, 여기서 설명을 더하자면, constructor 키워드로 생성자를 정의할 수 있다. 생성자는 스마트 컨트랙트가 deploy 되는 시점에 자동으로 실행된다. 현재 멤버변수 num을 매개변수 pNum으로 초기화하는 생성자가 정의 되어있다.
먼저 해당 컨트랙트를 그대로 deploy하면 우측 하단과 같이 에러가 발생한다. 이유는 컨트랙트의 생성자가 매개변수 하나를 받는데 이 매개변수를 입력하지 않고 deploy했기 때문이다. 다시 말하지만 생성자는 컨트랙트가 deploy될 때 수행되므로 deploy할 때 생성자에게 줄 값을 당연히 설정하고 deploy해야한다. 그렇다면 매개변수 값을 입력하고 deploy한 후 결과를 확인해보자.
생성자의 pNum 파라미터를 10으로 설정 한 후 deploy 하였다. 위에서 매개변수를 지정하지 않았을 때와 달리 정상적으로 deploy되며 num의 getter로 num값을 확인해보면 10이 제대로 저장된 것을 확인할 수 있다.
2. 인스턴스화
A 컨트랙트에서 B컨트랙트를 사용하고 싶을 수 있을 것이다. 우리는 다른 객체지향언어에서 클래스 변수를 만들어 사용했던 것처럼, 솔리디티에서도 컨트랙트 변수를 선언할 수 있다.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Math{
function add(uint _num1, uint _num2)public pure returns(uint){
return _num1 + _num2;
}
}
contract instanceEx{
Math public math = new Math();
function addNumbers(uint _num1, uint _num2) public view returns(uint){
return math.add(_num1, _num2);
}
}
위 코드를 보면 컨트랙트 Math를 instanceEx 컨트랙트에서 변수로 선언해 사용하는 것을 볼 수 있다. addNumbers 함수는 Math의 add 함수를 래핑한 것으로 사실상 add와 addNumbers는 모두 같은 기능을 한다고 볼 수 있다. 어찌되었건 위처럼 다른 컨트랙트를 변수로 선언해 사용할 수 있다. 그러나 중복을 싫어하는 개발자는 위와 같이 똑같은 기능을 하는 의미없는 래핑함수를 싫어할 것이다. 다른 객체지향언어가 그렇듯, 솔리디티 또한 상속을 제공하며, 부모 컨트랙트의 기능을 그대로 사용할 수 있다.
3. 상속
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Student{
function university() public pure returns(string memory){
return "The University of Solidity";
}
}
contract inheritanceEx is Student{
}
위 코드는 Student 컨트랙트를. inheritanceEx가 상속받는 코드이다. 솔리디티는 "is" 키워드를 통해 상속을 할 수 있다. 현재 inheritanceEx 컨트랙트 내부는 비어있으나 Student를 상속받았으므로, university() 함수를 사용할 수 있다. 확인해보자.
좌측 하단은 내부가 비어있는 inheritanceEx 컨트랙트를 deploy한 후 university를 호출하여 "The University of Solidity" 문자열을 출력한 것이다. 상속을 받았기 때문에 university()함수를 inheritanceEx에서 사용할 수 있는 것을 볼 수 있다. 이제 부모 컨트랙트의 함수를 오버라이딩 하는 것을 연습해보자.
4. 오버라이딩
부모 컨트랙트에서 메서드를 자식 컨트랙트가 재정의 할 수 있도록 하기 위해선 반드시 virtual 키워드를 붙여줘야한다. 확인해보자.
위 코드를 보면 university() 함수를 부모 컨트랙트인 Student에서 virtual로 지정하지 않았는데 자식 컨트랙트에서. override하여 오류가 발생하는 것을 볼 수 있다. 반드시 재정의를 할 것 같은 함수는 virtual 키워드를 붙여줘야 한다.
오버라이딩 하는 쪽에서도 override 키워드를 붙여주지 않으면 오류가 발생한다.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Student{
function university() public pure virtual returns(string memory){
return "The University of Solidity";
}
}
contract inheritanceEx is Student{
function university() public pure override returns(string memory){
return "The University of Blockchain";
}
}
위 코드가 정상적으로 오버라이딩하는 코드이다. 부모 컨트랙트는 재정의가 예상되는 함수에 대해 virtual 키워드를 붙이며 자식 컨트랙트는 이 함수를 재정의하기 위해 override 키워드를 붙인다.
좌측 결과를 보면 위는 Student, 아래는 inheritanceEx의 university()를 호출했을 때 각각의 결과이다. 자식 쪽에서 함수를 재정의 했기 때문에 문자열이 바뀐 것을 볼 수 있다.
마치며
오늘은 컨트랙트에 대해 여러가지를 다뤄보았다. 객체지향언어에 익숙한 사람들은 아마 다 아는 내용일 것이다. 솔리디티에서 contract를 class와 유사하다 생각하고(사실 거의 똑같은 것 같다) 공부하면 훨씬 수월할 것이다.
참고자료
https://www.yes24.com/Product/Goods/111099912
솔리디티 프로그래밍 완벽 가이드 - YES24
개발 경험이 없어도 쉽게 블록체인과 솔리디티를 이해할 수 있습니다!솔리디티는 스마트 컨트랙트를 구현하는 언어이며, 스마트 컨트랙트는 블록체인에서 작동하는 프로그램이다. 『솔리디티
www.yes24.com
'Blockchain > Solidity' 카테고리의 다른 글
Solidity : Event (0) | 2023.06.05 |
---|---|
Solidity : 배열 다루기 (0) | 2023.06.04 |
Solidity : memory와 storage, 그리고 문자열 비교하기 (0) | 2023.06.01 |
Solidity : 함수 및 Modifier (0) | 2023.06.01 |
Solidity : 가시성 지정자 (0) | 2023.05.31 |