mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-06 19:26:41 +01:00
added address view, started implementation of dark theme
This commit is contained in:
@@ -30,3 +30,5 @@ other
|
||||
- mantain connection with wallet using websockets
|
||||
|
||||
- num address evolution throught time
|
||||
|
||||
- Error in Tx model. exploreBlockchain.go line 174
|
||||
|
||||
@@ -102,6 +102,8 @@ Webapp will run on 127.0.0.1:8080
|
||||
### Some screenshots
|
||||
Some screenshots can be old, and can contain errors.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
@@ -171,6 +171,7 @@ func explore(client *rpcclient.Client, blockHash string) {
|
||||
|
||||
}
|
||||
}
|
||||
//ERROR! need to make array with all Vin and array with Vout, with addresses and amount values
|
||||
saveTx(newTx)
|
||||
} else {
|
||||
originAddresses = append(originAddresses, "origin")
|
||||
|
||||
Binary file not shown.
@@ -3,9 +3,11 @@ package main
|
||||
import "time"
|
||||
|
||||
type AddressModel struct {
|
||||
Hash string `json:"hash"`
|
||||
Amount float64 `json:"amount"`
|
||||
InBittrex bool `json:"inbittrex"`
|
||||
Hash string `json:"hash"`
|
||||
Amount float64 `json:"amount"`
|
||||
InBittrex bool `json:"inbittrex"`
|
||||
Txs []TxModel `json:"txs"`
|
||||
Blocks []BlockModel `json:"blocks"`
|
||||
}
|
||||
type DateModel struct {
|
||||
Hour int `json:"hour"`
|
||||
@@ -26,7 +28,7 @@ type TxModel struct {
|
||||
BlockHash string `json:"blockhash"`
|
||||
BlockHeight string `json:"blockheight"`
|
||||
Time int64 `json:"time"`
|
||||
DateT time.Time `json:"datef"` //date formated
|
||||
DateT time.Time `json:"datet"` //date formated
|
||||
Date DateModel
|
||||
}
|
||||
type BlockModel struct {
|
||||
@@ -40,7 +42,7 @@ type BlockModel struct {
|
||||
PreviousHash string `json:"previoushash"`
|
||||
NextHash string `json:"nexthash"`
|
||||
Time int64 `json:"time"`
|
||||
DateT time.Time `json:"datef"` //date formated
|
||||
DateT time.Time `json:"datet"` //date formated
|
||||
Date DateModel
|
||||
}
|
||||
|
||||
|
||||
BIN
screenshots/goBlockchainDataAnalysis00_new.png
Normal file
BIN
screenshots/goBlockchainDataAnalysis00_new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
@@ -52,6 +52,12 @@ var routes = Routes{
|
||||
"/address/network/{address}",
|
||||
AddressNetwork,
|
||||
},
|
||||
Route{
|
||||
"Address",
|
||||
"GET",
|
||||
"/address/{hash}",
|
||||
Address,
|
||||
},
|
||||
Route{
|
||||
"AddressSankey",
|
||||
"GET",
|
||||
@@ -179,6 +185,36 @@ func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, string(jNetwork))
|
||||
}
|
||||
}
|
||||
func Address(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
|
||||
vars := mux.Vars(r)
|
||||
hash := vars["hash"]
|
||||
if hash == "undefined" {
|
||||
fmt.Fprintln(w, "not valid hash")
|
||||
} else {
|
||||
address := AddressModel{}
|
||||
err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
|
||||
|
||||
txs := []TxModel{}
|
||||
err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"from": hash}, bson.M{"to": hash}}}).All(&txs)
|
||||
address.Txs = txs
|
||||
|
||||
for _, tx := range address.Txs {
|
||||
blocks := []BlockModel{}
|
||||
err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
|
||||
for _, block := range blocks {
|
||||
address.Blocks = append(address.Blocks, block)
|
||||
}
|
||||
}
|
||||
|
||||
//convert []resp struct to json
|
||||
jsonResp, err := json.Marshal(address)
|
||||
check(err)
|
||||
|
||||
fmt.Fprintln(w, string(jsonResp))
|
||||
}
|
||||
}
|
||||
func AddressSankey(w http.ResponseWriter, r *http.Request) {
|
||||
ipFilter(w, r)
|
||||
vars := mux.Vars(r)
|
||||
@@ -376,8 +412,10 @@ func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) {
|
||||
for _, d := range hourCount {
|
||||
dayData = append(dayData, d.Count)
|
||||
}
|
||||
resp.Series = append(resp.Series, txs[0].Date.Day)
|
||||
resp.Data = append(resp.Data, dayData)
|
||||
if len(txs) > 0 {
|
||||
resp.Series = append(resp.Series, txs[0].Date.Day)
|
||||
resp.Data = append(resp.Data, dayData)
|
||||
}
|
||||
}
|
||||
hourLabels := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"}
|
||||
resp.Labels = hourLabels
|
||||
|
||||
@@ -13,6 +13,7 @@ angular.module('webApp', [
|
||||
'app.main',
|
||||
'app.network',
|
||||
'app.addressNetwork',
|
||||
'app.address',
|
||||
'app.sankey',
|
||||
'app.dateAnalysis'
|
||||
]).
|
||||
|
||||
29
web/css/bootstrapMaterialDarkOverwrite.css
vendored
Normal file
29
web/css/bootstrapMaterialDarkOverwrite.css
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
/* bootstrap overwrite dark */
|
||||
|
||||
body {
|
||||
background: #424242!important;
|
||||
}
|
||||
.panel-heading {
|
||||
border-radius: 0px!important;
|
||||
}
|
||||
.panel-title a {
|
||||
background: rgba(0,0,0,0)!important;
|
||||
text-decoration: none;
|
||||
}
|
||||
.panel-body {
|
||||
background: #212121;
|
||||
color: #ffffff;
|
||||
}
|
||||
.list-group-item {
|
||||
background: rgba(0,0,0,0)!important;
|
||||
}
|
||||
.list-group-item:hover {
|
||||
background: rgba(255, 255, 255, 0.2)!important;
|
||||
}
|
||||
.list-group-item p, a{
|
||||
color: #ffffff!important;
|
||||
}
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: rgba(245, 245, 245, 0.2)!important;
|
||||
}
|
||||
@@ -463,6 +463,11 @@
|
||||
color: #ffffff!important;
|
||||
}
|
||||
|
||||
.c_black{
|
||||
background: #000000!important;
|
||||
color: #ffffff!important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* blue grey */
|
||||
|
||||
@@ -30,15 +30,23 @@
|
||||
|
||||
|
||||
/* sidebar */
|
||||
.o_sidebar a{
|
||||
|
||||
.o_sidebar a {
|
||||
color: white;
|
||||
padding: 10px;
|
||||
}
|
||||
.o_sidebar a:hover{
|
||||
|
||||
.o_sidebar a:hover {
|
||||
background: #9E9E9E!important;
|
||||
color: white;
|
||||
}
|
||||
.o_sidebarIcon{
|
||||
|
||||
.o_sidebarIcon {
|
||||
font-size: 180%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.o_textRoundProgress {
|
||||
margin-left: 30%;
|
||||
margin-top: -15%;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<link rel="stylesheet" href="bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
|
||||
|
||||
<link href="css/bootstrapMaterialDarkOverwrite.css" rel="stylesheet">
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
<link href="css/colors.css" rel="stylesheet">
|
||||
|
||||
@@ -77,6 +78,7 @@
|
||||
<script src="views/main/main.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>
|
||||
|
||||
56
web/views/address/address.html
Normal file
56
web/views/address/address.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">{{address.hash}}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{address.amount}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Tx where address appears</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>BlockHeight</th>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Amount</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</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>{{tx.amount}}</td>
|
||||
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
21
web/views/address/address.js
Normal file
21
web/views/address/address.js
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('app.address', ['ngRoute'])
|
||||
|
||||
.config(['$routeProvider', function($routeProvider) {
|
||||
$routeProvider.when('/address/:hash', {
|
||||
templateUrl: 'views/address/address.html',
|
||||
controller: 'AddressCtrl'
|
||||
});
|
||||
}])
|
||||
|
||||
.controller('AddressCtrl', function($scope, $http, $routeParams) {
|
||||
$scope.address = {};
|
||||
$http.get(urlapi + 'address/' + $routeParams.hash)
|
||||
.then(function(data, status, headers, config) {
|
||||
console.log(data);
|
||||
$scope.address = data.data;
|
||||
}, function(data, status, headers, config) {
|
||||
console.log('data error');
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last 7 Days Tx/Day</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last 24 hours Tx/Hour</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@@ -18,9 +18,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last 7 Days Tx/Hour</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="panel-body">
|
||||
<h4>{{stats.realblockcount}}/{{stats.blockcount}} Blocks with content</h4>
|
||||
<div class="progress" style="margin:0;">
|
||||
<div class="progress-bar c_blueGrey500" ng-style="blockProgress"></div>
|
||||
<div class="progress-bar c_deepPurpleG300to500" ng-style="blockProgress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="panel-body">
|
||||
<h4>{{stats.txcount}} Txs</h4>
|
||||
<div class="progress" style="margin:0;">
|
||||
<div class="progress-bar c_blueGrey500" ng-style="txProgress"></div>
|
||||
<div class="progress-bar c_deepPurpleG300to500" ng-style="txProgress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="panel-body">
|
||||
<h4>{{stats.addrcount}} Addr</h4>
|
||||
<div class="progress" style="margin:0;">
|
||||
<div class="progress-bar c_blueGrey500" ng-style="txProgress"></div>
|
||||
<div class="progress-bar c_deepPurpleG300to500" ng-style="txProgress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -35,7 +35,7 @@
|
||||
<round-progress
|
||||
max="max"
|
||||
current="current"
|
||||
color="#45CCCE"
|
||||
color="#9575CD"
|
||||
bgcolor="#eaeaea"
|
||||
radius="100"
|
||||
stroke="20"
|
||||
@@ -46,6 +46,7 @@
|
||||
duration="800"
|
||||
animation="easeInOutQuart"
|
||||
animation-delay="0">{{current}}/{{max}}</round-progress>
|
||||
<div class="o_textRoundProgress">{{ current }}/{{ max }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,11 +55,11 @@
|
||||
<div class="panel-body">
|
||||
<round-progress
|
||||
max="max"
|
||||
current="current"
|
||||
color="#607D8B"
|
||||
current="20"
|
||||
color="#673AB7"
|
||||
bgcolor="#eaeaea"
|
||||
radius="100"
|
||||
stroke="20"
|
||||
stroke="25"
|
||||
semi="true"
|
||||
rounded="false"
|
||||
clockwise="true"
|
||||
@@ -66,6 +67,7 @@
|
||||
duration="800"
|
||||
animation="easeInOutQuart"
|
||||
animation-delay="0">{{current}}/{{max}}</round-progress>
|
||||
<div class="o_textRoundProgress">25%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,9 +75,9 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last 24 hours Tx/Hour
|
||||
<a ng-href="#!/dateAnalysis" class="pull-right c_blueGrey300">View more</a></h3>
|
||||
<a ng-href="#!/dateAnalysis" class="pull-right c_deepPurpleG300to500">View more</a></h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="line" class="chart chart-line" chart-data="last24hour.data" chart-labels="last24hour.labels">
|
||||
@@ -84,7 +86,7 @@
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Tx/Day Last 7 Days</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@@ -95,9 +97,9 @@
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last 7 days Tx/Hour
|
||||
<a ng-href="#!/dateAnalysis" class="pull-right c_blueGrey300">View more</a></h3>
|
||||
<a ng-href="#!/dateAnalysis" class="pull-right c_deepPurpleG300to500">View more</a></h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="line" class="chart chart-line" chart-data="last7dayhour.data" chart-labels="last7dayhour.labels" chart-series="last7dayhour.series">
|
||||
@@ -109,13 +111,13 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<h3 class="panel-title">Last addresses used</h3>
|
||||
</div>
|
||||
<div class="panel-body" style="max-height: 250px;overflow-y: scroll;">
|
||||
<div class="list-group-item" ng-repeat="address in addresses">
|
||||
<div class="row-content">
|
||||
<p class="list-group-item-text">{{address.hash}}</p>
|
||||
<a ng-href="#!/address/{{address.hash}}" class="list-group-item-text">{{address.hash}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,11 +126,11 @@
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="panel">
|
||||
<div class="panel-heading c_blueGrey300">
|
||||
<div class="panel-heading c_deepPurpleG300to500">
|
||||
<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-striped table-hover">
|
||||
<table class="table table-hover">
|
||||
<!--<colgroup>
|
||||
<col class="col-md-2">
|
||||
<col class="col-md-2">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="c_grey600" style="height:100%;position:fixed;"><!-- margin-top:-20px; -->
|
||||
<div class="c_grey900" style="height:100%;position:fixed;"><!-- margin-top:-20px; -->
|
||||
<ul class="nav o_sidebar">
|
||||
<li class="c_grey800">
|
||||
<li class="c_deepPurpleG300to500">
|
||||
<a href="#!/main">
|
||||
goBlockchainDataAnalysis
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user