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)
- 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.