mirror of
https://github.com/Rucknium/misc-research.git
synced 2024-11-16 15:58:03 +00:00
First commit of Pre-Fork-BCH-BTC-Spending
This commit is contained in:
parent
f4bc291723
commit
e2998b266a
5 changed files with 458 additions and 0 deletions
105
Pre-fork-BCH-BTC-Spending/aggregate-spent-status-data.R
Normal file
105
Pre-fork-BCH-BTC-Spending/aggregate-spent-status-data.R
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
library(data.table)
|
||||||
|
library(RSQLite)
|
||||||
|
library(DBI)
|
||||||
|
library(scales)
|
||||||
|
# NOTE: Also need lubridate package installed, but not loading it due to
|
||||||
|
# it masking functions
|
||||||
|
|
||||||
|
bch.data.dir <- ""
|
||||||
|
btc.data.dir <- ""
|
||||||
|
# Input data directory here, with trailing "/"
|
||||||
|
|
||||||
|
|
||||||
|
con.bch <- DBI::dbConnect(RSQLite::SQLite(), paste0(bch.data.dir, "tx-graph-node-indices.db"))
|
||||||
|
con.btc <- DBI::dbConnect(RSQLite::SQLite(), paste0(btc.data.dir, "tx-graph-node-indices.db"))
|
||||||
|
|
||||||
|
pre.fork.edgelist <- DBI::dbGetQuery(con.bch,
|
||||||
|
"SELECT origin_index, destination_index FROM edgelist_intermediate_2 WHERE block_height <= 478558")
|
||||||
|
# 478558 is last block height that BCH and BTC share a block
|
||||||
|
|
||||||
|
pre.fork.utxo.set <- setdiff(pre.fork.edgelist$destination_index, pre.fork.edgelist$origin_index)
|
||||||
|
|
||||||
|
DBI::dbWriteTable(con.bch, "pre_fork_utxo_set",
|
||||||
|
data.frame(destination_index = pre.fork.utxo.set, stringsAsFactors = FALSE))
|
||||||
|
|
||||||
|
pre.fork.utxo.set.value <- DBI::dbGetQuery(con.bch,
|
||||||
|
'SELECT destination_index, value FROM edgelist_intermediate_2 WHERE destination_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
|
||||||
|
setDT(pre.fork.utxo.set.value)
|
||||||
|
pre.fork.bitcoin.supply <- 50 * length(0:209999) + 25 * length(210000:419999) + 12.5 * length(420000:478558)
|
||||||
|
pre.fork.utxo.set.value[, sum(value)] / pre.fork.bitcoin.supply
|
||||||
|
# [1] 0.99984
|
||||||
|
pre.fork.bitcoin.supply - pre.fork.utxo.set.value[, sum(value)]
|
||||||
|
# [1] 2637.559
|
||||||
|
|
||||||
|
pre.fork.utxo.set.value <- pre.fork.utxo.set.value[ ! destination_index %in% c(1740174960, 1740175469), ]
|
||||||
|
# Removes the transactions that are coinbases of blocks 91722, 91812, 91842, 91880
|
||||||
|
# Since they are duplicated transaction hashes. See:
|
||||||
|
# https://bitcoin.stackexchange.com/questions/40444/what-happens-when-two-txids-collide
|
||||||
|
# https://github.com/bitcoin/bitcoin/commit/ab91bf39b7c11e9c86bb2043c24f0f377f1cf514
|
||||||
|
|
||||||
|
excluded.duplicate.tx.hashes.output.count <- 4
|
||||||
|
excluded.duplicate.tx.hashes.value <- 50 * 4
|
||||||
|
|
||||||
|
|
||||||
|
spent.status <- DBI::dbGetQuery(con.bch,
|
||||||
|
'SELECT origin_index, block_height FROM edgelist_intermediate_2 WHERE origin_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
|
||||||
|
colnames(spent.status) <- c("destination_index", "bch.spent.block_height")
|
||||||
|
setDT(spent.status)
|
||||||
|
|
||||||
|
|
||||||
|
spent.status <- merge(pre.fork.utxo.set.value, spent.status, all.x = TRUE)
|
||||||
|
# rm(pre.fork.utxo.set.value)
|
||||||
|
|
||||||
|
# aggregate(spent.status$value, by = list(! is.na(spent.status$bch.spent.block_height)), FUN = sum)
|
||||||
|
# Group.1 x
|
||||||
|
# 1 FALSE 5699742
|
||||||
|
# 2 TRUE 10779508
|
||||||
|
# table(spent.status[value > 0, ! is.na(bch.spent.block_height)])
|
||||||
|
# FALSE TRUE
|
||||||
|
# 29154762 21307064
|
||||||
|
|
||||||
|
|
||||||
|
bch.block.times <- readRDS(paste0(bch.data.dir, "block_times.rds"))
|
||||||
|
|
||||||
|
bch.block.times[, block_time := as.POSIXct(block_time, origin = "1970-01-01", tz = "GMT")]
|
||||||
|
colnames(bch.block.times) <- c("bch.spent.block_height", "block_time")
|
||||||
|
|
||||||
|
spent.status <- merge(spent.status, bch.block.times, all = TRUE, by = "bch.spent.block_height")
|
||||||
|
# Note that due to all = TRUE this will get all blocks,
|
||||||
|
# even if there are no target spent outputs within the block
|
||||||
|
|
||||||
|
spent.status.by.block <- spent.status[,
|
||||||
|
.(value = sum(value, na.rm= TRUE), n.outputs = length(destination_index[ (! is.na(value)) & value > 0])),
|
||||||
|
by = .(bch.spent.block_height, block_time)]
|
||||||
|
|
||||||
|
spent.status.by.block[, block_time.date := lubridate::date(block_time)]
|
||||||
|
|
||||||
|
spent.status.by.date <- spent.status.by.block[,
|
||||||
|
.(value = sum(value, na.rm= TRUE), n.outputs = sum(n.outputs, na.rm= TRUE)),
|
||||||
|
by = .(block_time.date)]
|
||||||
|
|
||||||
|
unspent <- spent.status.by.date[is.na(block_time.date), value]
|
||||||
|
cumsum.na.rm <- function(x) {x[is.na(x)] <- 0; cumsum(x)}
|
||||||
|
spent.status.by.date[, value.cumsum := cumsum.na.rm(value) - unspent]
|
||||||
|
|
||||||
|
spent.status.by.date[, perc.value.cumsum := 100 * value.cumsum / sum(value, na.rm = TRUE)]
|
||||||
|
spent.status.by.date[, unspent.perc.value.cumsum := 100 - perc.value.cumsum]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
btc.spent.status <- DBI::dbGetQuery(con.btc,
|
||||||
|
'SELECT origin_index, block_height FROM edgelist_intermediate_2 WHERE origin_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
|
||||||
|
colnames(btc.spent.status) <- c("destination_index, btc.spent.block_height")
|
||||||
|
setDT(btc.spent.status)
|
||||||
|
|
||||||
|
spent.status <- merge(spent.status, btc.spent.status, all.x = TRUE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
99
Pre-fork-BCH-BTC-Spending/construct-edgelist.R
Normal file
99
Pre-fork-BCH-BTC-Spending/construct-edgelist.R
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# install.packages("data.table")
|
||||||
|
# install.packages("RSQLite")
|
||||||
|
# install.packages("DBI")
|
||||||
|
|
||||||
|
library(data.table)
|
||||||
|
library(RSQLite)
|
||||||
|
library(DBI)
|
||||||
|
|
||||||
|
data.dir <- ""
|
||||||
|
# Input data directory here, with trailing "/"
|
||||||
|
|
||||||
|
source("https://gist.githubusercontent.com/jeffwong/5925000/raw/bf02ed0dd2963169a91664be02fb18e45c4d1e20/sqlitewritetable.R")
|
||||||
|
# From https://gist.github.com/jeffwong/5925000
|
||||||
|
# Modifies RSQLite's sqliteWriteTable function so as to reject duplicates
|
||||||
|
|
||||||
|
con <- DBI::dbConnect(RSQLite::SQLite(), paste0(data.dir, "tx-graph-node-indices.db"))
|
||||||
|
|
||||||
|
DBI::dbExecute(con, "CREATE TABLE nodes (
|
||||||
|
node TEXT,
|
||||||
|
node_index INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
unique(node)
|
||||||
|
)")
|
||||||
|
|
||||||
|
|
||||||
|
DBI::dbWriteTable(con, "edgelist",
|
||||||
|
data.frame(origin = character(0), destination = character(0), value = numeric(0),
|
||||||
|
block_height = integer(0), stringsAsFactors = FALSE))
|
||||||
|
|
||||||
|
tx.graph.files <- list.files(paste0(data.dir, "tx_graphs/"))
|
||||||
|
tx.graph.files <- tx.graph.files[grepl("^tx_graph.+rds$", tx.graph.files)]
|
||||||
|
|
||||||
|
|
||||||
|
tx.graph.indexed <- vector("list", length(tx.graph.files))
|
||||||
|
names(tx.graph.indexed) <- tx.graph.files
|
||||||
|
|
||||||
|
for (file.iter in tx.graph.files) {
|
||||||
|
|
||||||
|
tx.graph.chunk <- readRDS(paste0(data.dir, "tx_graphs/", file.iter))
|
||||||
|
|
||||||
|
tx.graph.chunk <-
|
||||||
|
rbind(
|
||||||
|
data.table(origin = paste0(tx.graph.chunk$incoming$origin.txid, "-",
|
||||||
|
formatC(tx.graph.chunk$incoming$origin.position, width = 4, format = "f", flag = "0", digits = 0)),
|
||||||
|
destination = tx.graph.chunk$incoming$txid,
|
||||||
|
value = NA_real_,
|
||||||
|
block_height = as.integer(tx.graph.chunk$incoming$block_height), stringsAsFactors = FALSE),
|
||||||
|
data.table(origin = tx.graph.chunk$outgoing$txid,
|
||||||
|
destination = paste0(tx.graph.chunk$outgoing$txid, "-",
|
||||||
|
formatC(tx.graph.chunk$outgoing$position, width = 4, format = "f", flag = "0", digits = 0)),
|
||||||
|
value = tx.graph.chunk$outgoing$value,
|
||||||
|
block_height = as.integer(tx.graph.chunk$outgoing$block_height), stringsAsFactors = FALSE)
|
||||||
|
)
|
||||||
|
|
||||||
|
DBI::dbWriteTable(con, "edgelist",
|
||||||
|
tx.graph.chunk, append = TRUE)
|
||||||
|
|
||||||
|
new.nodes <- unique(c(tx.graph.chunk$origin, tx.graph.chunk$destination))
|
||||||
|
|
||||||
|
nodes.to.insert <- data.frame(node = new.nodes, node_index = NA, stringsAsFactors = FALSE)
|
||||||
|
|
||||||
|
mysqliteWriteTable(con, "nodes",
|
||||||
|
nodes.to.insert, append = TRUE, row.names = FALSE, ignore = TRUE)
|
||||||
|
|
||||||
|
cat(file.iter, base::date(), "\n")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DBI::dbWriteTable(con, "edgelist_intermediate_1",
|
||||||
|
data.frame(origin = character(0), destination = character(0),
|
||||||
|
value = numeric(0), block_height = integer(0),
|
||||||
|
node_index = integer(0), stringsAsFactors = FALSE), overwrite = TRUE)
|
||||||
|
|
||||||
|
base::date()
|
||||||
|
DBI::dbExecute(con, "INSERT INTO edgelist_intermediate_1 SELECT
|
||||||
|
origin, destination, value, block_height, node_index FROM
|
||||||
|
edgelist JOIN nodes ON edgelist.origin = nodes.node")
|
||||||
|
base::date()
|
||||||
|
|
||||||
|
|
||||||
|
DBI::dbExecute(con,
|
||||||
|
"ALTER TABLE edgelist_intermediate_1 RENAME COLUMN node_index TO origin_index")
|
||||||
|
|
||||||
|
|
||||||
|
DBI::dbWriteTable(con, "edgelist_intermediate_2",
|
||||||
|
data.frame(origin = character(0), destination = character(0),
|
||||||
|
origin_index = integer(0), node_index = integer(0),
|
||||||
|
value = numeric(0), block_height = integer(0), stringsAsFactors = FALSE))
|
||||||
|
|
||||||
|
base::date()
|
||||||
|
DBI::dbExecute(con, "INSERT INTO edgelist_intermediate_2 SELECT
|
||||||
|
origin, destination, origin_index, node_index, value, block_height FROM
|
||||||
|
edgelist_intermediate_1 JOIN nodes ON edgelist_intermediate_1.destination = nodes.node")
|
||||||
|
base::date()
|
||||||
|
|
||||||
|
DBI::dbExecute(con,
|
||||||
|
"ALTER TABLE edgelist_intermediate_2 RENAME COLUMN node_index TO destination_index")
|
||||||
|
|
||||||
|
|
61
Pre-fork-BCH-BTC-Spending/create-graphs.R
Normal file
61
Pre-fork-BCH-BTC-Spending/create-graphs.R
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
library(data.table)
|
||||||
|
library(ggplot2)
|
||||||
|
library(scales)
|
||||||
|
# NOTE: Also need lubridate package installed, but not loading it due to
|
||||||
|
# it masking functions
|
||||||
|
|
||||||
|
|
||||||
|
spent.status.by.date <- spent.status.by.date[ ! is.na(block_time.date), ]
|
||||||
|
|
||||||
|
spent.status.by.date.reshaped <- melt(spent.status.by.date, id.vars = c("block_time.date"),
|
||||||
|
measure.vars = c("perc.value.cumsum", "unspent.perc.value.cumsum"))
|
||||||
|
|
||||||
|
|
||||||
|
c_trans <- function(a, b, breaks = b$breaks, format = b$format) {
|
||||||
|
a <- scales::as.trans(a)
|
||||||
|
b <- scales::as.trans(b)
|
||||||
|
|
||||||
|
name <- paste(a$name, b$name, sep = "-")
|
||||||
|
|
||||||
|
trans <- function(x) a$trans(b$trans(x))
|
||||||
|
inv <- function(x) b$inverse(a$inverse(x))
|
||||||
|
|
||||||
|
trans_new(name, trans, inverse = inv, breaks = breaks, format=format)
|
||||||
|
}
|
||||||
|
# Thanks to https://stackoverflow.com/questions/59542697/reverse-datetime-posixct-data-axis-in-ggplot-version-3
|
||||||
|
|
||||||
|
rev_date <- c_trans("reverse", "time")
|
||||||
|
|
||||||
|
spent.status.by.date.reshaped[, block_time.date := as.POSIXct(block_time.date)]
|
||||||
|
spent.status.by.date.reshaped[, variable :=
|
||||||
|
factor(variable, levels = c("perc.value.cumsum", "unspent.perc.value.cumsum"))]
|
||||||
|
|
||||||
|
# #FF9900 BTC color
|
||||||
|
# https://gist.github.com/paladini/ef383fce1b782d919898
|
||||||
|
# #0AC18E BCH color
|
||||||
|
# https://bitcoincashstandards.org/
|
||||||
|
|
||||||
|
png(paste0(bch.data.dir, "preliminary-pre-fork-BCH-spent-status.png"), width = 800, height = 2000)
|
||||||
|
|
||||||
|
print(
|
||||||
|
ggplot(spent.status.by.date.reshaped, aes(x = block_time.date, y=value, fill=variable)) +
|
||||||
|
geom_area(alpha = 0.6 , size = 0, colour = "black") + coord_flip() +
|
||||||
|
scale_x_continuous(trans = rev_date) +
|
||||||
|
scale_fill_manual(values = c("#0AC18E", "purple"), breaks = rev(c("perc.value.cumsum", "unspent.perc.value.cumsum"))) +
|
||||||
|
ylab("\t\t\t\t\t\tPercent github.com/Rucknium") +
|
||||||
|
theme(legend.position = "top", axis.title.y = element_blank(),
|
||||||
|
axis.text = element_text(size = 20), axis.title.x = element_text(size = 20),
|
||||||
|
legend.title = element_blank(), legend.text = element_text(size = 15)) +
|
||||||
|
geom_vline(xintercept = as.POSIXct("2017-11-12"), linetype = 3) +
|
||||||
|
geom_text(aes(x = as.POSIXct("2017-11-12"), label = "Max BCH/BTC Exchange Rate", y = 25), colour = "white", size = 7.5) +
|
||||||
|
geom_vline(xintercept = as.POSIXct("2017-12-20"), linetype = 3) +
|
||||||
|
geom_text(aes(x = as.POSIXct("2017-12-20"), label = "Max BCH/USD Exchange Rate", y = 25), colour = "white", size = 7.5) +
|
||||||
|
geom_vline(xintercept = as.POSIXct("2018-11-15"), linetype = 3) +
|
||||||
|
geom_text(aes(x = as.POSIXct("2018-11-15"), label = "BSV Hard Fork", y = 12), colour = "white", size = 7.5) +
|
||||||
|
geom_vline(xintercept = as.POSIXct("2020-11-15"), linetype = 3) +
|
||||||
|
geom_text(aes(x = as.POSIXct("2020-11-15"), label = "BCHABC Hard Fork", y = 15), colour = "white", size = 7.5)
|
||||||
|
)
|
||||||
|
# https://en.wikipedia.org/wiki/List_of_bitcoin_forks
|
||||||
|
dev.off()
|
||||||
|
|
||||||
|
|
156
Pre-fork-BCH-BTC-Spending/extract-tx-graphs.R
Normal file
156
Pre-fork-BCH-BTC-Spending/extract-tx-graphs.R
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
# install.packages("rbch")
|
||||||
|
# install.packages("data.table")
|
||||||
|
# install.packages("future.apply")
|
||||||
|
|
||||||
|
library(rbch)
|
||||||
|
library(data.table)
|
||||||
|
library(future.apply)
|
||||||
|
|
||||||
|
# 478,558 is last block that BCH and BTC have in common
|
||||||
|
|
||||||
|
|
||||||
|
bitcoin.conf.file <- ""
|
||||||
|
# Input filepath for your bitcoin.conf file
|
||||||
|
|
||||||
|
data.dir <- ""
|
||||||
|
# Input data directory here, with trailing "/"
|
||||||
|
|
||||||
|
dir.create(paste0(data.dir, "tx_graphs"))
|
||||||
|
|
||||||
|
bch.config <- rbch::conrpc(bitcoin.conf.file)
|
||||||
|
|
||||||
|
# current.block.height <- rbch::getblockchaininfo(bch.config)@result$blocks
|
||||||
|
# current.block.height <- 733867
|
||||||
|
# 733867 is for BCH
|
||||||
|
current.block.height <- 729896
|
||||||
|
# 729896 is for BTC
|
||||||
|
|
||||||
|
cut.seq <- seq(20, current.block.height, by = 20)
|
||||||
|
cut.seq <- c(-1, cut.seq, current.block.height)
|
||||||
|
|
||||||
|
heights.to.process <- 0:current.block.height
|
||||||
|
heights.to.process <- split(heights.to.process,
|
||||||
|
cut(heights.to.process, cut.seq))
|
||||||
|
|
||||||
|
future::plan(future::multiprocess())
|
||||||
|
|
||||||
|
|
||||||
|
for (height.set in heights.to.process) {
|
||||||
|
|
||||||
|
extracted.txs <- future.apply::future_lapply(height.set, function(iter.block.height) {
|
||||||
|
|
||||||
|
if (iter.block.height %% 1000 == 0) {
|
||||||
|
cat(iter.block.height, base::date(), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
block.hash <- rbch::getblockhash(bch.config, iter.block.height)
|
||||||
|
block.data <- rbch::getblock(bch.config, blockhash = block.hash@result, verbosity = "l2")
|
||||||
|
# Argument verbose = 2 gives full transaction data
|
||||||
|
# For some reason it doesn't give the fee:
|
||||||
|
# https://docs.bitcoincashnode.org/doc/json-rpc/getrawtransaction.html
|
||||||
|
|
||||||
|
raw.txs.ls <- block.data@result$tx
|
||||||
|
|
||||||
|
coinbase.tx <- raw.txs.ls[[1]]
|
||||||
|
|
||||||
|
value <- vector("numeric", length(coinbase.tx$vout) )
|
||||||
|
|
||||||
|
for (j in seq_along(coinbase.tx$vout)) {
|
||||||
|
value[j] <- coinbase.tx$vout[[j]]$value
|
||||||
|
}
|
||||||
|
|
||||||
|
outgoing.coinbase <- data.table(txid = coinbase.tx$txid,
|
||||||
|
position = seq_along(coinbase.tx$vout), value = value, block_height = iter.block.height, stringsAsFactors = FALSE)
|
||||||
|
|
||||||
|
coinbase.return.value <- list(incoming =
|
||||||
|
data.table(txid = character(0), origin.txid = character(0),
|
||||||
|
origin.position = numeric(0), block_height = integer(0), stringsAsFactors = FALSE),
|
||||||
|
outgoing = outgoing.coinbase)
|
||||||
|
|
||||||
|
if ( length(raw.txs.ls) < 2) {
|
||||||
|
return(list(coinbase.return.value))
|
||||||
|
}
|
||||||
|
# No incoming txs for coinbase-only
|
||||||
|
|
||||||
|
# Results of this lapply below are returned
|
||||||
|
|
||||||
|
return.value <- lapply(2:length(raw.txs.ls), function(iter) {
|
||||||
|
# Start at 2 since the first tx is the coinbase tx
|
||||||
|
|
||||||
|
latest.tx <- raw.txs.ls[[iter]]
|
||||||
|
|
||||||
|
# addresses <- vector("character", length(latest.tx$vout) )
|
||||||
|
value <- vector("numeric", length(latest.tx$vout) )
|
||||||
|
|
||||||
|
for (j in seq_along(latest.tx$vout)) {
|
||||||
|
extracted.address <- latest.tx$vout[[j]]$scriptPubKey$addresses
|
||||||
|
if (length(extracted.address) > 1) {
|
||||||
|
extracted.address <- list(paste0(sort(unlist(extracted.address)), collapse = "|"))
|
||||||
|
# sort() so that the address order is always the same
|
||||||
|
}
|
||||||
|
|
||||||
|
stopifnot(length(extracted.address[[1]]) <= 1)
|
||||||
|
if (length(extracted.address) == 0) {next}
|
||||||
|
|
||||||
|
# addresses[j] <- extracted.address[[1]]
|
||||||
|
value[j] <- latest.tx$vout[[j]]$value
|
||||||
|
}
|
||||||
|
|
||||||
|
outgoing <- data.table(txid = latest.tx$txid,
|
||||||
|
# address = addresses,
|
||||||
|
position = seq_along(latest.tx$vout), value = value, block_height = iter.block.height, stringsAsFactors = FALSE)
|
||||||
|
|
||||||
|
origin.txid <- vector("character", length(latest.tx$vin) )
|
||||||
|
origin.position <- vector("numeric", length(latest.tx$vin) )
|
||||||
|
|
||||||
|
for (j in seq_along(latest.tx$vin)) {
|
||||||
|
extracted.address <- latest.tx$vin[[j]]$txid
|
||||||
|
stopifnot(length(extracted.address) <= 1)
|
||||||
|
stopifnot(length(extracted.address[[1]]) <= 1)
|
||||||
|
if (length(extracted.address) == 0) {next}
|
||||||
|
|
||||||
|
origin.txid[j] <- latest.tx$vin[[j]]$txid
|
||||||
|
origin.position[j] <- latest.tx$vin[[j]]$vout + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
incoming <- data.table(txid = latest.tx$txid, origin.txid = origin.txid,
|
||||||
|
origin.position = origin.position, block_height = iter.block.height, stringsAsFactors = FALSE)
|
||||||
|
|
||||||
|
list(incoming = incoming, outgoing = outgoing)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return.value[[length(return.value) + 1]] <- coinbase.return.value
|
||||||
|
# Note that this means that coinbase txs are now "last in the block"
|
||||||
|
|
||||||
|
return.value
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
print(object.size(extracted.txs), units = "Mb")
|
||||||
|
|
||||||
|
extracted.txs <- unlist(extracted.txs, recursive = FALSE)
|
||||||
|
|
||||||
|
incoming <- data.table::rbindlist(lapply(extracted.txs, function(x) {
|
||||||
|
x[[1]]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
outgoing <- data.table::rbindlist(lapply(extracted.txs, function(x) {
|
||||||
|
x[[2]]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
rm(extracted.txs)
|
||||||
|
|
||||||
|
saveRDS(list(incoming = incoming, outgoing = outgoing),
|
||||||
|
file = paste0(data.dir, "tx_graphs/tx_graph_height_",
|
||||||
|
paste0(formatC(range(height.set), width = 6, flag = "0"), collapse = "_to_"), ".rds"),
|
||||||
|
compress = FALSE)
|
||||||
|
|
||||||
|
rm(incoming)
|
||||||
|
rm(outgoing)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
37
Pre-fork-BCH-BTC-Spending/get-block-times.R
Normal file
37
Pre-fork-BCH-BTC-Spending/get-block-times.R
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
library(data.table)
|
||||||
|
|
||||||
|
bitcoin.conf.file <- ""
|
||||||
|
# Input filepath for your bitcoin.conf file
|
||||||
|
|
||||||
|
data.dir <- ""
|
||||||
|
# Input data directory here, with trailing "/"
|
||||||
|
|
||||||
|
bch.config <- rbch::conrpc(bitcoin.conf.file)
|
||||||
|
|
||||||
|
initial.fork.height <- 478558 - 1
|
||||||
|
|
||||||
|
# current.block.height <- 733867
|
||||||
|
# 733867 is for BCH
|
||||||
|
current.block.height <- 729896
|
||||||
|
# 729896 is for BTC
|
||||||
|
|
||||||
|
block.times <- vector(length(initial.fork.height:current.block.height), mode ="list")
|
||||||
|
|
||||||
|
for (iter.block.height in initial.fork.height:current.block.height) {
|
||||||
|
|
||||||
|
if (iter.block.height %% 1000 == 0) {
|
||||||
|
cat(iter.block.height, base::date(), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
block.hash <- rbch::getblockhash(bch.config, iter.block.height)
|
||||||
|
block.data <- rbch::getblock(bch.config, blockhash = block.hash@result, verbosity = "l1")
|
||||||
|
block.times[[iter.block.height - initial.fork.height + 1]] <-
|
||||||
|
data.frame(block_height = iter.block.height, block_time = block.data@result$time)
|
||||||
|
}
|
||||||
|
|
||||||
|
block.times <- data.table::rbindlist(block.times)
|
||||||
|
|
||||||
|
saveRDS(block.times, file = paste0(data.dir, "block_times.rds"))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue