CHIP 2024-milli-Satoshi: increase accuracy in transactions
Title: Milli-Satoshi storage of amounts
Type: protocol upgrade
Layer: All
Owner: You?
Author(s): Tom Zander
Status: Draft
Initial Publication Date: 2024-01-02
Latest Revision Date: 2024-03-11
Version: 0.0.5
Table of Contents
Summary
This proposal is a small change in transactions in order to allow us to move from 8 digits dividing a whole BitcoinCash to add several more.
Deployment
This is a minor protocol upgrade in the form of a new transaction version where a small change is needed in software that interprets raw transactions. A more detailed explanation can be found in teams.
Motivation
BitcoinCash follows the lessons from economics and this means that the total supply of coins ever created is limited. You probably heard about the idea; there will never be more then 21 million Bitcoin.
There are obviously a lot more people that are intended to use and own some Bitcoin than 21 million and therefore there are 8 zero's behind the separator. A single unit is called "a Satoshi". Leading to not 21 million but two quadrillion one hundred trillion Satoshi. (21 e+14).
While this is a lot, with a population of 8 Billion people that leaves only 2625.00 for each person on average. The actual number of Satoshi for many people will be a lot less as wealth is simply not evenly spread and this raises the question if this can work as a world currency. A single Satoshi would be worth a lot of coffees and breads.
The idea of sub-Satoshis is not novel, it is the simple concept that instead of a bread costing $4.00 it overnight changes to cost $4.00000. Which is actually exactly the same amount, but with extra precision.
The idea, as tested in economics and concepts like stock-splits, is that we simply multiply the amount of money stored in any users wallet. Or, maybe easier to understand. We add a couple of digits behind the separator. Instead of owning $123.12, you now own $123.1200. Which is, exactly the same amount. But with more zeros at the end. We call that higher precision, or milli-Satoshis since there are 3 in our proposal.
The benefit is that as the value rises due to BitcoinCash absorbing more and more of the worlds economy, it becomes possible to start using milli-Satoshi prices for payments. We can also split the money over more people than before. Essentially it allows us to keep growing whereas otherwise the system may hit a glass ceiling where it simply can't on-board more people.
The Fee Problem
While nodes currently will not relay any transaction with a fee less than 1000 sats/kB (1 sat/byte), this parameter is trivial to change on the node level, and miners can directly accept transactions with any fee rate they wish.
If social consensus agrees that fees on BCH should not exceed something like $0.10 (2024 USD), it’s inevitable that 1 sat/byte will not be able to deliver that promise. 1 sat per USD is a price of $100,000,000 USD/BCH. That would make $546 USD the smallest transaction possible at 1 sat/byte due to dust limits, and the fee to do so would be ~$219 USD.
Measuring fees in millisats is the only way to alleviate this. At 1 millisat per byte (1 sat/kB), the minimum transaction amount becomes $0.546 USD and the fee becomes $0.219 USD instead, which is significantly closer to the fee rates we expect on BitcoinCash.
Unfortunately, this still exceeds our arbitrary $0.10 USD desired fee threshold, but we can also reasonably expect that by the time we are measuring fees in millisats, $0.10 in 2024 USD will probably be something more like $1.00 in 2036 USD.
Technical Specification
Space for more digits
The 'amount' field in a transaction is capable of expansion. It it an 8-byte number and the design is that in 120 years we'd get 20 999 999.976 900 00 BCH. (see "Controlled Supply") This, in Satoshi, is the same but without that dot. In a transaction formatting this is 6 bytes. Hex: 0x0000BEFE6F6399A8
What that means is that if 100% of all block rewards since the beginning of time end up in 1 transaction-output, the number in that transaction-output will only need 6 bytes to record the amount. The actual space reserved for this field in every transaction is actually 8 bytes. So we have space for more digits. Lets find out how much space we have, shall we?
To find out, we repeatedly multiply this huge number by 10, stopping when the total amount every minted no longer fits in 8 bytes, we get to the following outcome:
- An extra 3 digits behind the separator.
- The block reward doesn't stop after 33 halvings, but after 42.
- The extra block rewards for that 36 years add a total of 0.02307 BCH to the entire supply.
The total amount is then 2099999999997060000 Satoshi, or in hexadecimal: 0x1d24b2dfac2523a0
Supply Era's
A simple program can do the math. Below is the output:
Today's reward schedule:
| Era | Added in Era | Total supply |
|---|---|---|
| 00 | 1050000000000000 | 1050000000000000 |
| 01 | 525000000000000 | 1575000000000000 |
| 02 | 262500000000000 | 1837500000000000 |
| 03 | 131250000000000 | 1968750000000000 |
| 04 | 65625000000000 | 2034375000000000 |
| 05 | 32812500000000 | 2067187500000000 |
| 06 | 16406250000000 | 2083593750000000 |
| 07 | 8203125000000 | 2091796875000000 |
| 08 | 4101562500000 | 2095898437500000 |
| 09 | 2050781250000 | 2097949218750000 |
| 10 | 1025390520000 | 2098974609270000 |
| 11 | 512695260000 | 2099487304530000 |
| 12 | 256347630000 | 2099743652160000 |
| 13 | 128173710000 | 2099871825870000 |
| 14 | 64086750000 | 2099935912620000 |
| 15 | 32043270000 | 2099967955890000 |
| 16 | 16021530000 | 2099983977420000 |
| 17 | 8010660000 | 2099991988080000 |
| 18 | 4005330000 | 2099995993410000 |
| 19 | 2002560000 | 2099997995970000 |
| 20 | 1001280000 | 2099998997250000 |
| 21 | 500640000 | 2099999497890000 |
| 22 | 250320000 | 2099999748210000 |
| 23 | 125160000 | 2099999873370000 |
| 24 | 62580000 | 2099999935950000 |
| 25 | 31290000 | 2099999967240000 |
| 26 | 15540000 | 2099999982780000 |
| 27 | 7770000 | 2099999990550000 |
| 28 | 3780000 | 2099999994330000 |
| 29 | 1890000 | 2099999996220000 |
| 30 | 840000 | 2099999997060000 |
| 31 | 420000 | 2099999997480000 |
| 32 | 210000 | 2099999997690000 |
| 33 | 0 | 2099999997690000 |
New schedule from the point where the previous would hit zero, and with everything multiplied by 1000.
| Era | Added in Era | Total supply |
|---|---|---|
| 33 | 122220000 | 2099999999875680000 |
| 34 | 61110000 | 2099999999936790000 |
| 35 | 30450000 | 2099999999967240000 |
| 36 | 15120000 | 2099999999982360000 |
| 37 | 7560000 | 2099999999989920000 |
| 38 | 3780000 | 2099999999993700000 |
| 39 | 1890000 | 2099999999995590000 |
| 40 | 840000 | 2099999999996430000 |
| 41 | 420000 | 2099999999996850000 |
| 42 | 210000 | 2099999999997060000 |
This 1000x is us limiting ourselves based on the assumption that 100% of all BCH ever minted should still be possible to store in a single transaction-output. It should be noted that since this is never actually going to happen in practice, a further 2 zero's should be easy and mostly safe to add. But the complexity in the full node might go up as a result. For now we propose to just stick to 1000x.
New transaction version
In the May 2023 we introduced the protocol rule that transaction versions not known to the network are not allowed. This gives us a good opportunity to allow applications to use the transaction version as an indication that something is to be used slightly different again. Similar to how this is happening with version 2 transactions and BIP68.
For transactions that are marked as version 10 or later, the 'outputValue' field in each output is to be interpreted as being a number that includes milli-Satoshis.
Payments from a transaction-output with version lower than 10, to a version 10 (or higher) transaction-output will thus convert the outputValue by multiplying it with 1000. And vice versa.
A version 10 transaction can thus split an outputValue in milli-Satoshis among its outputs, should it wish to do so. Conversely, moving from a version 10 to an older transaction version will lose the spare change and that can go to the miner. A big reason to aim for the May 2025 upgrade slot is to make losing milli-coins this way not an issue. The monetary value of a single Satoshi is still low enough that that unupgraded software accidentally losing milli-Satoshis is not something that hurts them. The miner simply gets a tiny bit more income. This low cost enables us the ability to be backwards compatible with old transaction generators. A very valuable feature for our growing ecosystem.
The choice of version 10 is based on the fact that various versions have been used already in the history of BitcoinCash. Various versions have been created before the consensus rule forbidding it was created. But nothing higher than version 4. See the tx-versions.csv file for details on usage. As the first new version in years, we just jump to version 10 and any software parsing any (historical) transaction will safely be able to determine how to handle the Value field.
Scripting
Money on BitcoinCash can be unlocked and transferred only when a specific
predicate
is affirmed to be true. The predicate is expressed in "Bitcoin Script" and
parts of it are relevant to the milli-Satoshi proposal since in 2022
BitcoinCash added the Native Introspection
scripting-opcodes. The relevant instructions
are the to OP_UTXOVALUE / OP_OUTPUTVALUE.
Value based opcodes today operate on the smallest unit, a single Satoshi. Where we have 100.0 00.000 Satoshi's in a full Bitcoin. This raises the question what to do when the introspected transaction is a milli-satoshi transaction and the values are 1000 times as large. Noteworthy in this question is that with cash-tokens, a script can be forced to be copied from one transaction to the next and that means that we can't assume the script can be written to only work on one transaction-version, it should be able to function on both types of transactions.
Consider also the various math operations we have today, since 2022 we use
64-bit math. While that is a
very signification widening of range, some scripts may prefer to use the
old style Value, in full Satoshi's, in order to avoid overflows due to
bigger integer numbers of value. The Bigger Integers
CHIP
goes into some detail on this topic.
The introspection opcodes should be able to dictate which of the two representations of value they want to use. Notice, however, that such a choice should only ever happen once per script since changing mid-calculation is bound to cause problems.
We introduce OP_SET_VALUE_MODE a new opcode with code-point 0xTODO that switches between Values with 8 digits behind the full unit and 11 digits.
| Operation | Codepoint | Description |
|---|---|---|
| OP_SET_VALUE_MODE | 0xff (-1) |
Pop the top item from the stack as an enum-index. Change the VM-wide conversion for usage of OP_VALUE and 'OP_OUTPUTVALUE'. 1: Sats. 2: SubSats |
Overview
quick overview of technical changes:
- TX version would tell parsers they need to decode the TX differently.
- OPcode would maintain past & future contracts consistent:
- if executed then OP_*VALUE introspection opcodes would return millisats instead of sats (irrespective of TX version)
- if not executed then OP_*VALUE introspection would return sats irrespective of TX version, and if underlying prevout/output used millisats then they are truncated e.g. returned value will be: millisats / 1000, where / is integer division.
Feedback & Reviews
Kallisti, developer and lead engineer on the Selene wallet, supported this proposal in a bitcoincashresearch post on March 8th, 2024. https://bitcoincashresearch.org/t/1213/34
Discussion
more digits
This specification explains why we can safely get 3 extra zero's with no
real downsides in our software stacks.
The rationale there is based on the total issued supply of sats, however.
Which will never be seen in practice on a single output, or even a single
transaction.
It is fair to say that 1% of all coins will never be on a single input or output and as a result we could be mostly safe about adding an additional 2 digits for nearly free. It fits in the same 8 byte number, as long as no more than 1% of total issuable supply never ends up on a single UTXO.
The author's personal opinion is that in the far future if this is deemed needed and safe, we can simply do it then. Same trick with a new transaction version, but 50 years from now. We'd even be able to reuse the opcode and simply add an extra enum value.
Why not wait?
The obvious question that comes up is based on today's price and the absolute value of a single Satoshi being so low that we don't expect we'll need this for quite some time. So, why not wait until we actually need this?
It is a fair question and there are various answers to this. First, today's M2 (circulating money supply in dollars) was in March 2023 about the same (in dollar-cents) as the amount of Satoshi's are in BitcoinCash. Having an optimistic outlook on the world economy means that on a long enough timescale we will actually need the the added accuracy. Coming to the conclusion that we will need it, the question left is one of when it would be best to do.
This proposal uses the fact that a single-Satoshi has extremely low value as an advantage. Most teams do not need to upgrade their software, because going from a transaction with milli-Satoshi to one without loses a minuscule fraction of a penny to fees.
Doing the upgrade earlier allows everyone to get used to the idea and plan their setup accordingly. And that makes 'now' the cheapest time to do the upgrade for the entire BitcoinCash ecosystem.
Changelog
At the end of 2023 the proposal was massively simplified after realization that some problems that were solved with the extra complexity was a non-issue in practice. Check git if you're curious.
March 2024 this proposal got renamed from 'CHIP-subSatoshi' to the more apt 'CHIP-milli-satoshi'
Copyright
Copyright (C) 2023-2024 Tom Zander
Copyright (C) 2024 Kallisti
Copyright (C) 2024 BitcoinCashAuthist
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.