Improving the Ethereum Developer Ecosystem with Libraries

Daniel Que
CryptoFin
Published in
3 min readAug 13, 2018

The Ethereum development ecosystem is lacking many tools which we take for granted in other programming environments. That’s why we’ve been working on our cryptofin-solidity library.

The Stadtbibliothek Stuttgart (library) in Germany.

A good library lets developers write less code which reduces bugs and saves development time. For blockchain development, libraries are even more impactful because they:

  • save gas for end users if they’re optimized
  • reduce the amount of code that needs to be audited

We’ve collected various methods in our cryptofin-solidity repo, with an initial focus on array utilities.

We’ll show you how to set it up in less than 10 seconds, then dive into some interesting code that’ll make you feel like you’ve done something productive today!

Quickstart

npm install --save cryptofin-solidity

Use it in a project

Assuming you’re using Truffle or something similar:

import "cryptofin-solidity/contracts/array-utils/AddressArrayUtils.sol";contract Contract {
using AddressArrayUtils for address[];
function containsDeadBeef(address[] memory addresses)
returns (bool)
{
return addresses.contains(address(0xdeadbeef));
}
}

And that’s it!

For more examples and documentation, see the GitHub.

Into the weeds

Let’s look at some cool and useful functionality.

indexOf and contains

indexOf gives the first index of an element in an array. It returns (uint256, bool) which allows us to implement contains in just two lines using multiple assignment:

(, bool isIn) = indexOf(A, a);  // Ignore uint256 index
return isIn;

map, reduce, filter

These are cool because they use a relatively unknown feature of Solidity: functional programming!

reduce and filter follow similar patterns.

Example:

uint256[] memory nonZeros = array.filter(isNonZero);

union

Using other library functions included in cryptofin-solidity (difference, intersect, and extend), we can very easily compute the union of two sets.

Recall that the union of two sets is:

{A - B} + {A ^ B} + {B - A}

sPopCheap

Let’s break it down:

  • s: signifies that this operates on a storage array rather than a memory array (the default)
  • pop: removes the element at the given index and returns that element
  • cheap: The usual way to implement pop is to delete the element at index and shift all subsequent elements to the left. The gas costs scale O(n), so an alternate algorithm is used to achieve O(1): swap the element at index with the last element, then delete the last element.

sPopCheap doesn’t preserve the array order, and is meant to be used with unordered lists. Another function, sPop preserves order but is more expensive.

We chose to keep the more expensive version as sPop because it behaves as expected for new developers.

argFilter and argGet

argFilter returns the indices that would filter an array, and is inspired by numpy’s argsort. argGet is like numpy’s indexing of arrays notation.

It allows us to work with data with the following structure:

uint256[] ids: [0, 1, 2, 3, 4]uint256[] ages: [20, 35, 14, 24, 48]address[] addresses: [
0x403B5178d38Cf0520F29592c1536061Ef59ff0BD,
0xF206af3D25f9Fa27b8E68bbA7E6Da953707663D2,
0xa1949d9c2fd3B13A47B04Ae05353C0A3A7573Eb8,
0xf163A8D25BF8c09a9Df4e376A50538FeD301e18c,
0xB5172c7E6B545Fa9Bdd1adCA46fb4e03150C6b0e
]

Let’s say we want to filter out anyone under the age of 21.

function noYoungins(uint256 a) pure returns (bool) {
return a >= 21;
}

Then,

uint256[] memory indexArray = ages.argFilter(noYoungins);filteredIDs = ids.argGet(indexArray);
filteredAges = ages.argGet(indexArray);
filteredAddresses = addresses.argGet(indexArray);

Next Steps

We’d love it if you contributed any general code you’ve written that’s suitable for a library! We’ve met some great developers at events like ETHGlobal, so we know you’re out there reading this!

In the near future, we’ll be tackling the following (and would appreciate some help):

  • More functionality
  • More tests
  • Documentation
  • Gas analysis
  • Gas optimization
  • Auto-generated libraries for different types (uint128, uint64, etc.)

We hope this library is useful for your next Solidity project!

Thanks to Nemil Dalal, Mert Çelebi, Graham Kaemmer, and Liam Horne for feedback on drafts!

CryptoFin designed Bskt, a way to create decentralized ERC20 token portfolios. Join our Telegram group for updates.

--

--

Daniel Que
CryptoFin

Engineer @ Coinbase. Previously Co-Founder of CryptoFin (aq by Coinbase), Engineer @ Uber.