Skip to content

Instantly share code, notes, and snippets.

@h1994st
Last active June 29, 2018 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h1994st/5ef9f48040877db8e1b58e9d698c7d52 to your computer and use it in GitHub Desktop.
Save h1994st/5ef9f48040877db8e1b58e9d698c7d52 to your computer and use it in GitHub Desktop.
C3 Linearization

第三题(加分题):自学C3 Linearization, 求以下 contract Z 的继承线

  • contract O
  • contract A is O
  • contract B is O
  • contract C is O
  • contract K1 is A, B
  • contract K2 is A, C
  • contract Z is K1, K2

Solution

L(O)  := [O]

L(A)  := [A] + merge(L(O), [O])
       = [A] + merge([O], [O])
       = [A, O]
L(B)  := [B, O]
L(C)  := [C, O]

L(K1) := [K1] + merge(L(B), L(A), [B, A])
       = [K1] + merge([B, O], [A, O], [B, A])
       = [K1, B, A, O]
L(K2) := [K2] + merge(L(C), L(A), [C, A])
       = [K2] + merge([C, O], [A, O], [C, A])
       = [K2, C, A, O]

L(Z)  := [Z] + merge(L(K2), L(K1), [K2, K1])
       = [Z] + merge([K2, C, A, O], [K1, B, A, O], [K2, K1])
       = [Z, K2, C, K1, B, A, O]

From Solidity Document:

Languages that allow multiple inheritance have to deal with several problems. One is the Diamond Problem. Solidity is similar to Python in that it uses “C3 Linearization” to force a specific order in the DAG of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the is directive is important: You have to list the direct base contracts in the order from "most base-like" to "most derived". Note that this order is different from the one used in Python. In the following code, Solidity will give the error “Linearization of inheritance graph impossible”.

Code

在Remix上部署contract Z,然后看控制台输出的log顺序

pragma solidity ^0.4.14;

contract O {
    constructor() public {
        emit PrintO();
    }
    event PrintO();
}
contract A is O {
    constructor() public {
        emit PrintA();
    }
    event PrintA();
}
contract B is O {
    constructor() public {
        emit PrintB();
    }
    event PrintB();
}
contract C is O {
    constructor() public {
        emit PrintC();
    }
    event PrintC();
}
contract K1 is A, B {
    constructor() public {
        emit PrintK1();
    }
    event PrintK1();
}
contract K2 is A, C {
    constructor() public {
        emit PrintK2();
    }
    event PrintK2();
}
contract Z is K1, K2 {
    constructor() public {
        emit PrintZ();
    }
    event PrintZ();
}

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment