Understanding Solidity Libraries

solidity libraries smart contracts dapps

Libraries are a way to separate out common code to help with DRY (Do not repeat yourself) paradigm. We can think of libraries as gems in ruby language or packages in python etc.

In solidity world libraries are a special type of smart contracts which contain common code. A important difference between normal smart contract and libraries is that libraries don’t have storage or ether associated with them.

Libraries also help with saving gas as the code is deployed once and used by many other contracts. You might ask how is it different from just importing the library or inherting the library and using it? Using a base contract instead of a library to split the common code won’t save gas because in Solidity, inheritance works by copying code. And the gas also depends on the size of the smart contract. Libraries also execute in the scope of the calling smart contract and has access to the existing mapping and state variable of the smart contract calling it.

Imagine if we were to implement a sorting method everytime we need to sort a set of elements? Reimplementing might be prone to bugs and may not be optimized and also a waste of time. This is where libraries shine.

A library is defined with the keyword library (library C {}) in the same way a contract is defined (contract A {}).

Calling a function of a library will use a special instruction (DELEGATECALL), that will cause the calling context to be passed to the library, as if it was code running in the contract itself.

Lets look a bit deeper as to what Delegatecall is:

Delegatecall / Callcode and Libraries
There exists a special variant of a message call, named delegatecall which is identical to a message call apart from the fact that the code at the target address is executed in the context of the calling contract and msg.sender and msg.value do not change their values.

This means that a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code is taken from the called address.

This makes it possible to implement the “library” feature in Solidity: Reusable library code that can be applied to a contract’s storage in order to e.g. implement a complex data structure

Here is an example of a library

library AwesomeLibrary {
    function getAddr() returns (address) {
        return address(this);
    }
}

contract A {
    function a() constant returns (address) {
        return AwesomeLibrary.getAddr();
    }
}

When we use inheritance it quite obvious as to how to link the code. But, in case of libraries contract A doesn’t have information about which addr to use for AwesomeLibrary. So the bytecode of contract A will have a placeholder which get filled by the linking process and points to the address of the library on the blockchain.

Comments

comments powered by Disqus