goBlockchainDataAnalysis/serverRoutes.go
serverRoutes.goRaw
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7 "sort"
8 "strconv"
9 "time"
10
11 "gopkg.in/mgo.v2/bson"
12
13 "github.com/gorilla/mux"
14)
15
16type Routes []Route
17
18var routes = Routes{
19 Route{
20 "Index",
21 "GET",
22 "/",
23 Index,
24 },
25 Route{
26 "Stats",
27 "Get",
28 "/stats",
29 Stats,
30 },
31 Route{
32 "AllAddresses",
33 "Get",
34 "/alladdresses",
35 AllAddresses,
36 },
37 Route{
38 "GetLastAddr",
39 "Get",
40 "/lastaddr",
41 GetLastAddr,
42 },
43 Route{
44 "GetLastTx",
45 "Get",
46 "/lasttx",
47 GetLastTx,
48 },
49 Route{
50 "Block",
51 "GET",
52 "/block/{height}",
53 Block,
54 },
55 Route{
56 "Tx",
57 "GET",
58 "/tx/{txid}",
59 Tx,
60 },
61 Route{
62 "Address",
63 "GET",
64 "/address/{hash}",
65 Address,
66 },
67 Route{
68 "AddressNetwork",
69 "GET",
70 "/address/network/{address}",
71 AddressNetwork,
72 },
73 Route{
74 "AddressSankey",
75 "GET",
76 "/address/sankey/{address}",
77 AddressSankey,
78 },
79 Route{
80 "NetworkMap",
81 "Get",
82 "/map",
83 NetworkMap,
84 },
85 Route{
86 "GetTotalHourAnalysis",
87 "Get",
88 "/totalhouranalysis",
89 GetTotalHourAnalysis,
90 },
91 Route{
92 "GetLast24HourAnalysis",
93 "Get",
94 "/last24hour",
95 GetLast24HourAnalysis,
96 },
97 Route{
98 "GetLast7DayAnalysis",
99 "Get",
100 "/last7day",
101 GetLast7DayAnalysis,
102 },
103 Route{
104 "GetLast7DayHourAnalysis",
105 "Get",
106 "/last7dayhour",
107 GetLast7DayHourAnalysis,
108 },
109 Route{
110 "GetAddressTimeChart",
111 "GET",
112 "/addresstimechart/{hash}",
113 GetAddressTimeChart,
114 },
115}
116
117//ROUTES
118
119func Index(w http.ResponseWriter, r *http.Request) {
120 fmt.Fprintln(w, "ask for recommendations in /r")
121 //http.FileServer(http.Dir("./web"))
122}
123
124/*
125func NewUser(w http.ResponseWriter, r *http.Request) {
126 ipFilter(w, r)
127 decoder := json.NewDecoder(r.Body)
128 var newUser UserModel
129 err := decoder.Decode(&newUser)
130 check(err)
131 defer r.Body.Close()
132
133 saveUser(userCollection, newUser)
134
135 fmt.Println(newUser)
136 fmt.Fprintln(w, "new user added: ", newUser.ID)
137}
138*/
139func Stats(w http.ResponseWriter, r *http.Request) {
140 ipFilter(w, r)
141
142 stats := getStats()
143
144 jsonResp, err := json.Marshal(stats)
145 check(err)
146
147 fmt.Fprintln(w, string(jsonResp))
148}
149func AllAddresses(w http.ResponseWriter, r *http.Request) {
150 ipFilter(w, r)
151
152 nodes := []NodeModel{}
153 iter := nodeCollection.Find(bson.M{"type": "address"}).Limit(10000).Iter()
154 err := iter.All(&nodes)
155
156 //convert []resp struct to json
157 jsonNodes, err := json.Marshal(nodes)
158 check(err)
159
160 fmt.Fprintln(w, string(jsonNodes))
161}
162func GetLastAddr(w http.ResponseWriter, r *http.Request) {
163 ipFilter(w, r)
164
165 addresses := []AddressModel{}
166 err := addressCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&addresses)
167 check(err)
168
169 //convert []resp struct to json
170 jsonResp, err := json.Marshal(addresses)
171 check(err)
172
173 fmt.Fprintln(w, string(jsonResp))
174}
175func GetLastTx(w http.ResponseWriter, r *http.Request) {
176 ipFilter(w, r)
177
178 txs := []TxModel{}
179 err := txCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&txs)
180 check(err)
181
182 //convert []resp struct to json
183 jsonData, err := json.Marshal(txs)
184 check(err)
185
186 fmt.Fprintln(w, string(jsonData))
187}
188func Block(w http.ResponseWriter, r *http.Request) {
189 ipFilter(w, r)
190
191 vars := mux.Vars(r)
192 var heightString string
193 heightString = vars["height"]
194 height, err := strconv.ParseInt(heightString, 10, 64)
195 if err != nil {
196 fmt.Fprintln(w, "not valid height")
197 } else {
198 block := BlockModel{}
199 err := blockCollection.Find(bson.M{"height": height}).One(&block)
200
201 txs := []TxModel{}
202 err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
203 block.Txs = txs
204
205 //convert []resp struct to json
206 jsonResp, err := json.Marshal(block)
207 check(err)
208
209 fmt.Fprintln(w, string(jsonResp))
210 }
211}
212func Tx(w http.ResponseWriter, r *http.Request) {
213 ipFilter(w, r)
214
215 vars := mux.Vars(r)
216 txid := vars["txid"]
217 if txid == "undefined" {
218 fmt.Fprintln(w, "not valid txid")
219 } else {
220 tx := TxModel{}
221 err := txCollection.Find(bson.M{"txid": txid}).One(&tx)
222
223 //convert []resp struct to json
224 jsonResp, err := json.Marshal(tx)
225 check(err)
226
227 fmt.Fprintln(w, string(jsonResp))
228 }
229}
230func Address(w http.ResponseWriter, r *http.Request) {
231 ipFilter(w, r)
232
233 vars := mux.Vars(r)
234 hash := vars["hash"]
235 if hash == "undefined" {
236 fmt.Fprintln(w, "not valid hash")
237 } else {
238 address := AddressModel{}
239 err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
240
241 txs := []TxModel{}
242 err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"vin.address": hash}, bson.M{"vout.address": hash}}}).All(&txs)
243 address.Txs = txs
244
245 for _, tx := range address.Txs {
246 blocks := []BlockModel{}
247 err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
248 for _, block := range blocks {
249 address.Blocks = append(address.Blocks, block)
250 }
251 }
252
253 //convert []resp struct to json
254 jsonResp, err := json.Marshal(address)
255 check(err)
256
257 fmt.Fprintln(w, string(jsonResp))
258 }
259}
260func AddressNetwork(w http.ResponseWriter, r *http.Request) {
261 ipFilter(w, r)
262
263 vars := mux.Vars(r)
264 address := vars["address"]
265 if address == "undefined" {
266 fmt.Fprintln(w, "not valid address")
267 } else {
268 network := addressTree(address)
269 network.Nodes[0].Shape = "triangle"
270
271 //convert []resp struct to json
272 jNetwork, err := json.Marshal(network)
273 check(err)
274
275 fmt.Fprintln(w, string(jNetwork))
276 }
277}
278func AddressSankey(w http.ResponseWriter, r *http.Request) {
279 ipFilter(w, r)
280 vars := mux.Vars(r)
281 address := vars["address"]
282 if address == "undefined" {
283 fmt.Fprintln(w, "not valid address")
284 } else {
285 network := addressTree(address)
286 var sankey SankeyModel
287
288 fmt.Println("network generated")
289 mapNodeK := make(map[string]int)
290 for k, n := range network.Nodes {
291 var sankeyNode SankeyNodeModel
292 //sankeyNode.StringNode = n.Id
293 sankeyNode.Node = k
294 sankeyNode.Name = n.Id
295 sankey.Nodes = append(sankey.Nodes, sankeyNode)
296 mapNodeK[n.Id] = k
297 }
298 for _, e := range network.Edges {
299 var sankeyLink SankeyLinkModel
300 //sankeyLink.StringSource = e.From
301 sankeyLink.Source = mapNodeK[e.From]
302 //sankeyLink.StringTarget = e.To
303 sankeyLink.Target = mapNodeK[e.To]
304 sankeyLink.Value = e.Label
305 sankey.Links = append(sankey.Links, sankeyLink)
306 }
307 fmt.Println("Sankey generated")
308
309 //convert []resp struct to json
310 jsonSankey, err := json.Marshal(sankey)
311 check(err)
312
313 fmt.Fprintln(w, string(jsonSankey))
314 }
315}
316func NetworkMap(w http.ResponseWriter, r *http.Request) {
317 ipFilter(w, r)
318
319 nodes, err := getAllNodes()
320 check(err)
321 edges, err := getAllEdges()
322 check(err)
323
324 var network NetworkModel
325 network.Nodes = nodes
326 network.Edges = edges
327
328 //convert []resp struct to json
329 jNetwork, err := json.Marshal(network)
330 check(err)
331
332 fmt.Fprintln(w, string(jNetwork))
333}
334
335func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) {
336 ipFilter(w, r)
337
338 hourAnalysis := []ChartCountModel{}
339 iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter()
340 err := iter.All(&hourAnalysis)
341
342 //sort by hour
343 sort.Slice(hourAnalysis, func(i, j int) bool {
344 return hourAnalysis[i].Elem < hourAnalysis[j].Elem
345 })
346
347 var resp ChartAnalysisResp
348 for _, d := range hourAnalysis {
349 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
350 resp.Data = append(resp.Data, d.Count)
351 }
352
353 //convert []resp struct to json
354 jsonResp, err := json.Marshal(resp)
355 check(err)
356 fmt.Fprintln(w, string(jsonResp))
357}
358
359func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) {
360 ipFilter(w, r)
361
362 fromDate := time.Now().AddDate(0, 0, -1)
363 toDate := time.Now()
364
365 txs := []TxModel{}
366 err := txCollection.Find(bson.M{
367 "datet": bson.M{
368 "$gt": fromDate,
369 "$lt": toDate,
370 },
371 }).Sort("-$natural").All(&txs)
372 check(err)
373
374 //generate map with 24 hours
375 hourFrequencies := map24hours()
376 for _, tx := range txs {
377 hourFrequencies[tx.Date.Hour]++
378 }
379 var hourCount []ChartCountModel
380 for hour, frequency := range hourFrequencies {
381 hourCount = append(hourCount, ChartCountModel{hour, frequency})
382 }
383 //sort by hour
384 sort.Slice(hourCount, func(i, j int) bool {
385 return hourCount[i].Elem < hourCount[j].Elem
386 })
387
388 var resp ChartAnalysisResp
389 for _, d := range hourCount {
390 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
391 resp.Data = append(resp.Data, d.Count)
392 }
393
394 //convert []resp struct to json
395 jsonResp, err := json.Marshal(resp)
396 check(err)
397 fmt.Fprintln(w, string(jsonResp))
398}
399func GetLast7DayAnalysis(w http.ResponseWriter, r *http.Request) {
400 ipFilter(w, r)
401
402 fromDate := time.Now().AddDate(0, 0, -7)
403 toDate := time.Now()
404
405 txs := []TxModel{}
406 err := txCollection.Find(bson.M{
407 "datet": bson.M{
408 "$gt": fromDate,
409 "$lt": toDate,
410 },
411 }).Sort("-$natural").All(&txs)
412 check(err)
413
414 //generate map with 24 hours
415 //hourFrequencies := map24hours()
416 dayFrequencies := make(map[int]int)
417 for _, tx := range txs {
418 dayFrequencies[tx.Date.Day]++
419 }
420 var dayCount []ChartCountModel
421 for day, frequency := range dayFrequencies {
422 dayCount = append(dayCount, ChartCountModel{day, frequency})
423 }
424 //sort by hour
425 sort.Slice(dayCount, func(i, j int) bool {
426 return dayCount[i].Elem < dayCount[j].Elem
427 })
428
429 var resp ChartAnalysisResp
430 for _, d := range dayCount {
431 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
432 resp.Data = append(resp.Data, d.Count)
433 }
434
435 //convert []resp struct to json
436 jsonResp, err := json.Marshal(resp)
437 check(err)
438 fmt.Fprintln(w, string(jsonResp))
439}
440
441func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) {
442 ipFilter(w, r)
443
444 var resp ChartSeriesAnalysisResp
445
446 for i := 0; i < 7; i++ {
447 fromDate := time.Now().AddDate(0, 0, -i-1)
448 toDate := time.Now().AddDate(0, 0, -i)
449 txs := []TxModel{}
450 err := txCollection.Find(bson.M{
451 "datet": bson.M{
452 "$gt": fromDate,
453 "$lt": toDate,
454 },
455 }).Sort("-$natural").All(&txs)
456 check(err)
457
458 //generate map with 24 hours
459 hourFrequencies := map24hours()
460 for _, tx := range txs {
461 hourFrequencies[tx.Date.Hour]++
462 }
463 var hourCount []ChartCountModel
464 for hour, frequency := range hourFrequencies {
465 hourCount = append(hourCount, ChartCountModel{hour, frequency})
466 }
467 //sort by hour
468 sort.Slice(hourCount, func(i, j int) bool {
469 return hourCount[i].Elem < hourCount[j].Elem
470 })
471 var dayData []int
472 for _, d := range hourCount {
473 dayData = append(dayData, d.Count)
474 }
475 if len(txs) > 0 {
476 resp.Series = append(resp.Series, txs[0].Date.Day)
477 resp.Data = append(resp.Data, dayData)
478 }
479 }
480 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"}
481 resp.Labels = hourLabels
482
483 //convert []resp struct to json
484 jsonResp, err := json.Marshal(resp)
485 check(err)
486 fmt.Fprintln(w, string(jsonResp))
487}
488func GetAddressTimeChart(w http.ResponseWriter, r *http.Request) {
489 ipFilter(w, r)
490
491 vars := mux.Vars(r)
492 hash := vars["hash"]
493 if hash == "undefined" {
494 fmt.Fprintln(w, "not valid hash")
495 } else {
496 address := AddressModel{}
497 err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
498
499 txs := []TxModel{}
500 err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"vin.address": hash}, bson.M{"vout.address": hash}}}).All(&txs)
501 address.Txs = txs
502
503 for _, tx := range address.Txs {
504 blocks := []BlockModel{}
505 err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
506 for _, block := range blocks {
507 address.Blocks = append(address.Blocks, block)
508 }
509 }
510
511 count := make(map[time.Time]float64)
512 for _, tx := range txs {
513 var val float64
514 for _, vin := range tx.Vin {
515 val = val + vin.Amount
516 }
517 count[tx.DateT] = val
518 }
519 var dateSorted []time.Time
520 for t, _ := range count {
521 dateSorted = append(dateSorted, t)
522 }
523 sort.Slice(dateSorted, func(i, j int) bool {
524 //return dateSorted[i] < dateSorted[j]
525 return dateBeforeThan(dateSorted[i], dateSorted[j])
526 })
527
528 var resp ChartAnalysisRespFloat64
529 for _, t := range dateSorted {
530 resp.Labels = append(resp.Labels, t.String())
531 resp.Data = append(resp.Data, count[t])
532 }
533
534 //convert []resp struct to json
535 jsonResp, err := json.Marshal(resp)
536 check(err)
537
538 fmt.Fprintln(w, string(jsonResp))
539 }
540}