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?