🎓 A1Learner
🔍
0 of 48 lessons completed

Solidity Using For

Using for is a line that attaches library functions to a type. After it, a value of that type can call those functions directly.

Using for lets a value call a library function

The line attaches DoubleLib to uint256. Then x.double() works.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
library DoubleLib {
    function double(uint256 x) internal pure returns (uint256) {
        return x * 2;
    }
}

contract Calculator {
    using DoubleLib for uint256;

    function doubled(uint256 x) public pure returns (uint256) {
        return x.double();
    }
}

The value becomes the first argument

a.add(b) means AddLib.add(a, b). The direct call gives the same answer.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
library AddLib {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }
}

contract Adder {
    using AddLib for uint256;

    function sum(uint256 a, uint256 b) public pure returns (uint256) {
        return a.add(b);
    }

    function direct(uint256 a, uint256 b) public pure returns (uint256) {
        return AddLib.add(a, b);
    }
}

Using for star attaches to every type

The star attaches MultiLib to all types. Each function still runs only on its own type.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
library MultiLib {
    function inc(uint256 x) internal pure returns (uint256) {
        return x + 1;
    }

    function flip(bool b) internal pure returns (bool) {
        return !b;
    }
}

contract AllTypes {
    using MultiLib for *;

    function run() public pure returns (uint256, bool) {
        uint256 n = 4;
        bool f = true;
        return (n.inc(), f.flip());
    }
}

Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
library PriceMath {
    function withTax(uint256 price, uint256 percent) internal pure returns (uint256) {
        return price + price * percent / 100;
    }

    function withDiscount(uint256 price, uint256 percent) internal pure returns (uint256) {
        return price - price * percent / 100;
    }
}

contract Order {
    using PriceMath for uint256;

    uint256 public price;

    function setPrice(uint256 p) public {
        price = p;
    }

    function checkout() public view returns (uint256) {
        return price.withTax(10).withDiscount(5);
    }
}

Key points

  • Using for: a declaration that attaches library functions to one type.
  • Use using for to write x.double() instead of DoubleLib.double(x).
  • The value before the dot becomes the first argument of the library function.
  • A using for line inside a contract applies to that contract only.
  • Using for * attaches a library to every type, and each function still runs only on its own first argument type.

In this example, PriceMath holds a tax function and a discount function. Order attaches PriceMath to uint256. Its checkout function first adds tax to the price, then takes a discount from that taxed price, and returns the result.

Note

using for works only with library functions, not with ordinary contract functions.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Remix IDE

Exercise

In x.add(y) with using AddLib for uint256, what does x become?