arnaucube
arnaucube/goBlockchainDataAnalysisPublic Self-hosted repository
goBlockchainDataAnalysis/exploreBlockchain.go
exploreBlockchain.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5
  6	"github.com/btcsuite/btcd/chaincfg/chainhash"
  7	"github.com/btcsuite/btcrpcclient"
  8)
  9
 10func explore(client *btcrpcclient.Client, blockHash string) {
 11	var realBlocks int
 12
 13	var nOrigin NodeModel
 14	nOrigin.Id = "origin"
 15	nOrigin.Label = "origin"
 16	nOrigin.Title = "origin"
 17	nOrigin.Group = "origin"
 18	nOrigin.Value = 1
 19	nOrigin.Shape = "dot"
 20	saveNode(nodeCollection, nOrigin)
 21
 22	for blockHash != "" {
 23		//generate hash from string
 24		bh, err := chainhash.NewHashFromStr(blockHash)
 25		check(err)
 26		block, err := client.GetBlockVerbose(bh)
 27		check(err)
 28
 29		var newBlock BlockModel
 30		newBlock.Hash = block.Hash
 31		newBlock.Height = block.Height
 32		newBlock.Confirmations = block.Confirmations
 33
 34		//get Fee value
 35		th, err := chainhash.NewHashFromStr(block.Tx[0])
 36		check(err)
 37		tx, err := client.GetRawTransactionVerbose(th)
 38		check(err)
 39		var totalFee float64
 40		for _, Vo := range tx.Vout {
 41			totalFee = totalFee + Vo.Value
 42		}
 43		newBlock.Fee = totalFee
 44
 45		//for each Tx, get the Tx value
 46		var totalAmount float64
 47		/*inside each block, there are []Tx
 48		inside each Tx, if is the Tx[0], is the Fees
 49		in the Tx[n] where n>0, each Tx is independent,
 50		and inside each Tx there are []Vout.
 51		Usually Vout[0] is the real Tx value
 52		and the Vout[1] is the rest of the amount in the original wallet.
 53		Each Tx moves all the wallet amount, and the realTx amount is sent to the destination
 54		and the rest of the wallet amount, is send to another owned wallet
 55		*/
 56		//if len(block.Tx) < 10 {
 57		for k, txHash := range block.Tx {
 58			//first Tx is the Fee
 59			//after first Tx is the Sent Amount
 60			if k > 0 {
 61				th, err := chainhash.NewHashFromStr(txHash)
 62				check(err)
 63				tx, err := client.GetRawTransactionVerbose(th)
 64				check(err)
 65				var originAddress string
 66				for _, Vi := range tx.Vin {
 67					th, err := chainhash.NewHashFromStr(Vi.Txid)
 68					check(err)
 69					txVi, err := client.GetRawTransactionVerbose(th)
 70					check(err)
 71					if len(txVi.Vout[0].ScriptPubKey.Addresses) > 0 {
 72						originAddress = txVi.Vout[0].ScriptPubKey.Addresses[0]
 73					} else {
 74						originAddress = "origin"
 75					}
 76
 77				}
 78				for _, Vo := range tx.Vout {
 79					totalAmount = totalAmount + Vo.Value
 80
 81					var blockTx TxModel
 82					blockTx.Txid = tx.Txid
 83					blockTx.Amount = Vo.Value
 84					blockTx.From = originAddress
 85					blockTx.To = Vo.ScriptPubKey.Addresses[0]
 86					newBlock.Tx = append(newBlock.Tx, blockTx)
 87				}
 88			}
 89		}
 90
 91		if totalAmount > 0 {
 92			newBlock.Amount = totalAmount
 93			saveBlock(blockCollection, newBlock)
 94			fmt.Print("Height: ")
 95			fmt.Println(newBlock.Height)
 96			fmt.Print("Amount: ")
 97			fmt.Println(newBlock.Amount)
 98			fmt.Print("Fee: ")
 99			fmt.Println(newBlock.Fee)
100			fmt.Println("-----")
101			realBlocks++
102		}
103		//}
104
105		//set the next block
106		blockHash = block.NextHash
107
108		//analyze block creator
109		for _, t := range newBlock.Tx {
110			var n1 NodeModel
111			var n2 NodeModel
112			n1.Id = t.From
113			n1.Label = t.From
114			n1.Title = t.From
115			n1.Group = newBlock.Hash
116			n1.Value = 1
117			n1.Shape = "dot"
118			n2.Id = t.To
119			n2.Label = t.To
120			n2.Title = t.To
121			n2.Group = newBlock.Hash
122			n2.Value = 1
123			n2.Shape = "dot"
124
125			var e EdgeModel
126			e.From = t.From
127			e.To = t.To
128			e.Label = t.Amount
129			e.Txid = t.Txid
130			e.Arrows = "to"
131
132			saveNode(nodeCollection, n1)
133			saveNode(nodeCollection, n2)
134			saveEdge(edgeCollection, e)
135		}
136
137	}
138	fmt.Print("realBlocks (blocks with Fee and Amount values): ")
139	fmt.Println(realBlocks)
140	fmt.Println("reached the end of blockchain")
141}