Skip to content

Instantly share code, notes, and snippets.

@bbozo
Last active August 25, 2017 17:53
Show Gist options
  • Save bbozo/01649c97f70559e03ce5b080a6260b08 to your computer and use it in GitHub Desktop.
Save bbozo/01649c97f70559e03ce5b080a6260b08 to your computer and use it in GitHub Desktop.
Best practices to handle amount & currency now that infinitely divisible non-ISO currencies are becoming a thing?
Classic wisdom for handling amount & currency would be to use a `char(3)` or `int` for currency and an `int` for amount, this is the norm in the financial sector since the 80s. You need to be aware which currency has which decimalization, and all good.
However, now we have an invasion of new de-facto currencies that don't necessarily have their ISO codes, so numeric ISO codes go out of the window (no more `int` for currencies) - we have NEO, litecoin, faircoin, ...
Next issue is the amount, at least with BTC we have "The Satoshi" which is [supposedly the smallest unit of BTC but not really](https://bitcoin.stackexchange.com/questions/122/will-we-ever-need-smaller-amounts-of-bitcoin-than-a-satoshi). But this is just 1 cryptocurrency out there.
At least in the Ruby community [the established "money" library](https://github.com/RubyMoney/money) uses an integer - "the cents" - as the minor unit of currency and now they set Satoshis as the cents for BTC.
However,
1. [this is not really 100% future-proof](https://bitcoin.stackexchange.com/questions/122/will-we-ever-need-smaller-amounts-of-bitcoin-than-a-satoshi) even in the limited BTC-only world,
2. new currencies may(did?) emerge which would make this setup even less viable - more currencies = more chances for somebody to have screwed up the decimalization of the smallest denomination
3. there is no good migration path for: "oops, this currency is now considered to be decimalized with 15 digits instead of 9" - this affects everything from code to apis, to databases and we all need to be in agreement at the same time
I suspect, writing this, that we need to start moving, everybody all over the globe, to a setup where we store amounts as decimals, and use decimals in our APIs.
A grueling prospect. And also, possibly an expensive one, [according to Postgresql docs](https://www.postgresql.org/docs/9.1/static/datatype-numeric.html) and [according to Oracle docs](https://docs.oracle.com/cd/B19306_01/olap.102/b14346/dml_datatypes002.htm) numerics/decimals are not recommended to be used in calculation-heavy columns (such as amounts), while traditional floats suffer from rounding errors.
I'm looking for four things here,
1. affirmation that I'm not crazy, that we really *all* need to start accepting `int` amounts as bad form and a bag of future worms future-incompatible with cryptocurrencies (and other hypothetical infinitely-divisible currencies)
2. if we're going for decimal columns in our databases, what kind of scale & precision will do? For BTC the amount range would be 1e-8 .. 1e8 - what about other currencies? [submitted also to bitcoin SE](https://bitcoin.stackexchange.com/questions/58680/minimum-and-maximum-values-of-all-cryptocurrencies)
3. what about the error handling? Sanitizing inputs to raise alarms if smaller denominations come in specific currency cases should eventually become the norm, if cryptocurrencies are indeed to take hold
4. what is the price of this migration to integers in terms of database size and speed?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment