Smart Contract Development
  • Introduction
    • What is a Transaction
    • Accounts and Signing
    • What is a smart contract
  • Learning Solidity
    • Introduction
    • Module 1
      • Variable Types
      • Variable Scope: State & Local variables
      • Global variables
      • Functions
        • View and Pure
        • Shadowing in Fuctions
      • Mapping
      • Require
      • Events
    • Project #1: Simple Registry
    • Module 2
      • Constructor
      • Data Location: Value & Reference
      • Interface
      • Import
        • Importing in Foundry
      • Inheritance
      • ERC-20
      • Checks-effect-interaction pattern
    • Project #2: Basic Vault
    • Module 3
      • Payable
      • Receive
      • Fallback
      • Returns
    • Project #3: ERC20+ETH Wrapper
    • Module 4
      • Immutable and Constant
      • Fixed-point Math
      • Abstract contracts
      • ERC-4626
      • Modifier + Inheritance +Ownable
      • Type
    • Project #4: Fractional Wrapper
    • Module 5
      • If-else
      • Libraries
        • TransferHelper
      • Chainlink Oracle
    • Project #5: Collateralized Vault
  • Compendium
    • Solidity Basics
      • Variable Types
      • Value Types
        • address
        • enum
      • Reference Types
        • strings
        • mappings
        • struct
        • Arrays
        • Multi-Dimensional arrays
      • Global Objects
      • Functions
        • Function types
        • Constructor Function
        • Transaction vs Call
        • Require, Revert, Assert
      • Function signature + selectors
      • Payable
        • Payable + withdraw
        • msg.value & payable functions
      • Receive
      • Fallback function (sol v 0.8)
        • Fallback function (sol v 0.6)
      • call, staticcall, delegatecall
    • Return & Events
    • Control Variable Visibility
    • Local Variables (Storage v Memory)
    • Data Location and Assignment Behaviors
    • Modifiers & Inheritance & Import
      • import styles
    • Interface & Abstract Contracts
    • ABI & Debugging
    • Libraries
    • Conditional(ternary) operators
    • Smart Contract Life-cycle
      • Pausing Smart Contracts
      • Destroying Smart Contracts
    • Merkle Trie and MPT
    • Merkle Tree Airdrop
  • Try & catch
  • Ethereum Signatures
  • EVM, Storage, Opcodes
    • EVM
    • Wei, Ether, Gas
    • Storage
    • ByteCode and Opcodes
    • Transaction costs & Execution costs
  • Reading txn input data
  • Data Representation
  • Yul
    • Yul
      • Intro
      • Basic operations
      • Storage Slots
      • Storage of Arrays and Mappings
      • Memory Operations
      • Memory: how solidity uses memory
      • Memory: Return, Require, Tuples and Keccak256
      • Memory: Logs and Events
      • Inter-contract calls
      • calldata
      • free memory pointer
    • Yul Exercises
      • read state variable
      • read mapping
      • iterate Array, Return Sum
    • memory-safe
  • Upgradable Contracts
    • Upgradability & Proxies
    • UUPS Example
    • Minimal Proxy Example
    • TPP Example
    • 🚧Diamond
      • On Storage
  • Gas Opt
    • Block Limit
    • gasLimit & min cost
    • Solidity Optimiser
    • Memory v calldata
    • Memory caching vs direct storage vs pointers
    • < vs <=
    • reverting early
    • X && Y, ||
    • constant and immutable
    • caching sload into mload
    • Syntactic Sugar
    • using unchecked w/o require
    • Compact Strings
    • Calling a view function
    • Custom errors over require
    • usage of this.
      • multiple address(this)
  • ERCs & EIPs
    • ERC-20.sol
      • Core functions
      • transfer()
      • transferFrom()
      • TLDR transfer vs transferFrom
    • Landing
      • ERC721.sol
      • EIP-721
        • LooksRare
        • Page 1
      • ERC-1271
      • EIP-2981
      • ERC-165
      • EIP-1167: Minimal Proxy Contract
    • VRFConsumerBase
    • UniswapV2Library
  • Yield Mentorship 2022
    • Projects
      • #1 Simple Registry
      • #2 Basic Vault
      • #3 ERC20+ETH Wrapper
        • setFailTransferTrue
      • #4 Fractional Wrapper
      • #5 Collateralized Vault
        • Process
        • Vault.sol
        • Testing
        • Chainlink Oracles
        • Pricing + Decimal scaling
        • Refactor for Simplicity
      • #9 Flash Loan Vault
        • Implementing ERC3156
        • Full code for lender
        • Ex-rate calculation
    • State Inheritance Testing
    • Testing w/ Mocks
    • Yield Style Guide
    • Github Actions
    • TransferHelper.sol
    • math logic + internal fn
    • Interfaces: IERC20
  • Foundry
    • Overview
    • Importing Contracts
    • Testing
      • stdError.arithmeticError
      • assume vs bound
      • Traces
      • label & console2
      • std-storage
  • Smart Contract Security
    • Damn Vulnerable Defi
      • 1. Unstoppable
      • 2. Naive receiver
      • 3. Truster
      • 4. Side Entrance
      • 5. The Rewarder
      • 6. Selfie
      • 7. Compromised
      • 8. Puppet
      • 9. Puppet V2
      • 10 - Free Rider
    • Merkle Tree: shortened proof attack
  • Fixed-Point Math
    • AMM Math
  • Solidity Patterns
    • checks-effects-interactions pattern
    • Router // batch
    • claimDelegate: stack unique owners
    • claimDelegate: cache previous user
  • Array: dup/ascending check
  • Deployment
    • Behind the Scenes
    • Interacting with External Contracts
    • Logging, Events, Solidity, Bloom Filter
  • Misc
    • Mnemonic Phrases
    • Bidul Ideas
  • Archive
    • Brownie Framework
      • Brownie basics
        • storing wallets in .env
        • Deployment to ganache
        • Interacting with contract
        • Unit Testing
        • Testnet deployment
        • Interacting w/ deployed contract
        • Brownie console
      • Brownie Advanced
        • Dependencies: import contracts
        • helpful_scripts.py
        • verify and publish
        • Forking and Mocking
        • Mocking
        • Forking
      • Testing
      • Scripts Framework
        • deploy.py
        • get_accounts
        • deploy_mocks()
        • fund_with_<token>()
      • Brownie Networks
    • Brownie Projects
      • SharedWallet
        • Multiple Beneficiaries
        • Common Code Contract
        • Adding Events
        • Renounce Ownership
        • Separate Files
      • Supply Chain
        • ItemManager()
        • Adding Events
        • Adding unique address to each item
      • Lottery
      • Aave - Lending and Borrowing
        • Approve & Deposit
        • Borrow
      • NFT
      • Advanced Collectible
        • adv_deploy() + Testing
        • Create Metadata
        • Setting the TokenURI
    • node npm
    • Ganache
    • Truffle
    • Remix
    • Installing Env
Powered by GitBook
On this page
  • TLDR
  • Old (for streamlining)
  • Benefits
  • Limitations
  • How to deploy libraries?
  1. Compendium

Libraries

https://jeancvllr.medium.com/solidity-tutorial-all-about-libraries-762e5a3692f9 https://medium.com/coinmonks/all-you-should-know-about-libraries-in-solidity-dd8bc953eae7

TLDR

You can use a library in two ways

  1. import, then call library functions: myLibrary.someFunction();

  2. import then attach via using keyword: using LibClone for address;

In method two, we are attaching the functions in the library as methods to variable type as declared in the using statement.

Example:

import {MathLib} from  './lib-file.sol';

contract test {
    using MathLib for uint;

    
    function testFn() external {
        uint a = 10;
        uint b = 10;
        uint c = a.subUint(b); // same as c = a - b
    }
}
  • library functions are attached and can be applied to uint variables.

  • uint variables have additional methods courtesy of the library.

  • with this approach, when you call a library function, these functions will receive the object they are called on as their first parameter.

    • subUint takes 2 parameters, a and b.

Old (for streamlining)

Similar to contract (contract{}), a library is a different type of Smart Contract that contains reusable code. Similar to a package in python.

Once deployed on the blockchain (only once) it is assigned a specific address, and its properties/methods can be used by other contracts in the Ethereum network.

They enable to develop in a more modular way. It is helpful to think of a library as a singleton in the EVM, a piece of code that can be called from any contract without the need to deploy it again.

pragma solidity ^0.5.0;

library libraryName {
    // struct, enum or constant variable declaration
    // function definition with body
}

pragma solidity ^0.5.0;
library MathLib {
    
    struct MathConstant {
        uint Pi;             // π (Pi) ≈ 3.1415926535...
        uint Phi;            // Golden ratio ≈ 1.6180339887...
        uint Tau;            // Tau (2pi) ≈ 6.283185...
        uint Omega;          // Ω (Omega) ≈ 0.5671432904...
        uint ImaginaryUnit;  // i (Imaginary Unit) = √–1
        uint EulerNb;        // Euler number ≈ 2.7182818284590452...
        uint PythagoraConst; // Pythagora constant (√2) ≈ 1.41421... 
        uint TheodorusConst; // Theodorus constant (√3) ≈ 1.73205... 
    }   
}
pragma solidity 0.8.3;
//calling the lib
import "https:github.com/OpenZepplin/openzepplin-contracts/contracts/math/SafeMath.sol";

contract LibrariesExample {

    using SafeMath for uint;   //using the lib for uint methods like .add/.sub(_amt)

    mapping(address=> uint) public tokenBalance;

    constructor() {
        tokenBalance[msg.sender] = 1;
    }

    function sendToken(address _to, uint _amt) public returns(bool){
        tokenBalance[msg.sender] -= tokenBalance.[msg.sender].sub(_amt);
        tokenBalance[_to] += tokenBalance.[msg.sender].add(_amt);

        return true;
    }
}

Benefits

  • Usability: Functions in a library can be used by many contracts. If you have many contracts that have some common code, then you can deploy that common code as a library.

  • Economical: Using a base contract to deploy the common code won’t save gas because in Solidity, inheritance works by copying code. However, deploying common code as library will save gas

    • as code is reused using the DELEGATECALL feature and execution is done within the context of the calling contract.

  • Good add-ons : Solidity libraries can be used to add member functions to data types. For instance, think of libraries like the standard libraries or packages that you can use in other programming languages to perform complex math operations on numbers.

Limitations

Libraries in Solidity are considered stateless, and hence have the following restrictions:

  • They do not have any storage (so can’t have non-constant state variables)

    • Can hold struct and enum : these are user-defined variables.

    • any other variable defined as constant (immutable), since constant variables are stored in the contract’s bytecode, not in storage.

  • They can’t hold ETH

    • can’t have a fallback function

    • Doesn’t allow payable functions

  • Cannot inherit nor be inherited

  • Can’t be destroyed (no selfdestruct() function since version 0.4.20)

How to deploy libraries?

Library deployment is a bit different from regular smart contract deployment. Here are two scenarios :

  1. Embedded Library: If a smart contract is consuming a library which have only internal functions, then the EVM simply embeds library into the contract. Instead of using delegate call to call a function, it simply uses JUMP statement (normal method call). There is no need to separately deploy library in this scenario.

  2. Linked Library : On the flip side, if a library contain public or external functions then library needs to be deployed. The deployment of library will generate a unique address in the blockchain. This address needs to be linked with calling contract.

Read More:

PreviousABI & DebuggingNextConditional(ternary) operators

Last updated 2 years ago

https://jeancvllr.medium.com/solidity-tutorial-all-about-libraries-762e5a3692f9
https://www.youtube.com/watch?v=25MLAnIzXRw
https://coinsbench.com/deep-dive-into-solidity-libraries-e9bd7f9061fb