Skip to content

Instantly share code, notes, and snippets.

@onyb
Last active May 11, 2020 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onyb/5b23b35a336556dfc2c9a389f419c7fa to your computer and use it in GitHub Desktop.
Save onyb/5b23b35a336556dfc2c9a389f419c7fa to your computer and use it in GitHub Desktop.
Bitcoin Hardening

Bitcoin Hardening

Enjoy the Bitcoin Halving event from the comfort of your terminal.

Requirements

  • Go 1.13
  • Bitcoin full-node
    • If you don't have one, signup on Blockdaemon to get a free shared Bitcoin full-node.

How to run

$ git clone git@gist.github.com:5b23b35a336556dfc2c9a389f419c7fa.git hardening
$ cd hardening
$ RPC_HOST="..." RPC_USER="..." RPC_PASSWORD="..." go run main.go
Using a Blockdaemon shared node
$ git clone git@gist.github.com:5b23b35a336556dfc2c9a389f419c7fa.git hardening
$ cd hardening
$ RPC_HOST="btccore-main.bdnodes.net?auth=<...>" RPC_USER="blockdaemon" RPC_PASSWORD="..." RPC_ENABLE_TLS="true" go run main.go
module hardening
go 1.13
require (
github.com/btcsuite/btcd v0.20.1-beta.0.20200414114020-8b54b0b96418
github.com/btcsuite/btcutil v1.0.2
github.com/mattn/go-colorable v0.1.6 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 // indirect
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f // indirect
)
package main
import (
"fmt"
"os"
"time"
"github.com/btcsuite/btcd/rpcclient"
log "github.com/sirupsen/logrus"
prefixed "github.com/x-cray/logrus-prefixed-formatter"
)
const PRE_HALVING_SUBSIDY = 1250000000
// GetWire initializes a an RPC client to communicate with bitcoind
func GetWire(host string, user string, pass string, tls bool) *rpcclient.Client {
connCfg := &rpcclient.ConnConfig{
Host: host,
User: user,
Pass: pass,
HTTPPostMode: true,
DisableTLS: !tls,
}
// The notification parameter is nil since notifications are not
// supported in HTTP POST mode.
client, err := rpcclient.New(connCfg, nil)
if client == nil || err != nil {
log.WithFields(log.Fields{
"host": host,
"user": user,
"TLS": tls,
}).Fatal("Failed to initialize RPC client.")
}
info, err := client.GetBlockChainInfo()
if info == nil || err != nil {
log.WithFields(log.Fields{
"host": host,
"user": user,
"TLS": tls,
}).Fatal("Failed to connect to RPC server.")
}
log.WithFields(log.Fields{
"chain": info.Chain,
}).Info("RPC connection established")
return client
}
func main() {
log.SetFormatter(&prefixed.TextFormatter{
TimestampFormat: "2006/01/02 - 15:04:05",
FullTimestamp: true,
QuoteEmptyFields: true,
SpacePadding: 30,
})
wire := GetWire(
os.Getenv("RPC_HOST"),
os.Getenv("RPC_USER"),
os.Getenv("RPC_PASSWORD"),
os.Getenv("RPC_ENABLE_TLS") == "true",
)
defer wire.Shutdown()
for true {
info, err := wire.GetBlockChainInfo()
if err != nil {
log.Fatal("Could not execute RPC: getblockchaininfo")
}
stats, err := wire.GetBlockStats(info.BestBlockHash, &[]string{"subsidy"})
if err != nil {
log.Fatal("Could not execute RPC: getblockstats")
}
remainingBlocks := 630000 - info.Blocks
eta := remainingBlocks * 10
log.WithFields(log.Fields{
"height": info.Blocks,
"subsidy": stats.Subsidy,
"remainingBlocks": remainingBlocks,
"ETA": fmt.Sprintf("%dh%dm", eta/60, eta%60),
}).Info("Get current block")
if stats.Subsidy == PRE_HALVING_SUBSIDY>>1 {
log.WithFields(log.Fields{
"subsidy": stats.Subsidy,
"blocks": info.Blocks,
"bestblockhash": info.BestBlockHash,
}).Info("Halving detected!")
break
}
time.Sleep(5 * time.Second)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment