Skip to content

Instantly share code, notes, and snippets.

@corollari
Last active December 8, 2020 13:58
Show Gist options
  • Save corollari/49fdd265c423e99aa2ee5613a3a0fed2 to your computer and use it in GitHub Desktop.
Save corollari/49fdd265c423e99aa2ee5613a3a0fed2 to your computer and use it in GitHub Desktop.
Script to compute the rate of deposits for bitcoin's top 100 richlist
# Written by M. Umpalumpa
# cat dades.txt | cut -d '|' -f 2 | sed 's/$/,/g'
library("tidyverse")
library("scales")
library("cowplot")
m=c(32.13020295700615, 99.1405981485184, 1.5942239429670317, 0.1022817979395588, 89.89998743639623, 22.04740581659658, 2.908773788484201, 2.128161394532075, 19.854438448603766, 6.100715578450923, 73.52812544028787, 0.15303352123049677, 2.057510431112946, 0.5090975471690009, 8.822847307873154, 0.9646507894505084, 10.633486158012644, 10.752961215353686, 0.623227667529089, 1.9249673092713593, 1062.3245263045403, 2.4026945192310976, 0.4724306252362129, 0, 0, 2.4370985287994262, 2.4025600190304695, 14.294229431358646, 5.561130232484709, 58.91914985068248, 1.3802330592663525, 4.39056552762256, 2.282080180456862, 170.09152041345268, 183.1396468217296, 26.70259034244617, 0.8114306181571791, 110.40120381282193, 629.1901071865803, 0.09634317553917675, 9690.707387984183, 64.81246759592297, 8.264424183171974, 0.34785172662825015, 72.49889444967448, 0.42934251886068325, 10.412053236355401, 0.721121356815158, 3.538236334625577, 1.2975033319020317, 1.8473425565836425, 0.34602750250117026, 21.43199865405744, 23.470061487816267, 36.42082954731172, 1109.247123248382, 1.3715734512332565, 7.738292271116461, 0.2740771388821822, 5.447575799637094, 4.952785738799368, 8.418408475531285, 7.428006780670688, 10.897278714302988, 5.942404311326634, 6.462912227839712, 2.971669762950973, 7.922417042697852, 6.96018257997784, 3.466689988366891, 7.954492829301953, 5.447569626195021, 7.457335617423419, 8.420616512018238, 5.942801563577606, 8.420614947766065, 6.463021752490337, 7.457332089368785, 156.64831498077817, 4.457499181664657, 3.466053201221793, 55.31556384845805, 56.46875491776793, 4.971551902002461, 1.0154010621155045, 5.803659035834764, 5.0067007034033875, 0.10709691842662696, 0.6157780820902925, 454.530592032388, 0.10413800942306717, 0.5328328677059091, 0.10413738699748205, 0.10322031479468731, 0.3181980814700788, 0.1041368354875974, 0.1032188849206809, 21.526467812320675, 0.10413779757411977, 0.10413779550738553)
#length(m) 100
m=m/12
M=tibble(m)
L=tibble(sort(m)[1:80])
ggplot(data=M, aes(m)) +
geom_histogram(col="brown", fill="orange", alpha=0.2, binwidth=30)+
labs(title="Incoming transactions for Bitcoin's top 100 holders") +
labs(x="Average number of monthly transactions per address", y="% of total")+
scale_y_continuous(labels = scales::percent_format(scale=1)) -> FigA
ggplot(data=L, aes(sort(m)[1:80])) +
geom_histogram(col="brown", fill="orange", alpha=0.2, binwidth=0.1)+
labs(title="Zoomed on first 80% of addresses") +
labs(x="Average number of monthly transactions per address", y="% of total")+
scale_y_continuous(labels = scales::percent_format(scale = 0.8)) -> FigB
finalplot=plot_grid(FigA,FigB,labels="AUTO")

Go to https://bitinfocharts.com/top-100-richest-bitcoin-addresses.html and execute the following code in the console:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const txsPerMonth = []

let addresses = Array.from(document.querySelectorAll('.table>tbody>tr>td:nth-child(2)>a')).map(a=>a.innerText)

// Sequential to avoid triggering rate limits
for(const addr of addresses){
  // This counts the movement per block instead of per transaction, but in this case it's alright since it's not normal to send two big transactions to cold storage in the same block
  const rawAddrPage=await fetch(`https://bitinfocharts.com/bitcoin/address/${addr}-full`).then(res=>res.text())
  const txs = Array.from(new DOMParser().parseFromString(rawAddrPage, "text/html").querySelectorAll('.trb'))
  const incomingTx = txs.filter(tx=>tx.querySelector(".text-success")!==null)
  // Filter the ones below 1000$ (dust)
  const nondustTx = incomingTx.filter(tx=>{
    const amountElem = tx.querySelector('.muteds.hidden-phone')
    if(amountElem === null){
      return false // Zero amount or tx created before 2010 (no price available)
    }
    const value = Number(amountElem.innerText.match(/[0123456789\.,]+/ig)[0].replace(/,/g, ''))
    return value > 1000
  })
  firstTxTime = Date.parse(txs[txs.length-1].querySelector('.utc').innerText.match(/.* /))
  totalInterval= (Date.now()-firstTxTime)/1e3
  const txsPerSec =  nondustTx.length/totalInterval
  txsPerMonth.push(txsPerSec*3600*24*30)
  console.log(addr, txsPerSec*3600*24*365)
  await sleep(5*1000) // 5 secs
}

const half= Math.floor(txsPerMonth.length/2)
median = txsPerMonth.sort()[half]
console.log(median)

Caveats

  • Only transactions with a value higher than 1000$ are counted, this is because these high value addresses tend to attract a lot of dust transactions (and some transactions that are pretty high, for example one was worth 600$ but clearly wasn't made by the owner since all the other transactions were higher than 1M$) and these need to be filtered out. A side-effect of this is that transactions made before 2010 are not counted, since before then no price was available. I think this is fine since back then the amounts transferrable in Bitcoin were quite small, so none of the attributes or characteristics of vaults are really applicable. Furthermore, these don't skew the graph, since there's already a lot of addresses with low amounts of incoming transactions and not many that had transactions that old.
  • Due to how information on bitinfocharts.com is structured, we have to base our analysis on a per-block level instead of a transaction one. I don't believe this to be a problem since it's very unlikely to perform two transactions to a cold wallet in the same blocks and, in case this happens, it could still be seen as a single transaction from the end user, since the spending protocols will only be exercised once.
Address Transactions per year
35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP 32.13020295700615
34xp4vRoCGJym3xR7yCVPFHoCNxv4Twseo 99.1405981485184
37XuVSEpWW4trkfmvWzegTHQt7BdktSKUs 1.5942239429670317
1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF 0.1022817979395588
1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ 89.89998743639623
bc1qa5wkgaew2dkv56kfvj49j0av5nml45x9ek9hz6 22.04740581659658
37tRFZw7n94Jddq6TfVs3MbCXmDX6eMfeY 2.908773788484201
3JurbUwpsAPqvUkwLM5CtwnEWrNnUKJNoD 2.128161394532075
38UmuUqPCrFmQo4khkomQwZ4VbY2nZMJ67 19.854438448603766
bc1qgdjqv0av3q56jvd82tkdjpy7gdp9ut8tlqmgrpmv24sq90ecnvqqjwvw97 6.100715578450923
3Kzh9qAqVWQhEsfQz7zEQL1EuSx5tyNLNS 73.52812544028787
1LdRcdxfbSnmCYYNdeYpUnztiYzVfBEQeC 0.15303352123049677
1AC4fMwgY8j9onSbXEWeH6Zan8QGMSdmtA 2.057510431112946
385cR5DM96n1HvBDMzLHPYcw89fZAXULJP 0.5090975471690009
3PKgBYdKoXABCa8ec5Ypm73nKeAvJxtnSb 8.822847307873154
1LruNZjwamWJXThX2Y8C2d47QqhAkkc5os 0.9646507894505084
3Ee3Cft7X4DbRzMoBdaKWrCZ4AqriA5sbF 10.633486158012644
3FGKwP7XQA9Gb27if7zQGJSSynbzWLrV3p 10.752961215353686
bc1q5shngj24323nsrmxv99st02na6srekfctt30ch 0.623227667529089
17hf5H8D6Yc4B7zHEg3orAtKn7Jhme7Adx 1.9249673092713593
3LCGsSmfr24demGvriN4e3ft8wEcDuHFqh 1062.3245263045403
1BX5MXZ95rMiQJBH9yKpcmbAt9VcfyAfHE 2.4026945192310976
13JQwoSLLR3ffXwswe2HCTK9oq4i8MWK3q 0.4724306252362129
12ib7dApVFvg82TXKycWBNpN8kFyiAN1dr 0
12tkqA9xSoowkzoERHMWNKsTey55YEBqkv 0
1NH8vuaJaMXbtj4Qx6iFaQY8btdVcAn9iz 2.4370985287994262
1ANjYHibCQ6FzagLfeXubC8SQYDfUS5wAJ 2.4025600190304695
3H5JTt42K7RmZtromfTSefcMEFMMe18pMD 14.294229431358646
1AnwDVbwsLBVwRfqN2x9Eo4YEJSPXo2cwG 5.561130232484709
3EiEN1JJCudBgAwL7c6ajqnPzx9LrK1VT6 58.91914985068248
1932eKraQ3Ad9MeNBHb14WFQbNrLaKeEpT 1.3802330592663525
14eQD1QQb8QFVG8YFwGz7skyzsvBLWLwJS 4.39056552762256
3EcoyfYvsBXBwdbdf4SY6DAU84kqS6mNLs 2.282080180456862
12vu5hGbWNUu4JvcUwCs52ERDbrp7zFG99 170.09152041345268
3Pja5FPK1wFB9LkWWJai8XYL1qjbqqT9Ye 183.1396468217296
1aXzEKiDJKzkPxTZy9zGc3y1nCDwDPub2 26.70259034244617
17rm2dvb439dZqyMe2d4D6AQJSgg6yeNRn 0.8114306181571791
3ErNFK17MbH3GAGfakMwTrKo8uHmBuuVX1 110.40120381282193
3JZq4atUahhuA9rLhXLMhhTo133J9rF97j 629.1901071865803
1PeizMg76Cf96nUQrYg8xuoZWLQozU5zGW 0.09634317553917675
19iqYbeATe4RxghQZJnYVFU4mjUUu76EA6 9690.707387984183
3ETUmNhL2JuCFFVNSpk8Bqx2eorxyP9FVh 64.81246759592297
3HroDXv8hmzKRtaSfBffRgedKpru8fgy6M 8.264424183171974
1GR9qNz7zgtaW5HwwVpEJWMnGWhsbsieCG 0.34785172662825015
3NmTt7XQmR3S9sPQnbfqSFjKb3gb2uzMLt 72.49889444967448
3N9an8wv4SYi3FVXs3xR5k2AqXeNZiw2mf 0.42934251886068325
38Md7BghVmV7XUUT1Vt9CvVcc5ssMD6ojt 10.412053236355401
1KUr81aewyTFUfnq4ZrpePZqXixd59ToNn 0.721121356815158
3BMEXqGpG4FxBA1KWhRFufXfSTRgzfDBhJ 3.538236334625577
3DwVjwVeJa9Z5Pu15WHNfKcDxY5tFUGfdx 1.2975033319020317
3FrM1He2ZDbsSKmYpEZQNGjFTLMgCZZkaf 1.8473425565836425
1BZaYtmXka1y3Byi2yvXCDG92Tjz7ecwYj 0.34602750250117026
1MDq7zyLw6oKichbFiDDZ3aaK59byc6CT8 21.43199865405744
3DVJfEsDTPkGDvqPCLC41X85L1B1DQWDyh 23.470061487816267
1PJyv83xXVL7fFYyYVZY53DjZj5qXZQvsw 36.42082954731172
34Jpa4Eu3ApoPVUKNTN2WeuXVVq1jzxgPi 1109.247123248382
1Cr7EjvS8C7gfarREHCvFhd9gT3r46pfLb 1.3715734512332565
3JPauiFhP4K3AevmgNMFfMSN7pLZbuADJQ 7.738292271116461
1HBM45n214sV9yXoizBwTksUgEysTPpk46 0.2740771388821822
12n3s8MCqdZzPnTisYrXagbfw8pJg8y9BW 5.447575799637094
1MVo3EXLakJym29CFK6o1MyaCBMdvcmmrL 4.952785738799368
14Ai5GcasUdr5hR2GMzeojkzB9cm4oufHt 8.418408475531285
1Q7cu7WkeDurYgffeEc9CEnA6zLohbh9iQ 7.428006780670688
1FUBESNxB2JkyXPc4o9wwoGt158DC9A8dj 10.897278714302988
16Azr3MAzMKMPmxZXfRsBbBPYHnp2CuJNJ 5.942404311326634
1EDRfeNkjkH2SAhSbEKzhKuabnEbVWbKEp 6.462912227839712
1JYbzYitYQ1ZWTx5KEx7WH2AejC5i5UUbF 2.971669762950973
1JpiTWauQdtysbynNp88dWeuyg2gBbKDcT 7.922417042697852
14YN9Zsx4H8DXUoK2XfRvjuanfjK1RrkHz 6.96018257997784
1Enhkd9LkQV56a9M12P4VuMDkjyTeLJy5m 3.466689988366891
1Cb1G5qFK91fShyaPPZWVFwYFBtqRG7h8D 7.954492829301953
1MqAfNMgbZoKtRinT89q1faSZqTKTqCFhR 5.447569626195021
1Hyh53PULY6Jyq5LPAJ4CHjgzEbVaqy7KU 7.457335617423419
19Te6hzGFSbryomVYqzG2kpBmAJYykx5Yv 8.420616512018238
1NNGdZMYsN9pgLSXZ5dD5KFUbatFynpmvY 5.942801563577606
1C5TB2QzeDDJUE4EQD17NmSyEXTk34huRo 8.420614947766065
1C1bbDApniTd7DtUodpr3ayXxVtcHvwWgx 6.463021752490337
1LyTftu54VMYCv5pq3S4pMzPRMnsYKTESw 7.457332089368785
3FmSqKEoqa8fqLjFRVaNbs9kvbFYqFxLDM 156.64831498077817
17YyZSNFt31pzGXfZtrzs7Y5Nd56rG2uU5 4.457499181664657
1q9kwzJggw6AbQjzJeYQFYK8D5gQK8sSh 3.466053201221793
3DgMKS1HVjYXs1mHXoBtPrzSxvv7sx9Fkz 55.31556384845805
34MSicAL7qVGkevFPLwyc9KohGzoUSnu3Q 56.46875491776793
14zukxqLuLXg5kqZYRB1Q3Audec3NtxJPW 4.971551902002461
19G5kkYvjawZiYKhFeh8WmfBN31pdP94Jr 1.0154010621155045
3JSssZCJ3PHEdgNv7hzNE26EEzzvYNjZLy 5.803659035834764
17rfparnM8RaaUyuHFNC9ErqkvRqebNPjE 5.0067007034033875
1F34duy2eeMz5mSrvFepVzy7Y1rBsnAyWC 0.10709691842662696
3AWpzKtkHfWsiv9RGXKA3Z8951LefsUGXQ 0.6157780820902925
1BxgwUXszgVMrs9ZSfdcGLqne2vMYaW8jf 454.530592032388
1f1miYFQWTzdLiCBxtHHnNiW7WAWPUccr 0.10413800942306717
3E5B5QbDjUL471PEed9vZDwCSck9btBLkD 0.5328328677059091
14YK4mzJGo5NKkNnmVJeuEAQftLt795Gec 0.10413738699748205
1KbrSKrT3GeEruTuuYYUSQ35JwKbrAWJYm 0.10322031479468731
1Ki3WTEEqTLPNsN5cGTsMkL2sJ4m5mdCXT 0.3181980814700788
1P1iThxBH542Gmk1kZNXyji4E4iwpvSbrt 0.1041368354875974
12tLs9c9RsALt4ockxa1hB4iTCTSmxj2me 0.1032188849206809
1CLDGCwHYuUwfmiF5F1YWWBwZuThe6MwX2 21.526467812320675
1BAFWQhH9pNkz3mZDQ1tWrtKkSHVCkc3fV 0.10413779757411977
1ucXXZQSEf4zny2HRwAQKtVpkLPTUKRtt 0.10413779550738553

Median of monthly transactions: 0.44774595613455564

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment