package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/rpcclient"
|
|
)
|
|
|
|
func explore(client *rpcclient.Client, blockHash string) {
|
|
var realBlocks int
|
|
/*var nOrigin NodeModel
|
|
nOrigin.Id = "origin"
|
|
nOrigin.Label = "origin"
|
|
nOrigin.Title = "origin"
|
|
nOrigin.Group = "origin"
|
|
nOrigin.Value = 1
|
|
nOrigin.Shape = "dot"
|
|
saveNode(nodeCollection, nOrigin)*/
|
|
|
|
for blockHash != "" {
|
|
//generate hash from string
|
|
bh, err := chainhash.NewHashFromStr(blockHash)
|
|
check(err)
|
|
block, err := client.GetBlockVerbose(bh)
|
|
check(err)
|
|
if block.Height > config.StartFromBlock {
|
|
var newBlock BlockModel
|
|
newBlock.Hash = block.Hash
|
|
newBlock.Confirmations = block.Confirmations
|
|
newBlock.Size = block.Size
|
|
newBlock.Height = block.Height
|
|
//newBlock.Amount = block.Amount
|
|
//newBlock.Fee = block.Fee
|
|
newBlock.PreviousHash = block.PreviousHash
|
|
newBlock.NextHash = block.NextHash
|
|
newBlock.Time = block.Time
|
|
newBlock.DateT = unixTimeToTime(block.Time)
|
|
newBlock.Date.Year, newBlock.Date.Month, newBlock.Date.Day, newBlock.Date.Hour = decomposeDate(block.Time)
|
|
|
|
//stats blocks
|
|
stats := getStats()
|
|
stats.BlockCount++
|
|
if len(block.Tx) > 1 {
|
|
stats.RealBlockCount++
|
|
}
|
|
updateStats(stats)
|
|
|
|
for k, txHash := range block.Tx {
|
|
if k > 0 {
|
|
realBlocks++
|
|
|
|
//stats txs
|
|
stats := getStats()
|
|
stats.TxCount++
|
|
updateStats(stats)
|
|
|
|
fmt.Print("Block Height: ")
|
|
fmt.Print(block.Height)
|
|
fmt.Print(", num of Tx: ")
|
|
fmt.Print(k)
|
|
fmt.Print("/")
|
|
fmt.Println(len(block.Tx) - 1)
|
|
|
|
th, err := chainhash.NewHashFromStr(txHash)
|
|
check(err)
|
|
blockTx, err := client.GetRawTransactionVerbose(th)
|
|
check(err)
|
|
|
|
//save Tx Node
|
|
var nodeTx NodeModel
|
|
nodeTx.Id = txHash
|
|
nodeTx.Label = txHash
|
|
nodeTx.Title = txHash
|
|
nodeTx.Group = strconv.FormatInt(block.Height, 10)
|
|
nodeTx.Value = 1
|
|
nodeTx.Shape = "square"
|
|
nodeTx.Type = "tx"
|
|
saveNode(nodeCollection, nodeTx)
|
|
|
|
//Tx save
|
|
var newTx TxModel
|
|
newTx.Hex = blockTx.Hex
|
|
newTx.Txid = blockTx.Txid
|
|
newTx.Hash = blockTx.Hash
|
|
newTx.BlockHash = block.Hash
|
|
newTx.BlockHeight = strconv.FormatInt(block.Height, 10)
|
|
newTx.Time = blockTx.Time
|
|
newTx.DateT = unixTimeToTime(block.Time)
|
|
newTx.Date.Year, newTx.Date.Month, newTx.Date.Day, newTx.Date.Hour = decomposeDate(block.Time)
|
|
|
|
var originAddresses []string
|
|
var outputAddresses []string
|
|
var outputAmount []float64
|
|
for _, Vo := range blockTx.Vout {
|
|
for _, outputAddr := range Vo.ScriptPubKey.Addresses {
|
|
outputAddresses = append(outputAddresses, outputAddr)
|
|
outputAmount = append(outputAmount, Vo.Value)
|
|
var n2 NodeModel
|
|
n2.Id = outputAddr
|
|
n2.Label = outputAddr
|
|
n2.Title = outputAddr
|
|
n2.Group = strconv.FormatInt(block.Height, 10)
|
|
n2.Value = 1
|
|
n2.Shape = "dot"
|
|
n2.Type = "address"
|
|
saveNode(nodeCollection, n2)
|
|
|
|
//Address
|
|
var addr AddressModel
|
|
addr.Hash = outputAddr
|
|
addr.InBittrex = false
|
|
saveAddress(addr)
|
|
|
|
var newVout Vout
|
|
newVout.Value = Vo.Value
|
|
newVout.Address = outputAddr
|
|
newTx.Vout = append(newTx.Vout, newVout)
|
|
}
|
|
}
|
|
for _, Vi := range blockTx.Vin {
|
|
th, err := chainhash.NewHashFromStr(Vi.Txid)
|
|
check(err)
|
|
txVi, err := client.GetRawTransactionVerbose(th)
|
|
check(err)
|
|
|
|
//if len(txVi.Vout[Vi.Vout].ScriptPubKey.Addresses) > 0 {
|
|
//add tx to newBlock
|
|
newBlock.Tx = append(newBlock.Tx, blockTx.Txid)
|
|
|
|
//Tx save
|
|
for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses {
|
|
originAddresses = append(originAddresses, originAddr)
|
|
|
|
var newVin Vin
|
|
newVin.Txid = blockTx.Txid
|
|
newVin.Amount = txVi.Vout[Vi.Vout].Value
|
|
newVin.Address = originAddr
|
|
newTx.Vin = append(newTx.Vin, newVin)
|
|
|
|
var n1 NodeModel
|
|
n1.Id = originAddr
|
|
n1.Label = originAddr
|
|
n1.Title = originAddr
|
|
n1.Group = strconv.FormatInt(block.Height, 10)
|
|
n1.Value = 1
|
|
n1.Shape = "dot"
|
|
n1.Type = "address"
|
|
saveNode(nodeCollection, n1)
|
|
|
|
//Address
|
|
var addr AddressModel
|
|
addr.Hash = originAddr
|
|
addr.InBittrex = false
|
|
saveAddress(addr)
|
|
|
|
for k, outputAddr := range outputAddresses {
|
|
var eIn EdgeModel
|
|
eIn.From = originAddr
|
|
eIn.To = txHash
|
|
eIn.Label = txVi.Vout[Vi.Vout].Value
|
|
eIn.Txid = blockTx.Txid
|
|
eIn.Arrows = "to"
|
|
eIn.BlockHeight = block.Height
|
|
saveEdge(edgeCollection, eIn)
|
|
|
|
var eOut EdgeModel
|
|
eOut.From = txHash
|
|
eOut.To = outputAddr
|
|
eOut.Label = outputAmount[k]
|
|
eOut.Txid = blockTx.Txid
|
|
eOut.Arrows = "to"
|
|
eOut.BlockHeight = block.Height
|
|
saveEdge(edgeCollection, eOut)
|
|
|
|
//date analysis
|
|
//dateAnalysis(e, tx.Time)
|
|
//hour analysis
|
|
hourAnalysis(eIn, blockTx.Time)
|
|
|
|
//newTx.To = outputAddr
|
|
|
|
}
|
|
}
|
|
/*} else {
|
|
originAddresses = append(originAddresses, "origin")
|
|
}*/
|
|
|
|
}
|
|
saveTx(newTx)
|
|
fmt.Print("originAddresses: ")
|
|
fmt.Println(len(originAddresses))
|
|
fmt.Print("outputAddresses: ")
|
|
fmt.Println(len(outputAddresses))
|
|
}
|
|
}
|
|
saveBlock(newBlock)
|
|
}
|
|
//set the next block
|
|
blockHash = block.NextHash
|
|
}
|
|
|
|
fmt.Print("realBlocks added (blocks with Fee and Amount values): ")
|
|
fmt.Println(realBlocks)
|
|
fmt.Println("reached the end of blockchain")
|
|
}
|