Cairo isn’t an object oriented language, yet we can still have mixins. Essentially, it’s possible to do the equivalent of Solidity’s is Ownable
in Cairo. All that’s necessary is to explicitly import all the public functions you want to have in your contract.
To illustrate, in the “mixin” file, we define an external function:
//
// ownable_external.cairo
//
from ownable.library import Ownable
@external
func transfer_ownership{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
new_owner: felt
) {
Ownable.transfer_ownership(new_owner);
return ();
}
Then, in the main contract file, we import from this file to make any functions available in the final compiled contract:
//
// main.cairo
//
// importing an @external function will make it available
// as an entrypoint in this main contract
from ownable.ownable_external transfer_ownership
@external
func foo() {
return ()
}
Granted, it’s not as clean as in Solidity, but it’s way better than copy-pasting functions all over your code base.
You can find a fully tested and working example in the repo.
Before Cairo v0.10.0, this used to be a security issue, because the compiler would import every public function from a module, not just those explicitly declared in the import statement. Thankfully, this is not the case anymore. Using the latest Cairo version, you can take full advantage of this technique and not loose any sleep over it.