mirror of
https://github.com/arnaucube/goBlockchainDataAnalysis.git
synced 2026-02-07 03:36:44 +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
|
- mantain connection with wallet using websockets
|
||||||
|
|
||||||
- num address evolution throught time
|
- 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"
|
nodeTx.Type = "tx"
|
||||||
saveNode(nodeCollection, nodeTx)
|
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 originAddresses []string
|
||||||
var outputAddresses []string
|
var outputAddresses []string
|
||||||
var outputAmount []float64
|
var outputAmount []float64
|
||||||
@@ -101,6 +112,11 @@ func explore(client *rpcclient.Client, blockHash string) {
|
|||||||
addr.Hash = outputAddr
|
addr.Hash = outputAddr
|
||||||
addr.InBittrex = false
|
addr.InBittrex = false
|
||||||
saveAddress(addr)
|
saveAddress(addr)
|
||||||
|
|
||||||
|
var newVout Vout
|
||||||
|
newVout.Value = Vo.Value
|
||||||
|
newVout.Address = outputAddr
|
||||||
|
newTx.Vout = append(newTx.Vout, newVout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, Vi := range blockTx.Vin {
|
for _, Vi := range blockTx.Vin {
|
||||||
@@ -108,24 +124,20 @@ func explore(client *rpcclient.Client, blockHash string) {
|
|||||||
check(err)
|
check(err)
|
||||||
txVi, err := client.GetRawTransactionVerbose(th)
|
txVi, err := client.GetRawTransactionVerbose(th)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
if len(txVi.Vout[Vi.Vout].ScriptPubKey.Addresses) > 0 {
|
if len(txVi.Vout[Vi.Vout].ScriptPubKey.Addresses) > 0 {
|
||||||
//add tx to newBlock
|
//add tx to newBlock
|
||||||
newBlock.Tx = append(newBlock.Tx, blockTx.Txid)
|
newBlock.Tx = append(newBlock.Tx, blockTx.Txid)
|
||||||
|
|
||||||
//Tx save
|
//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 {
|
for _, originAddr := range txVi.Vout[Vi.Vout].ScriptPubKey.Addresses {
|
||||||
originAddresses = append(originAddresses, originAddr)
|
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
|
var n1 NodeModel
|
||||||
n1.Id = originAddr
|
n1.Id = originAddr
|
||||||
@@ -167,11 +179,10 @@ func explore(client *rpcclient.Client, blockHash string) {
|
|||||||
//hour analysis
|
//hour analysis
|
||||||
hourAnalysis(eIn, blockTx.Time)
|
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)
|
saveTx(newTx)
|
||||||
} else {
|
} else {
|
||||||
originAddresses = append(originAddresses, "origin")
|
originAddresses = append(originAddresses, "origin")
|
||||||
|
|||||||
@@ -18,12 +18,24 @@ type DateModel struct {
|
|||||||
BlockHash string `json:"blockhash"`
|
BlockHash string `json:"blockhash"`
|
||||||
BlockHeight string `json:"blockheight"`*/
|
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 {
|
type TxModel struct {
|
||||||
Hex string `json:"hex"`
|
Hex string `json:"hex"`
|
||||||
Txid string `json:"txid"`
|
Txid string `json:"txid"`
|
||||||
Hash string `json:"hash"`
|
Hash string `json:"hash"`
|
||||||
From string `json:"from"` //hash of address
|
/*From string `json:"from"` //hash of address
|
||||||
To string `json:"to"` //hash of address
|
To string `json:"to"` //hash of address*/
|
||||||
|
Vin []Vin `json:"vin"`
|
||||||
|
Vout []Vout `json:"vout"`
|
||||||
Amount float64 `json:"amount"`
|
Amount float64 `json:"amount"`
|
||||||
BlockHash string `json:"blockhash"`
|
BlockHash string `json:"blockhash"`
|
||||||
BlockHeight string `json:"blockheight"`
|
BlockHeight string `json:"blockheight"`
|
||||||
@@ -39,6 +51,7 @@ type BlockModel struct {
|
|||||||
//Amount float64 `json:"amount"`
|
//Amount float64 `json:"amount"`
|
||||||
//Fee float64 `json:"fee"`
|
//Fee float64 `json:"fee"`
|
||||||
Tx []string `json:"txid"` //txid of the TxModel
|
Tx []string `json:"txid"` //txid of the TxModel
|
||||||
|
Txs []TxModel `json:"txs"`
|
||||||
PreviousHash string `json:"previoushash"`
|
PreviousHash string `json:"previoushash"`
|
||||||
NextHash string `json:"nexthash"`
|
NextHash string `json:"nexthash"`
|
||||||
Time int64 `json:"time"`
|
Time int64 `json:"time"`
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ var routes = Routes{
|
|||||||
GetLastTx,
|
GetLastTx,
|
||||||
},
|
},
|
||||||
Route{
|
Route{
|
||||||
"AddressNetwork",
|
"Block",
|
||||||
"GET",
|
"GET",
|
||||||
"/address/network/{address}",
|
"/block/{height}",
|
||||||
AddressNetwork,
|
Block,
|
||||||
},
|
},
|
||||||
Route{
|
Route{
|
||||||
"Address",
|
"Address",
|
||||||
@@ -58,6 +58,12 @@ var routes = Routes{
|
|||||||
"/address/{hash}",
|
"/address/{hash}",
|
||||||
Address,
|
Address,
|
||||||
},
|
},
|
||||||
|
Route{
|
||||||
|
"AddressNetwork",
|
||||||
|
"GET",
|
||||||
|
"/address/network/{address}",
|
||||||
|
AddressNetwork,
|
||||||
|
},
|
||||||
Route{
|
Route{
|
||||||
"AddressSankey",
|
"AddressSankey",
|
||||||
"GET",
|
"GET",
|
||||||
@@ -167,22 +173,36 @@ func GetLastTx(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
fmt.Fprintln(w, string(jsonData))
|
fmt.Fprintln(w, string(jsonData))
|
||||||
}
|
}
|
||||||
func AddressNetwork(w http.ResponseWriter, r *http.Request) {
|
func Block(w http.ResponseWriter, r *http.Request) {
|
||||||
ipFilter(w, r)
|
ipFilter(w, r)
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
address := vars["address"]
|
var heightString string
|
||||||
if address == "undefined" {
|
heightString = vars["height"]
|
||||||
fmt.Fprintln(w, "not valid address")
|
height, err := strconv.ParseInt(heightString, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(w, "not valid height")
|
||||||
} else {
|
} else {
|
||||||
network := addressTree(address)
|
block := BlockModel{}
|
||||||
network.Nodes[0].Shape = "triangle"
|
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
|
//convert []resp struct to json
|
||||||
jNetwork, err := json.Marshal(network)
|
jsonResp, err := json.Marshal(block)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
fmt.Fprintln(w, string(jNetwork))
|
fmt.Fprintln(w, string(jsonResp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func Address(w http.ResponseWriter, r *http.Request) {
|
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))
|
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) {
|
func AddressSankey(w http.ResponseWriter, r *http.Request) {
|
||||||
ipFilter(w, r)
|
ipFilter(w, r)
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ angular.module('webApp', [
|
|||||||
'angular-svg-round-progressbar',
|
'angular-svg-round-progressbar',
|
||||||
'app.navbar',
|
'app.navbar',
|
||||||
'app.main',
|
'app.main',
|
||||||
|
'app.block',
|
||||||
|
'app.address',
|
||||||
'app.network',
|
'app.network',
|
||||||
'app.addressNetwork',
|
'app.addressNetwork',
|
||||||
'app.address',
|
|
||||||
'app.sankey',
|
'app.sankey',
|
||||||
'app.dateAnalysis'
|
'app.dateAnalysis'
|
||||||
]).
|
]).
|
||||||
|
|||||||
8
web/css/bootstrapMaterialDarkOverwrite.css
vendored
8
web/css/bootstrapMaterialDarkOverwrite.css
vendored
@@ -21,9 +21,15 @@ body {
|
|||||||
.list-group-item:hover {
|
.list-group-item:hover {
|
||||||
background: rgba(255, 255, 255, 0.2)!important;
|
background: rgba(255, 255, 255, 0.2)!important;
|
||||||
}
|
}
|
||||||
.list-group-item p, a{
|
.list-group-item p {
|
||||||
color: #ffffff!important;
|
color: #ffffff!important;
|
||||||
}
|
}
|
||||||
|
.list-group-item a {
|
||||||
|
color: #512DA8!important;
|
||||||
|
}
|
||||||
|
.list-group-item-text {
|
||||||
|
color: #9575CD!important;
|
||||||
|
}
|
||||||
.table-hover tbody tr:hover {
|
.table-hover tbody tr:hover {
|
||||||
background-color: rgba(245, 245, 245, 0.2)!important;
|
background-color: rgba(245, 245, 245, 0.2)!important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,9 +76,10 @@
|
|||||||
<script src="app.js"></script>
|
<script src="app.js"></script>
|
||||||
<script src="views/navbar.js"></script>
|
<script src="views/navbar.js"></script>
|
||||||
<script src="views/main/main.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/network/network.js"></script>
|
||||||
<script src="views/addressNetwork/addressNetwork.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/sankey/sankey.js"></script>
|
||||||
<script src="views/dateAnalysis/dateAnalysis.js"></script>
|
<script src="views/dateAnalysis/dateAnalysis.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -8,23 +8,29 @@
|
|||||||
{{address.amount}}
|
{{address.amount}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-heading c_deepPurpleG300to500">
|
<div class="panel-heading c_deepPurpleG300to500">
|
||||||
<h3 class="panel-title">Blocks where address appears</h3>
|
<h3 class="panel-title">Blocks where address appears</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body" ng-repeat="block in address.blocks">
|
<div class="panel-body">
|
||||||
Block Height: {{block.height}}
|
<div class="list-group">
|
||||||
<br>
|
<a ng-href="#!/block/{{block.height}}" class="list-group-item-text" ng-repeat="block in address.blocks">
|
||||||
Hash: {{block.Hash}}
|
Block Height: {{block.height}}
|
||||||
<br>
|
<br> Hash: {{block.hash}}
|
||||||
{{block.datet}}
|
<br> {{block.datet}}
|
||||||
<br>
|
<br> Size: {{block.size}} bytes
|
||||||
{{block.Size}}
|
<br>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="panel-heading c_deepPurpleG300to500">
|
<div class="panel-heading c_deepPurpleG300to500">
|
||||||
<h3 class="panel-title">Tx where address appears</h3>
|
<h3 class="panel-title">Tx where address appears</h3>
|
||||||
@@ -42,9 +48,21 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="tx in address.txs">
|
<tr ng-repeat="tx in address.txs">
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.blockheight}}</td>
|
<td style="max-width:20px; overflow:hidden;">
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.from}}</td>
|
<a ng-href="#!/block/{{tx.blockheight}}" class="list-group-item-text">
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.to}}</td>
|
{{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>{{tx.amount}}</td>
|
||||||
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
||||||
</tr>
|
</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>
|
<h3 class="panel-title">Last Tx with amount</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body" style="max-height: 250px;overflow-y: scroll;">
|
<div class="panel-body" style="max-height: 250px;overflow-y: scroll;">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
<!--<colgroup>
|
<thead>
|
||||||
<col class="col-md-2">
|
<tr>
|
||||||
<col class="col-md-2">
|
<th>BlockHeight</th>
|
||||||
<col class="col-md-2">
|
<th>Txid</th>
|
||||||
<col class="col-md-2">
|
<th>Input</th>
|
||||||
<col class="col-md-2">
|
<th>Output</th>
|
||||||
<col class="col-md-2">
|
</tr>
|
||||||
</colgroup>-->
|
</thead>
|
||||||
<thead>
|
<tbody>
|
||||||
<tr>
|
<tr ng-repeat="tx in txs">
|
||||||
<th>BlockHeight</th>
|
<td style="max-width:20px; overflow:hidden;">
|
||||||
<th>From</th>
|
<a ng-href="#!/block/{{tx.blockheight}}" class="list-group-item-text">
|
||||||
<th>To</th>
|
{{tx.blockheight}}
|
||||||
<th>Amount</th>
|
</a>
|
||||||
<th></th>
|
</td>
|
||||||
</tr>
|
<td style="max-width:20px; overflow:hidden;">
|
||||||
</thead>
|
<a ng-href="#!/address/{{tx.from}}" class="list-group-item-text">
|
||||||
<tbody>
|
{{tx.txid}}
|
||||||
<tr ng-repeat="tx in txs">
|
</a>
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.blockheight}}</td>
|
</td>
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.from}}</td>
|
<td style="max-width:20px; overflow:hidden;">
|
||||||
<td style="max-width:20px; overflow:hidden;">{{tx.to}}</td>
|
<table><tbody><tr ng-repeat="vin in tx.vin"><td>
|
||||||
<td>{{tx.amount}}</td>
|
<a ng-href="#!/address/{{vin.address}}" class="list-group-item-text">
|
||||||
<td><a ng-href="#!/tx/{{tx.id}}">View</a></td>
|
{{vin.address}}
|
||||||
</tr>
|
</a>
|
||||||
</tbody>
|
:{{vin.amount}}
|
||||||
</table>
|
</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>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user