[Memo] Formules de maths utiles pour l'analyse on-chain

flo

Administrator
Staff member
Joined
Jan 2, 2023
Messages
20
Petit thread pour répertorier les formules de maths utiles dans le cadre de l'analyse on-chain

Bitcoin

Calculer la
supply totale du BTC

On sait selon le whitepaper du Bitcoin que la récompense initiale de 50 BTC est divisée par 2 tous les 210 000 blocs, cela jusqu'à atteindre environ 21 000 000 de BTC.



Voici la formule :

Avec [imath]i[/imath] représentant une période (ou "époque") de halving, on peut le voir comme le ième halving

[imath] \small{BTC\:supply} = \displaystyle\sum_{i=0}^{32} 210000 \biggr(\frac{50}{2^i}\biggr) \approx 21000000 [/imath]

Estimer la supply du BTC au "nième" bloc (hauteur)

J'ai trouvé une formule pour estimer la supply du BTC au nième block sur Dune, sauf qu'elle est erronée... :

https://dune.com/queries/3425943/5752826

wrong-btc-supply-query-dune.png


Transformons cet agrégat SQL en notation mathématique pour une meilleure lisibilité :

[imath]round(x) = \bigl\lfloor x \bigr\rceil[/imath]

[imath] \small{incorrect\:formula} \approx \displaystyle\sum_{h=0}^n \frac{50}{2^{\bigl\lfloor \frac{h}{210000} \bigr\rceil}} [/imath]

On se rend vite compte que l'usage de ROUND est incorrect car cela estime un halving 2x plus tôt que prévu, il aurait fallu utiliser FLOOR.

Autre problème : la supply max du BTC est d'environ 20 999 999, 9769 et le Block Subsidy ne peut pas être inférieur à 1 satoshi ([imath]10^{-8}[/imath])

Hors ici il n'y a pas de limite pour le résultat, cela entraine une imprécision lorsque n vaut ou dépasse 6930000 (33e halving).

Bon, ça n'arrivera pas avant environ 2140 alors il y a le temps, mais tout de même 😁

SQL:
-- incorrect way to estimate supply

, btc_supply AS (
    SELECT SUM(50/POWER(2, ROUND(height/210000))) AS supply
    FROM bitcoin.blocks
    )
,

C'est plus parlant avec une image :

btc-subsidy-by-block-height-good-wrong.png

Sur le graphique on observe une division de la récompense par 2 à partir de 105 000 blocs au lieu de 210 000 avec la méthode de l'arrondi (round).

Il faut impérativement utiliser FLOOR(x) dans la formule !

Pour une raison que j'ignore, sur Dune les fonctions ROUND(x), CEIL(x) et FLOOR(x) agissent toutes comme FLOOR(x) dès que [imath]x[/imath] devient trop petit... Il s'agit très probablement d'un bug

C'est pour cela que même si la formule de départ est fausse, l'estimation est à peu près bonne sur Dune...

Donc prudence si vous faites des copier/coller ! Toujours vérifier ses résultats et les formules utilisées

[imath]h[/imath] représente la hauteur du bloc

[imath]\text{floor(x)} = \lfloor x \rfloor[/imath]

[imath]\text{Avec } 0 \le n < 6930000[/imath]

[imath] \small{BTC\:supply\:at\:block\:n} \approx \displaystyle\sum_{h=0}^n \frac{50}{2^{\bigl\lfloor\frac{h}{210000}\bigr\rfloor}} [/imath]

[imath]\text{Si n} \ge 6930000 \text{ alors la supply vaut 20 999 999, 9769}[/imath]

Exemple Python

Python:
import math
import numpy as np


if __name__ == '__main__':
    vf = np.vectorize(lambda h: 50 / (2 ** (math.floor(h / 210000))))

    n = 841938
    supply = vf(np.arange(n+1)).sum()
    print(f"supply at block height {n}: {supply} (approx)")

    # affichage: supply at block height 841938: 19693559.375 (approx)

Exemple SQL (Data provider: Dune)

SQL:
SELECT
    CASE
        WHEN MAX(height) >= 210000*33 THEN 20999999.9769
        ELSE SUM(50/POWER(2, FLOOR(height/210000)))
    END as supply
FROM bitcoin.blocks;

Si on obtient une bonne estimation on pourrait optimiser un petit peu les performances pour un ordinateur :

Dans la solution précédente, pour calculer la supply au block [imath]n[/imath] il faut [imath]n[/imath] itération. Pour le bloc 841938 ca veut dire 841938 tours de boucle, même si c'est presque insignifiant ça peut être drastiquement réduit

/!\ en cours de rédaction et de réflexion, erreurs possibles

[math] \text{Avec } 0≤n<6930000 \\ t = \frac{n}{210000} \\ \{t\} = t - \lfloor t \rfloor \\ \{t\} \times 210000 = n - \lfloor t \rfloor \times 210000 \\ \text{\:BTC\:supply\:at\:block\:n} \approx \displaystyle\sum_{i=0}^{\lfloor t \rfloor - 1} 210000 \biggr(\frac{50}{2^i}\biggr) + (n - \lfloor t \rfloor \times 210000 + 1)\times \frac{50}{2^{\lfloor t \rfloor}} [/math]
 
Last edited: