mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
corrected tx model, added block view in frontend
This commit is contained in:
@@ -30,5 +30,3 @@ other
|
||||
- mantain connection with wallet using websockets
|
||||
|
||||
- num address evolution throught time
|
||||
|
||||
- Error in Tx model. exploreBlockchain.go line 174
|
||||
|
||||
@@ -79,6 +79,17 @@ func explore(client *rpcclient.Client, blockHash string) {
|
||||
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
|
||||
@@ -101,6 +112,11 @@ func explore(client *rpcclient.Client, blockHash string) {
|
||||
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 {
|
||||
@@ -108,24 +124,20 @@ func explore(client *rpcclient.Client, blockHash string) {
|
||||
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
|
||||
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)
|
||||
for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses {
|
||||
originAddresses = append(originAddresses, originAddr)
|
||||
|
||||
newTx.From = 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
|
||||
@@ -167,11 +179,10 @@ func explore(client *rpcclient.Client, blockHash string) {
|
||||
//hour analysis
|
||||
hourAnalysis(eIn, blockTx.Time)
|
||||
|
||||
newTx.To = outputAddr
|
||||
//newTx.To = outputAddr
|
||||
|
||||
}
|
||||
}
|
||||
//ERROR! need to make array with all Vin and array with Vout, with addresses and amount values
|
||||
saveTx(newTx)
|
||||
} else {
|
||||
originAddresses = append(originAddresses, "origin")
|
||||
|
||||
@@ -18,12 +18,24 @@ type DateModel struct {
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`*/
|
||||
}
|
||||
type Vin struct {
|
||||
Txid string `json:"txid"`
|
||||
Vout uint32 `json:"vout"`
|
||||
Amount float64 `json:"amount"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
type Vout struct {
|
||||
Value float64 `json:"value"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
type TxModel struct {
|
||||
Hex string `json:"hex"`
|
||||
Txid string `json:"txid"`
|
||||
Hash string `json:"hash"`
|
||||
From string `json:"from"` //hash of address
|
||||
To string `json:"to"` //hash of address
|
||||
Hex string `json:"hex"`
|
||||
Txid string `json:"txid"`
|
||||
Hash string `json:"hash"`
|
||||
/*From string `json:"from"` //hash of address
|
||||
To string `json:"to"` //hash of address*/
|
||||
Vin []Vin `json:"vin"`
|
||||
Vout []Vout `json:"vout"`
|
||||
Amount float64 `json:"amount"`
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`
|
||||
@@ -39,6 +51,7 @@ type BlockModel struct {
|
||||
//Amount float64 `json:"amount"`
|
||||
//Fee float64 `json:"fee"`
|
||||
Tx []string `json:"txid"` //txid of the TxModel
|
||||
Txs []TxModel `json:"txs"`
|
||||
PreviousHash string `json:"previoushash"`
|
||||
NextHash string `json:"nexthash"`
|
||||
Time int64 `json:"time"`
|
||||
|
||||
@@ -47,10 +47,10 @@ var routes = Routes{
|
||||
GetLastTx,
|
||||
},
|
||||
Route{
|
||||
"AddressNetwork",
|
||||
"Block",
|
||||
"GET",
|
||||
"/address/network/{address}",
|
||||
AddressNetwork,
|
||||
"/block/{height}",
|
||||
Block,
|
||||
},
|
||||
Route{
|
||||
"Address",
|
||||
@@ -58,6 +58,12 @@ var routes = Routes{
|
||||
"/address/{hash}",
|
||||
Address,
|
||||
},
|
||||
Route{
|
||||
"AddressNetwork",
|
||||
"GET",
|
||||
"/address/network/{address}",
|
||||
AddressNetwork,
|
||||
},
|
||||
Route{
|
||||
"AddressSankey",
|
||||
"GET",
|
||||
@@ -167,22 +173,36 @@ func GetLastTx(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
fmt.Fprintln(w, string(jsonData))
|
||||
}
|
||||
func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
func Block(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
address := vars["address"]
|
||||
if address == "undefined" {
|
||||
fmt.Fprintln(w, "not valid address")
|
||||
var heightString string
|
||||
heightString = vars["height"]
|
||||
height, err := strconv.ParseInt(heightString, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintln(w, "not valid height")
|
||||
} else {
|
||||
network := addressTree(address)
|
||||
network.Nodes[0].Shape = "triangle"
|
||||
block := BlockModel{}
|
||||
err := blockCollection.Find(bson.M{"height": height}).One(&block)
|
||||
|
||||
txs := []TxModel{}
|
||||
err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
|
||||
block.Txs = txs
|
||||
|
||||
/*for _, tx := range address.Txs {
|
||||
blocks := []BlockModel{}
|
||||
err = blockCollection.Find(bson.M{"blockheight": tx.BlockHash}).All(&blocks)
|
||||
for _, block := range blocks {
|
||||
address.Blocks = append(address.Blocks, block)
|
||||
}
|
||||
}*/
|
||||
|
||||
//convert []resp struct to json
|
||||
jNetwork, err := json.Marshal(network)
|
||||
jsonResp, err := json.Marshal(block)
|
||||
check(err)
|
||||
|
||||
fmt.Fprintln(w, string(jNetwork))
|
||||
fmt.Fprintln(w, string(jsonResp))
|
||||
}
|
||||
}
|
||||
func Address(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -215,6 +235,24 @@ func Address(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, string(jsonResp))
|
||||
}
|
||||
}
|
||||
func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
address := vars["address"]
|
||||
if address == "undefined" {
|
||||
fmt.Fprintln(w, "not valid address")
|
||||
} else {
|
||||
network := addressTree(address)
|
||||
network.Nodes[0].Shape = "triangle"
|
||||
|
||||
//convert []resp struct to json
|
||||
jNetwork, err := json.Marshal(network)
|
||||
check(err)
|
||||
|
||||
fmt.Fprintln(w, string(jNetwork))
|
||||
}
|
||||
}
|
||||
func AddressSankey(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
|
||||
@@ -11,9 +11,10 @@ angular.module('webApp', [
|
||||
'angular-svg-round-progressbar',
|
||||
'app.navbar',
|
||||
'app.main',
|
||||
'app.block',
|
||||
'app.address',
|
||||
'app.network',
|
||||
'app.addressNetwork',
|
||||
'app.address',
|
||||
'app.sankey',
|
||||
'app.dateAnalysis'
|
||||
]).
|
||||
|
||||
8
web/css/bootstrapMaterialDarkOverwrite.css
vendored
8
web/css/bootstrapMaterialDarkOverwrite.css
vendored
@@ -21,9 +21,15 @@ body {
|
||||
.list-group-item:hover {
|
||||
background: rgba(255, 255, 255, 0.2)!important;
|
||||
}
|
||||
.list-group-item p, a{
|
||||
.list-group-item p {
|
||||
color: #ffffff!important;
|
||||
}
|
||||
.list-group-item a {
|
||||
color: #512DA8!important;
|
||||
}
|
||||
.list-group-item-text {
|
||||
color: #9575CD!important;
|
||||
}
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: rgba(245, 245, 245, 0.2)!important;
|
||||
}
|
||||
|
||||
@@ -76,9 +76,10 @@
|
||||
<script src="app.js"></script>
|
||||
<script src="views/navbar.js"></script>
|
||||
<script src="views/main/main.js"></script>
|
||||
<script src="views/address/address.js"></script>
|
||||
<script src="views/block/block.js"></script>
|
||||
<script src="views/network/network.js"></script>
|
||||
<script src="views/addressNetwork/addressNetwork.js"></script>
|
||||
<script src="views/address/address.js"></script>
|
||||
<script src="views/sankey/sankey.js"></script>
|
||||
<script src="views/dateAnalysis/dateAnalysis.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -8,23 +8,29 @@
|
||||
{{address.amount}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Blocks where address appears</h3>
|
||||
</div>
|
||||
<div class="panel-body" ng-repeat="block in address.blocks">
|
||||
Block Height: {{block.height}}
|
||||
<br>
|
||||
Hash: {{block.Hash}}
|
||||
<br>
|
||||
{{block.datet}}
|
||||
<br>
|
||||
{{block.Size}}
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<a ng-href="#!/block/{{block.height}}" class="list-group-item-text" ng-repeat="block in address.blocks">
|
||||
Block Height: {{block.height}}
|
||||
<br> Hash: {{block.hash}}
|
||||
<br> {{block.datet}}
|
||||
<br> Size: {{block.size}} bytes
|
||||
<br>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Tx where address appears</h3>
|
||||
@@ -42,9 +48,21 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tx in address.txs">
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.blockheight}}</td>
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.from}}</td>
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.to}}</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/block/{{tx.blockheight}}" class="list-group-item-text">
|
||||
{{tx.blockheight}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/address/{{tx.from}}" class="list-group-item-text">
|
||||
{{tx.from}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/address/{{tx.to}}" class="list-group-item-text">
|
||||
{{tx.to}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{tx.amount}}</td>
|
||||
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
||||
</tr>
|
||||
|
||||
73
web/views/block/block.html
Normal file
73
web/views/block/block.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Block Height {{block.height}}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
Block Hash:
|
||||
<p style="font-size: 9px;">
|
||||
{{block.hash}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Block evolution</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Tx in block</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="col-sm-12">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Txid</th>
|
||||
<th>Input</th>
|
||||
<th>Output</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tx in block.txs">
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/address/{{tx.from}}" class="list-group-item-text">
|
||||
{{tx.txid}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<table><tbody><tr ng-repeat="vin in tx.vin"><td>
|
||||
<a ng-href="#!/address/{{vin.address}}" class="list-group-item-text">
|
||||
{{vin.address}}
|
||||
</a>
|
||||
:{{vin.amount}}
|
||||
</td></tr></tbody></table>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<table><tbody><tr ng-repeat="vout in tx.vout"><td>
|
||||
<a ng-href="#!/address/{{vout.address}}" class="list-group-item-text">
|
||||
{{vout.address}}
|
||||
</a>
|
||||
:{{vout.value}}
|
||||
</td></tr></tbody></table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
21
web/views/block/block.js
Normal file
21
web/views/block/block.js
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.block', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/block/:height', {
|
||||
templateUrl: 'views/block/block.html',
|
||||
controller: 'BlockCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('BlockCtrl', function($scope, $http, $routeParams) {
|
||||
$scope.block = {};
|
||||
$http.get(urlapi + 'block/' + $routeParams.height)
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log(data);
|
||||
$scope.block = data.data;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
});
|
||||
@@ -130,34 +130,46 @@
|
||||
<h3 class="panel-title">Last Tx with amount</h3>
|
||||
</div>
|
||||
<div class="panel-body" style="max-height: 250px;overflow-y: scroll;">
|
||||
<table class="table table-hover">
|
||||
<!--<colgroup>
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
</colgroup>-->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>BlockHeight</th>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Amount</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tx in txs">
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.blockheight}}</td>
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.from}}</td>
|
||||
<td style="max-width:20px; overflow:hidden;">{{tx.to}}</td>
|
||||
<td>{{tx.amount}}</td>
|
||||
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>BlockHeight</th>
|
||||
<th>Txid</th>
|
||||
<th>Input</th>
|
||||
<th>Output</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tx in txs">
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/block/{{tx.blockheight}}" class="list-group-item-text">
|
||||
{{tx.blockheight}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<a ng-href="#!/address/{{tx.from}}" class="list-group-item-text">
|
||||
{{tx.txid}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<table><tbody><tr ng-repeat="vin in tx.vin"><td>
|
||||
<a ng-href="#!/address/{{vin.address}}" class="list-group-item-text">
|
||||
{{vin.address}}
|
||||
</a>
|
||||
:{{vin.amount}}
|
||||
</td></tr></tbody></table>
|
||||
</td>
|
||||
<td style="max-width:20px; overflow:hidden;">
|
||||
<table><tbody><tr ng-repeat="vout in tx.vout"><td>
|
||||
<a ng-href="#!/address/{{vout.address}}" class="list-group-item-text">
|
||||
{{vout.address}}
|
||||
</a>
|
||||
:{{vout.value}}
|
||||
</td></tr></tbody></table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user