Complete: Bounty #3 - ULID motoko library

Create a ULID Library in Motoko - #3

Amazing thanks to the The Dragginz Team for donating a fully funded bounty to ICDevs. If you have a bounty you’d like to fully fund, please reach out and we can give you the details.

Current Status: Discussion

  • Discussion (11/08/2021) ← We are here
  • Ratification
  • Open for application
  • Assigned
  • In Review
  • Closed

Bounty Details

  • Current Bounty Amount: 20 ICP
  • Match Available: 20 ICP - (For every ICP sent to 860bd56f4c8a9d40f26462e51e2a4dd4e27cf0e1463372a1179df089695bfd63, will add one more ICP to the bounty, up to 20 ICP, After 20 ICP, Donations to the above address will add .25 ICP to this issue and .75 ICP to fund other initiatives)
  • Time Left: Expires 12/31/2022
  • Project Type: Single Contributor
  • Opened: 11/08/2021
  • Time Commitment: Days
  • Project Type: Traditional
  • Experience Type: Intermediate - Motoko; Intermediate - Encoding
  • Issue Type: Application Development


This bounty gives the opportunity to

  • learn how motoko works
  • learn about unique ID encodings
  • learn about randomness on the IC

A donor(The Dragginz Team) genrously funded a full bounty for ICDevs to help find a dev that would like to build a ULID library.

The spec for ULID can be found at GitHub - ulid/spec: The canonical spec for ulid

There are a number of example libraries in other languages. You will need to transcode the library into motoko. This may require the construction of other sub libraries for encoding, string manipulation, and decoding.

There are unique properites that the IC has that you should take advantage of. The IC provides randomness via the Random base library. This library shold two modes. One where true randomness is used and another where an alternative form of randomness that does not require an async await to be used. Perhaps hasing the Principal of the canister plus an always increasing nonce might do the trick but a healthy discussion shold ensue about what will work and what won’t.

To apply for this bounty you should:

  • Include links to previous work writing tutorials and any other open-source contributions(ie. your github).
  • Include a brief overview of how you will complete the task. This can include things like which dependencies you will use, how you will make it self-contained, the sacrifices you would have to make to achieve that, or how you will make it simple. Anything that can convince us you are taking a thoughtful and expert approach to this design.
  • Give an estimated timeline on completing the task.
  • Post your application text to the Bounty Thread

Selection Process

The developer’s advisors will propose a vote to award the bounty and the Developer Advisors will vote.

Bounty Completion

Please keep your ongoing code in a public repository(fork or branch is ok). Please provide regular (at least weekly) updates. Code commits count as updates if you link to your branch/fork from the bounty thread. We just need to be able to see that you are making progress.

The balance of the bounty will be paid out at completion.

Once you have finished, please alert the dev forum thread that you have completed work and where we can find that work. We will review and award the bounty reward if the terms have been met. If there is any coordination work(like a pull request) or additional documentation needed we will inform you of what is needed before we can award the reward.

Bounty Abandonment and Re-awarding

If you cease work on the bounty for a prolonged(at the Developer Advisory Board’s discretion) or if the quality of work degrades to the point that we think someone else should be working on the bounty we may re-award it. We will be transparent about this and try to work with you to push through and complete the project, but sometimes, it may be necessary to move on or to augment your contribution with another resource which would result in a split bounty.


The bounty was generously funded by a donor(The Dragginz Team). If you would like to turbocharge this bounty you can seed additional donations of ICP to 860bd56f4c8a9d40f26462e51e2a4dd4e27cf0e1463372a1179df089695bfd63. ICDevs will match the bounty 1:1 for the first 20 ICP and then 0.25:1 after that. All donations will be tax deductible for US Citizens and Corporations. If you send a donation and need a donation receipt, please email the hash of your donation transaction, physical address, and name to More information about how you can contribute can be found at our donations page.

General Bounty Process


The draft bounty is posted to the DFINITY developer’s forum for discussion


The developer advisor’s board will propose a bounty be ratified and a vote will take place to ratify the bounty. Until a bounty is ratified by the Dev it hasn’t been officially adopted. Please take this into consideration if you are considering starting early.

Open for application

Developers can submit applications to the Dev Forum post. The council will consider these as they come in and propose a vote to award the bounty to one of the applicants. If you would like to apply anonymously you can send an email to austin at icdevs dot org or sending a PM on the dev forum.


A developer is currently working on this bounty, you are free to contribute, but any splitting of the award will need to be discussed with the currently assigned developer.

In Review

The Dev Council is reviewing the submission


The award has be been given and the bounty is closed.


We are waiting on our first community match.

Other Bounties


I have experimented with UUIDs in Motoko a few months ago. I was not aware that ulid existed. I would love to take a look at this, it looks very promising. :eyes:


I thought of you when I wrote this up. I would imagine this would be a pretty simple one for you. I know you are slammed. Know anyone else that would benefit from tackling it? UUID v4 is coming next week, so maybe you already have that one written?

I know you are slammed.

Maybe I have already played around with it… and as a result, a working prototype. :wink:

But I’d like to discuss the Random part of it, my current POC uses Random.blob, which is async. Is there a preference, sync vs async?

Good stuff here, I tried to tackle this in the past: UUIDs generator
@quint your UUID lib is amazing but my concerns regarding any uuid generator are:

  • collision probability
  • costs
  • async time delays.

The UUID’s in our app will be visible so a simple int incremental won’t just do it. Also we can’t rely on the client to provide any “help” in this process.

Here are some links:

Maybe we need to create a new UID standard based on time, canister_id and principal_id?

1 Like

These should be very low, since a ULID also contains the time of creations, and the other part is not just incremental. So you shouldn’t be able to just guess an ULID.

  • I still have not found a good way to test costs on the IC, so I have no idea, maybe I’ll do some benchmarks on a test canister.
  • Another one that can be included in these tests, I’ll provide some updates soon.

Looks like you are proactively working on this? Awesome! I have two thoughts about randomness. I think the libraries should have two modes. One that uses randomness to produce true random IDs that produce crypto secure IDs and then another mode that uses pseudo-randomness. Maybe we hash something like a blob of (Principal, timestamp, nonce). The random one will obviously take an extra round to produce which is a bummer but at least it will be offered. The pseudo-random should be ok…I really wish that motoko would expose the block or message ID in the msg variable so we could use it for this purpose. Maybe I will post a message on the forum about it.


The UUID package I wrote is based on pseudo-randomness.
The ULID package currently uses Random.blob as a source.

I’ll make sure the packages have both options.

How would a pseudo-randomness interface look like? Do we need a standard for this?
I used my IO package, but I am not sure if this is the way to go forward.

It looks like we may need to put in some requests with the Motoko team for some proper pseudo randomness. See Exposing Message ID or Message Order in a block to motoko - #4 by nomeata

In the meantime, we are going to have to look it up. I’ll take a look at UUID and see how you did it. It is probably sufficient for now.

Looks like you let the user supply their own randomness with:

public class Generator(
        rand : IO.Reader<Nat8>,
        node : [Nat8],

What is the node? I like this approach because you can stick the IC random entropy in there if you want it and it lets the user decide to do their own psuedo randomness. If they want to hash they can…or / nonce or something like that.

This is just based on the spec.

In version 1 of UUID, a node consisted of an IEEE 802 MAC address, usually the host address. Now these are drawn from, and unique within, some “name space”.

In our case this can be the canister ID f.e., or just some random entropy (it has to be 48 bits tho…)

Ok…so an easy function to translate a principal to 48 bits would be a good utility function to have.

Maybe just Hash(Principal) # 1stHalf of Hash(Principal)?

I updated the ULID package. In now includes both an async and sync option.
There is also a small example.


This Bounty is under review to be awarded to quint! Please review and provide comments at GitHub - aviate-labs/ ULID Generator for Motoko

1 Like

Bumping this post. :inbox_tray:

Same with this one. 24 more hours for comments or requests and then I’m going to award the bounty.

This Bounty has been closed out and awarded. Quint elected to forfeit the prize back to the ICDevs treasury as part of his joining the Developer Advisor’s Committee Board. We appreciated the donation and are super excited to have Quint’s influence on board. Quint has contributed an immense amount of code to the motoko ecosystem and we should all recognize his significant contributions.

Go Quint!


What’s Canister ID “f.e”? I didn’t get what f.e. is.

any update on async delays?