# Inheritance, Interfaces, Abstract Contracts and Libraries — Blockchain & Smart Contracts (Solidity)

Source: https://www.geekswithgeeks.com/en/solidity/d-inheritance

> Structure code with inheritance, interfaces and libraries.

## Reusing and structuring code

Contracts can **inherit** from others with `is`: `contract Shop is Ownable, Pausable`. Solidity supports **multiple inheritance** and resolves it with **C3 linearisation**; list parents from "most base" to "most derived". Functions intended to be overridden are marked **`virtual`**, and overriding functions use **`override`** (listing all parents when ambiguous, such as `override(A, B)`). **`super.fn()`** calls the next implementation in the linearisation. An **abstract contract** has at least one unimplemented function and cannot be deployed. An **interface** declares only external function signatures, events and errors, with no state or implementation; interfaces such as `IERC20` let your contract call any compliant contract. **Libraries** hold reusable functions: `internal` library functions are inlined into the calling contract, while `public` ones are deployed separately and linked. **`using SafeCast for uint256;`** attaches library functions to a type so you can write `x.toUint128()`. Prefer **composition** and small, focused contracts; deep inheritance trees make audits harder.

## An interface, an abstract base and a library

Calling any ERC-20 through its interface.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IERC20Minimal {
    function balanceOf(address account) external view returns (uint256);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

library Percent {
    function bps(uint256 amount, uint256 basisPoints) internal pure returns (uint256) {
        return (amount * basisPoints) / 10_000;
    }
}

abstract contract FeeCollector {
    using Percent for uint256;

    address public immutable treasury;

    constructor(address treasury_) {
        treasury = treasury_;
    }

    function feeBps() public view virtual returns (uint256);   // derived contracts decide

    function _fee(uint256 amount) internal view returns (uint256) {
        return amount.bps(feeBps());
    }
}

contract Checkout is FeeCollector {
    IERC20Minimal public immutable token;

    constructor(IERC20Minimal token_, address treasury_) FeeCollector(treasury_) {
        token = token_;
    }

    function feeBps() public pure override returns (uint256) {
        return 100;                                              // 1%
    }

    function pay(address merchant, uint256 amount) external {
        uint256 fee = _fee(amount);
        require(token.transferFrom(msg.sender, treasury, fee), "fee transfer failed");
        require(token.transferFrom(msg.sender, merchant, amount - fee), "payment failed");
    }
}
```

## A standard plug socket

An interface is a standard plug socket: any appliance (token) that follows the standard fits, without the wall needing to know which brand it is. Libraries are the shared toolbox every electrician carries.

**Quiz:** What is an interface in Solidity?

- [ ] A contract with full implementations
- [ ] A library
- [ ] A deployed proxy
- [x] A declaration of external functions, events and errors with no state or implementation

*Answer:* A declaration of external functions, events and errors with no state or implementation. Interfaces describe how to call contracts without implementing anything.
