Solidity
솔리디티의 이상한 상속 계층구조
pangyoelon
2023. 4. 26. 16:43
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/* Inheritance tree
A
/ \
B C
\ /
D
*/
contract A {
function foo() public virtual {
emit Log("A.foo called");
}
function bar() public virtual {
emit Log("A.bar called");
}
}
contract B is A {
function foo() public virtual override {
emit Log("B.foo called");
A.foo();
}
function bar() public virtual override {
emit Log("B.bar called");
super.bar();
}
}
contract C is A {
function foo() public virtual override {
emit Log("C.foo called");
A.foo();
}
function bar() public virtual override {
emit Log("C.bar called");
super.bar();
}
}
contract D is C,B {
function foo() public override(B, C) {
super.foo();
}
function bar() public override(B, C) {
super.bar();
}
}
위와 같은 예제 코드를 보았다
일반적으로 생각해 봤을 때 해당 컨트랙트들의 상속구조는 아래와 같다
A
/ \
B C
\ /
D
여기서 D컨트랙트를 배포 후 foo함수를 실행시켜보면 예상대로 동작할 것이다
그런데 문제는 D컨트랙트의 bar함수인데, bar함수를 실행시켜보면 아래와 같은 로그가 나온다
어째서일까? 답을 얻기 위해 코드에서 하나의 변인을 조작해보았다
contract D is B,C {
// 👆 순서를 C,B에서 B,C로 바꿔보았다
function foo() public override(B, C) {
super.foo();
}
function bar() public override(B, C) {
super.bar();
}
}
is 뒤의 두 컨트랙트의 순서를 바꾼 뒤, D의 bar를 실행시켜보면 결과가 전과 다르다
그렇다!
is 뒤에서 선순위 컨트랙트를 후순위 컨트랙트가 오버라이딩을 한다는 뜻은, 단지 덮어쓴다는 게 아니라
후순위 컨트랙트가 선순위 컨트랙트의 자식이 된다는 뜻이다!
즉 B와 C가 동일선상에 있는 계층구조가 아닌
A
|
B
|
C
|
D
위와 같은 직선형의 계층구조라는 것!