diff --git a/.gitignore b/.gitignore index c085c5e..7322542 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,6 @@ /*.conf -/*.json +config.json *.mp4 logs diff --git a/DevelopmentNotes.md b/DevelopmentNotes.md index ae5a691..dbab99b 100644 --- a/DevelopmentNotes.md +++ b/DevelopmentNotes.md @@ -33,3 +33,7 @@ other BlockHeight string `json:"blockheight"` } ``` + +- mantain connection with wallet using websockets + +- add 24h to hour analysis, to show also hours with 0 transactions diff --git a/configEXAMPLE.json b/configEXAMPLE.json new file mode 100644 index 0000000..184113b --- /dev/null +++ b/configEXAMPLE.json @@ -0,0 +1,22 @@ +{ + "user": "faircoinrpc", + "pass": "password", + "host": "127.0.0.1", + "port": "3021", + "genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046", + "genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7", + "startFromBlock": 0, + "server": { + "serverIP": "127.0.0.1", + "serverPort": "3014", + "webServerPort": "8080", + "allowedIPs": [ + "127.0.0.1" + ], + "blockedIPs": [] + }, + "mongodb": { + "ip": "127.0.0.1", + "database": "goBlockchainDataAnalysis" + } +} diff --git a/dateAnalysis.go b/dateAnalysis.go index f137441..2a0da60 100644 --- a/dateAnalysis.go +++ b/dateAnalysis.go @@ -9,6 +9,21 @@ import ( "gopkg.in/mgo.v2/bson" ) +func decomposeDate(blockTime int64) (int, int, int, int) { + /*i, err := strconv.ParseInt(blockTime, 10, 64) + if err != nil { + panic(err) + }*/ + i := blockTime + year := time.Unix(i, 0).Year() + month := time.Unix(i, 0).Month() + day := time.Unix(i, 0).Day() + hour := time.Unix(i, 0).Hour() + return year, int(month), day, hour +} +func unixTimeToTime(blockTime int64) time.Time { + return time.Unix(blockTime, 0) +} func timeToDate(blockTime int64) string { stringTime := strconv.FormatInt(blockTime, 10) i, err := strconv.ParseInt(stringTime, 10, 64) diff --git a/exploreBlockchain.go b/exploreBlockchain.go index d86f20b..fd109d9 100644 --- a/exploreBlockchain.go +++ b/exploreBlockchain.go @@ -37,6 +37,8 @@ func explore(client *btcrpcclient.Client, blockHash string) { 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) for k, txHash := range block.Tx { if k > 0 { @@ -53,7 +55,7 @@ func explore(client *btcrpcclient.Client, blockHash string) { blockTx, err := client.GetRawTransactionVerbose(th) check(err) - //save Tx + //save Tx Node var nodeTx NodeModel nodeTx.Id = txHash nodeTx.Label = txHash @@ -105,6 +107,8 @@ func explore(client *btcrpcclient.Client, blockHash string) { 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) diff --git a/goBlockchainDataAnalysis b/goBlockchainDataAnalysis index 6f5fc08..9042092 100755 Binary files a/goBlockchainDataAnalysis and b/goBlockchainDataAnalysis differ diff --git a/instructions.md b/instructions.md deleted file mode 100644 index d804d9b..0000000 --- a/instructions.md +++ /dev/null @@ -1,32 +0,0 @@ -# Instructions - -#### Install FairCoin Wallet and configure -now, need to configure wallet: -.FairCoin/ - FairCoin.conf - -``` -rpcuser=usernamerpc -rpcpassword=password -rpcport=3021 -rpcworkqueue=2000 -server=1 -rpcbind=127.0.0.1 -rpcallowip=127.0.0.1 -``` - -execute wallet: -./faircoind -txindex -reindex-chainstate - -### Configure - -```json -{ - "user": "usernamerpc", - "pass": "password", - "host": "127.0.0.1", - "port": "3021", - "genesisTx": "7c27ade2c28e67ed3077f8f77b8ea6d36d4f5eba04c099be3c9faa9a4a04c046", - "genesisBlock": "beed44fa5e96150d95d56ebd5d2625781825a9407a5215dd7eda723373a0a1d7" -} -``` diff --git a/mongoModels.go b/mongoModels.go index d13107d..4ae567e 100644 --- a/mongoModels.go +++ b/mongoModels.go @@ -1,29 +1,32 @@ package main +import "time" + type AddressModel struct { Hash string `json:"hash"` Amount float64 `json:"amount"` InBittrex bool `json:"inbittrex"` } type DateModel struct { - Hour string `json:"hour"` - Day string `json:"day"` - Month string `json:"month"` - Amount float64 `json:"amount"` + Hour int `json:"hour"` + Day int `json:"day"` + Month int `json:"month"` + Year int `json:"year"` + /*Amount float64 `json:"amount"` BlockHash string `json:"blockhash"` - BlockHeight string `json:"blockheight"` + BlockHeight string `json:"blockheight"`*/ } 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 - Amount float64 `json:"amount"` - BlockHash string `json:"blockhash"` - BlockHeight string `json:"blockheight"` - Time int64 `json:"time"` - DateF string `json:"datef"` //date formated + 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 + Amount float64 `json:"amount"` + BlockHash string `json:"blockhash"` + BlockHeight string `json:"blockheight"` + Time int64 `json:"time"` + DateT time.Time `json:"datef"` //date formated Date DateModel } type BlockModel struct { @@ -33,11 +36,11 @@ type BlockModel struct { Height int64 `json:"height"` //Amount float64 `json:"amount"` //Fee float64 `json:"fee"` - Tx []string `json:"txid"` //txid of the TxModel - PreviousHash string `json:"previoushash"` - NextHash string `json:"nexthash"` - Time int64 `json:"time"` - DateF string `json:"datef"` //date formated + Tx []string `json:"txid"` //txid of the TxModel + PreviousHash string `json:"previoushash"` + NextHash string `json:"nexthash"` + Time int64 `json:"time"` + DateT time.Time `json:"datef"` //date formated Date DateModel } diff --git a/serverRoutes.go b/serverRoutes.go index 45ba319..1a04631 100644 --- a/serverRoutes.go +++ b/serverRoutes.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" "sort" + "strconv" + "time" "gopkg.in/mgo.v2/bson" @@ -57,10 +59,16 @@ var routes = Routes{ NetworkMap, }, Route{ - "GetHourAnalysis", + "GetTotalHourAnalysis", "Get", - "/houranalysis", - GetHourAnalysis, + "/totalhouranalysis", + GetTotalHourAnalysis, + }, + Route{ + "GetLast24HourAnalysis", + "Get", + "/last24hour", + GetLast24HourAnalysis, }, } @@ -199,57 +207,60 @@ func NetworkMap(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, string(jNetwork)) } -/* -func SelectItem(w http.ResponseWriter, r *http.Request) { +func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) { ipFilter(w, r) - vars := mux.Vars(r) - userid := vars["userid"] - itemid := vars["itemid"] - //find item - item, err := getItemById(itemid) - if err != nil { - fmt.Fprintln(w, "item "+itemid+" not found") - } - - //find user - user, err := getUserById(userid) - if err != nil { - fmt.Fprintln(w, "user "+userid+" not found") - } - //increase TActed in item - item.TActed = item.TActed + 1 + hourAnalysis := []HourCountModel{} + iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter() + err := iter.All(&hourAnalysis) - //save item - item, err = updateItem(item) - check(err) - fmt.Println(item) + //sort by hour + sort.Slice(hourAnalysis, func(i, j int) bool { + return hourAnalysis[i].Hour < hourAnalysis[j].Hour + }) - //add item to []Actions of user - user.Actions = append(user.Actions, itemid) + var resp HourAnalysisResp + for _, d := range hourAnalysis { + resp.Labels = append(resp.Labels, d.Hour) + resp.Data = append(resp.Data, d.Count) + } - //save user - user, err = updateUser(user) + //convert []resp struct to json + jsonResp, err := json.Marshal(resp) check(err) - fmt.Println(user) - - fmt.Fprintln(w, "user: "+userid+", selects item: "+itemid) + fmt.Fprintln(w, string(jsonResp)) } -*/ -func GetHourAnalysis(w http.ResponseWriter, r *http.Request) { + +func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) { ipFilter(w, r) - hourAnalysis := []HourCountModel{} - iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter() - err := iter.All(&hourAnalysis) + fromDate := time.Now().AddDate(0, 0, -1) + toDate := time.Now() + txs := []TxModel{} + err := txCollection.Find(bson.M{ + "datet": bson.M{ + "$gt": fromDate, + "$lt": toDate, + }, + }).Sort("-$natural").All(&txs) + check(err) + + hourFrequencies := make(map[int]int) + for _, tx := range txs { + hourFrequencies[tx.Date.Hour]++ + } + var hourCount []HourCountModel + for hour, frequency := range hourFrequencies { + hourCount = append(hourCount, HourCountModel{strconv.Itoa(hour), frequency}) + } //sort by hour - sort.Slice(hourAnalysis, func(i, j int) bool { - return hourAnalysis[i].Hour < hourAnalysis[j].Hour + sort.Slice(hourCount, func(i, j int) bool { + return hourCount[i].Hour < hourCount[j].Hour }) var resp HourAnalysisResp - for _, d := range hourAnalysis { + for _, d := range hourCount { resp.Labels = append(resp.Labels, d.Hour) resp.Data = append(resp.Data, d.Count) } diff --git a/web/img/favicon.png b/web/img/favicon.png new file mode 100644 index 0000000..0867d3d Binary files /dev/null and b/web/img/favicon.png differ diff --git a/web/index.html b/web/index.html index c2cf056..fa15f55 100644 --- a/web/index.html +++ b/web/index.html @@ -6,6 +6,8 @@ goBlockchainDataAnalysis + + diff --git a/web/views/dateAnalysis/dateAnalysis.html b/web/views/dateAnalysis/dateAnalysis.html index 4f1415c..9d7e0c4 100644 --- a/web/views/dateAnalysis/dateAnalysis.html +++ b/web/views/dateAnalysis/dateAnalysis.html @@ -1,10 +1,19 @@
-
+
-

Tx for each Hour

+

All time Tx/Hour

- + + +
+
+
+
+

Last 24 hours Tx/Hour

+
+
+
diff --git a/web/views/dateAnalysis/dateAnalysis.js b/web/views/dateAnalysis/dateAnalysis.js index d25f58c..36f1a87 100644 --- a/web/views/dateAnalysis/dateAnalysis.js +++ b/web/views/dateAnalysis/dateAnalysis.js @@ -10,18 +10,35 @@ angular.module('app.dateAnalysis', ['ngRoute', 'chart.js']) }]) .controller('DateAnalysisCtrl', function($scope, $http, $routeParams) { - $scope.data=[]; - $scope.labels=[]; + $scope.totalhour={ + data: [], + labels: [] + }; - $http.get(urlapi + 'houranalysis') + $http.get(urlapi + 'totalhouranalysis') .then(function(data, status, headers, config) { console.log('data success'); console.log(data); - $scope.data = data.data.data; - $scope.labels=data.data.labels; + $scope.totalhour.data = data.data.data; + $scope.totalhour.labels=data.data.labels; }, function(data, status, headers, config) { console.log('data error'); }); + //date analysis + $scope.last24hour= { + data:[], + labels: [] + }; + $http.get(urlapi + 'last24hour') + .then(function(data, status, headers, config) { + console.log('data success'); + console.log(data); + + $scope.last24hour.data = data.data.data; + $scope.last24hour.labels = data.data.labels; + }, function(data, status, headers, config) { + console.log('data error'); + }); }); diff --git a/web/views/main/main.html b/web/views/main/main.html index 951e38c..1f1c748 100644 --- a/web/views/main/main.html +++ b/web/views/main/main.html @@ -16,7 +16,7 @@
-

Tx/Hour

+

Last 24 hours Tx/Hour

diff --git a/web/views/main/main.js b/web/views/main/main.js index 04de367..c28ac46 100644 --- a/web/views/main/main.js +++ b/web/views/main/main.js @@ -37,7 +37,7 @@ angular.module('app.main', ['ngRoute']) //date analysis $scope.data = []; $scope.labels = []; - $http.get(urlapi + 'houranalysis') + $http.get(urlapi + 'last24hour') .then(function(data, status, headers, config) { console.log('data success'); console.log(data);