C3 linearization is an algorithm that determines the order in which parent contracts are searched when a derived contract inherits from multiple parents. It's also called the Method Resolution Order (MRO).
It solves the Diamond Problem, where a contract inherits from two parents that both inherit from the same grandparent. Without C3, the compiler wouldn't know which version of a shared function to execute.
1. Fundamental Rule
The most important thing to remember for Solidity is the direction of inheritance - from "most base-like" to "most derived."
In the declaration contract Child is A, B, B is considered "more derived" than A. If both have the same function, the version in B will be checked first.
2. How the Search Order Works
When you call a function or use the super keyword, Solidity follows a flattened list generated by the C3 algorithm. The search follows these steps:
Start at the Child: Check if the function is defined in the current contract.
Move Right-to-Left: Check the parent contracts in the order they were listed, starting from the right-most one.
Go Up the Hierarchy: Move up to the grandparents only after all immediate parents have been checked.
Example: The "Diamond" Chain
contract A {
function foo() public virtual { /* Logic A */ }
}
contract B is A {
function foo() public virtual override { super.foo(); }
}
contract C is A {
function foo() public virtual override { super.foo(); }
}
// Order: A (base) -> B -> C (most derived)
contract D is B, C {
function foo() public override(B, C) {
super.foo();
}
}
The Linearization of D is: [D, C, B, A]
super.foo() in D calls C.
super.foo() in C calls B.
super.foo() in B calls A.
C3 linearization prevents contract A function being called twice.
Top comments (0)