Show ethereum specific data in tx detail in explorer
This commit is contained in:
parent
8ac57a3d56
commit
463eab9d2d
@ -241,7 +241,10 @@ func (w *Worker) GetTransaction(txid string, spendingTxs bool, specificJSON bool
|
||||
}
|
||||
}
|
||||
ethSpecific = eth.GetEthereumTxData(bchainTx)
|
||||
feesSat.Mul(ethSpecific.GasPriceNum, ethSpecific.GasUsed)
|
||||
// mempool txs do not have fees yet
|
||||
if ethSpecific.GasUsed != nil {
|
||||
feesSat.Mul(ethSpecific.GasPriceNum, ethSpecific.GasUsed)
|
||||
}
|
||||
if len(bchainTx.Vout) > 0 {
|
||||
valInSat = bchainTx.Vout[0].ValueSat
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ func GetErc20FromTx(tx *bchain.Tx) ([]Erc20Transfer, error) {
|
||||
var r []Erc20Transfer
|
||||
var err error
|
||||
csd, ok := tx.CoinSpecificData.(completeTransaction)
|
||||
if ok {
|
||||
if ok && csd.Receipt != nil {
|
||||
r, err = erc20GetTransfersFromLog(csd.Receipt.Logs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
"system_user": "blockbook-ethereum-classic",
|
||||
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
|
||||
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
|
||||
"explorer_url": "https://gastracker.io/",
|
||||
"explorer_url": "",
|
||||
"additional_params": "-resyncindexperiod=4441",
|
||||
"block_chain": {
|
||||
"parse": true,
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
"system_user": "blockbook-ethereum",
|
||||
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
|
||||
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
|
||||
"explorer_url": "https://etherscan.io/",
|
||||
"explorer_url": "",
|
||||
"additional_params": "",
|
||||
"block_chain": {
|
||||
"parse": true,
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
"system_user": "blockbook-ethereum",
|
||||
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
|
||||
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
|
||||
"explorer_url": "https://ropsten.etherscan.io/",
|
||||
"explorer_url": "",
|
||||
"additional_params": "",
|
||||
"block_chain": {
|
||||
"parse": true,
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -81,7 +82,7 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch
|
||||
is: is,
|
||||
debug: debugMode,
|
||||
}
|
||||
s.templates = parseTemplates()
|
||||
s.templates = s.parseTemplates()
|
||||
|
||||
// map only basic functions, the rest is enabled by method MapFullPublicInterface
|
||||
serveMux.Handle(path+"favicon.ico", http.FileServer(http.Dir("./static/")))
|
||||
@ -202,6 +203,7 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request) (interface{}, e
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
glog.Error(getFunctionName(handler), " recovered from panic: ", e)
|
||||
debug.PrintStack()
|
||||
if s.debug {
|
||||
data = jsonError{fmt.Sprint("Internal server error: recovered from panic ", e), http.StatusInternalServerError}
|
||||
} else {
|
||||
@ -264,6 +266,7 @@ func (s *PublicServer) htmlTemplateHandler(handler func(w http.ResponseWriter, r
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
glog.Error(getFunctionName(handler), " recovered from panic: ", e)
|
||||
debug.PrintStack()
|
||||
t = errorInternalTpl
|
||||
if s.debug {
|
||||
data = s.newTemplateDataWithError(fmt.Sprint("Internal server error: recovered from panic ", e))
|
||||
@ -286,7 +289,7 @@ func (s *PublicServer) htmlTemplateHandler(handler func(w http.ResponseWriter, r
|
||||
if s.debug {
|
||||
// reload templates on each request
|
||||
// to reflect changes during development
|
||||
s.templates = parseTemplates()
|
||||
s.templates = s.parseTemplates()
|
||||
}
|
||||
t, data, err = handler(w, r)
|
||||
if err != nil || (data == nil && t != noTpl) {
|
||||
@ -349,7 +352,7 @@ type TemplateData struct {
|
||||
Status string
|
||||
}
|
||||
|
||||
func parseTemplates() []*template.Template {
|
||||
func (s *PublicServer) parseTemplates() []*template.Template {
|
||||
templateFuncMap := template.FuncMap{
|
||||
"formatTime": formatTime,
|
||||
"formatUnixTime": formatUnixTime,
|
||||
@ -361,11 +364,17 @@ func parseTemplates() []*template.Template {
|
||||
t[errorTpl] = template.Must(template.New("error").Funcs(templateFuncMap).ParseFiles("./static/templates/error.html", "./static/templates/base.html"))
|
||||
t[errorInternalTpl] = template.Must(template.New("error").Funcs(templateFuncMap).ParseFiles("./static/templates/error.html", "./static/templates/base.html"))
|
||||
t[indexTpl] = template.Must(template.New("index").Funcs(templateFuncMap).ParseFiles("./static/templates/index.html", "./static/templates/base.html"))
|
||||
t[txTpl] = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html"))
|
||||
t[addressTpl] = template.Must(template.New("address").Funcs(templateFuncMap).ParseFiles("./static/templates/address.html", "./static/templates/txdetail.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
t[blocksTpl] = template.Must(template.New("blocks").Funcs(templateFuncMap).ParseFiles("./static/templates/blocks.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
t[blockTpl] = template.Must(template.New("block").Funcs(templateFuncMap).ParseFiles("./static/templates/block.html", "./static/templates/txdetail.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
t[sendTransactionTpl] = template.Must(template.New("block").Funcs(templateFuncMap).ParseFiles("./static/templates/sendtx.html", "./static/templates/base.html"))
|
||||
if s.chainParser.GetChainType() == bchain.ChainEthereumType {
|
||||
t[txTpl] = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail_ethereumtype.html", "./static/templates/base.html"))
|
||||
t[addressTpl] = template.Must(template.New("address").Funcs(templateFuncMap).ParseFiles("./static/templates/address.html", "./static/templates/txdetail_ethereumtype.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
t[blockTpl] = template.Must(template.New("block").Funcs(templateFuncMap).ParseFiles("./static/templates/block.html", "./static/templates/txdetail_ethereumtype.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
} else {
|
||||
t[txTpl] = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html"))
|
||||
t[addressTpl] = template.Must(template.New("address").Funcs(templateFuncMap).ParseFiles("./static/templates/address.html", "./static/templates/txdetail.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
t[blockTpl] = template.Must(template.New("block").Funcs(templateFuncMap).ParseFiles("./static/templates/block.html", "./static/templates/txdetail.html", "./static/templates/paging.html", "./static/templates/base.html"))
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -161,6 +162,7 @@ func (s *SocketIoServer) onMessage(c *gosocketio.Channel, req map[string]json.Ra
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
glog.Error(c.Id(), " onMessage ", method, " recovered from panic: ", r)
|
||||
debug.PrintStack()
|
||||
e := resultError{}
|
||||
e.Error.Message = "Internal error"
|
||||
rv = e
|
||||
@ -664,6 +666,7 @@ func (s *SocketIoServer) onSubscribe(c *gosocketio.Channel, req []byte) interfac
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
glog.Error(c.Id(), " onSubscribe recovered from panic: ", r)
|
||||
debug.PrintStack()
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@ -7,20 +7,46 @@
|
||||
<div class="data-div">
|
||||
<table class="table data-table">
|
||||
<tbody>
|
||||
{{if $tx.Confirmations}}
|
||||
{{- if $tx.Confirmations -}}
|
||||
<tr>
|
||||
<td style="width: 25%;">Mined Time</td>
|
||||
<td class="data">{{formatUnixTime $tx.Blocktime}}</td>
|
||||
</tr>{{end}}
|
||||
</tr>{{end -}}
|
||||
<tr>
|
||||
<td style="width: 25%;">In Block</td>
|
||||
<td class="ellipsis data">{{if $tx.Confirmations}}{{$tx.Blockhash}}{{else}}Unconfirmed{{end}}</td>
|
||||
</tr>
|
||||
{{if $tx.Confirmations}}
|
||||
{{- if $tx.Confirmations -}}
|
||||
<tr>
|
||||
<td>In Block Height</td>
|
||||
<td class="data"><a href="/block/{{$tx.Blockheight}}">{{$tx.Blockheight}}</a></td>
|
||||
</tr>{{end}}
|
||||
{{- if $tx.EthereumSpecific -}}
|
||||
<tr>
|
||||
<td>Status</td>
|
||||
{{- if $tx.EthereumSpecific.Status -}}
|
||||
{{- if ne $tx.EthereumSpecific.Status 1 -}}
|
||||
<td class="data">Pending</td>
|
||||
{{- else -}}
|
||||
<td class="data text-success">Success</td>
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
<td class="data text-danger">Fail</td>
|
||||
{{- end -}}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Value</td>
|
||||
<td class="data">{{formatAmount $tx.ValueOut}} {{$cs}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gas Used / Limit</td>
|
||||
<td class="data">{{if $tx.EthereumSpecific.GasUsed}}{{$tx.EthereumSpecific.GasUsed}}{{else}}pending{{end}} / {{$tx.EthereumSpecific.GasLimit}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gas Price</td>
|
||||
<td class="data">{{formatAmount $tx.EthereumSpecific.GasPrice}} {{$cs}}</td>
|
||||
</tr>
|
||||
{{- else -}}
|
||||
<tr>
|
||||
<td>Total Input</td>
|
||||
<td class="data">{{formatAmount $tx.ValueIn}} {{$cs}}</td>
|
||||
@ -29,11 +55,12 @@
|
||||
<td>Total Output</td>
|
||||
<td class="data">{{formatAmount $tx.ValueOut}} {{$cs}}</td>
|
||||
</tr>
|
||||
{{if $tx.Fees}}
|
||||
{{- end -}}
|
||||
{{- if $tx.Fees -}}
|
||||
<tr>
|
||||
<td>Fees</td>
|
||||
<td class="data">{{formatAmount $tx.Fees}} {{$cs}}</td>
|
||||
</tr>{{end}}
|
||||
</tr>{{end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
129
static/templates/txdetail_ethereumtype.html
Normal file
129
static/templates/txdetail_ethereumtype.html
Normal file
@ -0,0 +1,129 @@
|
||||
{{define "txdetail"}}{{$cs := .CoinShortcut}}{{$addr := .AddrStr}}{{$tx := .Tx}}
|
||||
<div class="alert alert-data">
|
||||
<div class="row line-bot">
|
||||
<div class="col-xs-7 col-md-8 ellipsis">
|
||||
<a href="/tx/{{$tx.Txid}}">{{$tx.Txid}}</a>
|
||||
</div>
|
||||
{{- if $tx.Confirmations -}}
|
||||
<div class="col-xs-5 col-md-4 text-muted text-right">mined {{formatUnixTime $tx.Blocktime}}</div>
|
||||
{{- end -}}
|
||||
</div>
|
||||
<div class="row line-mid">
|
||||
<div class="col-md-4">
|
||||
<div class="row">
|
||||
<table class="table data-table">
|
||||
<tbody>
|
||||
{{- range $vin := $tx.Vin -}}
|
||||
<tr>
|
||||
<td>
|
||||
{{- range $a := $vin.Addresses -}}
|
||||
<span class="ellipsis float-left">
|
||||
{{if and (ne $a $addr) $vin.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
|
||||
</span>
|
||||
{{- else -}}
|
||||
<span class="float-left">Unparsed address</span>
|
||||
{{- end -}}
|
||||
</td>
|
||||
</tr>
|
||||
{{- else -}}
|
||||
<tr>
|
||||
<td>No Inputs</td>
|
||||
</tr>
|
||||
{{- end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1 col-xs-12 text-center">
|
||||
<svg class="octicon" viewBox="0 0 8 16">
|
||||
<path fill-rule="evenodd" d="M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row">
|
||||
<table class="table data-table">
|
||||
<tbody>
|
||||
{{- range $vout := $tx.Vout -}}
|
||||
<tr>
|
||||
<td>
|
||||
{{- range $a := $vout.ScriptPubKey.Addresses -}}
|
||||
<span class="ellipsis float-left">
|
||||
{{- if and (ne $a $addr) $vout.ScriptPubKey.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
|
||||
</span>
|
||||
{{- else -}}
|
||||
<span class="float-left">Unparsed address</span>
|
||||
{{- end -}}
|
||||
</td>
|
||||
</tr>
|
||||
{{- else -}}
|
||||
<tr>
|
||||
<td>No Outputs</td>
|
||||
</tr>
|
||||
{{- end -}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 text-right" style="padding: .4rem 0;">
|
||||
{{formatAmount $tx.ValueOut}} {{$cs}}
|
||||
</div>
|
||||
</div>
|
||||
{{- if $tx.Erc20Transfers -}}
|
||||
<div class="row line-top" style="padding: 15px 0 6px 15px;">
|
||||
ERC20 Token Transfers
|
||||
</div>
|
||||
{{- range $erc20 := $tx.Erc20Transfers -}}
|
||||
<div class="row" style="padding: 2px 15px;">
|
||||
<div class="col-md-4">
|
||||
<div class="row">
|
||||
<table class="table data-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="ellipsis float-left">{{if ne $erc20.From $addr}}<a href="/address/{{$erc20.From}}">{{$erc20.From}}</a>{{else}}{{$erc20.From}}{{end}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1 col-xs-12 text-center">
|
||||
<svg class="octicon" viewBox="0 0 8 16">
|
||||
<path fill-rule="evenodd" d="M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="row">
|
||||
<table class="table data-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="ellipsis float-left">{{if ne $erc20.To $addr}}<a href="/address/{{$erc20.From}}">{{$erc20.To}}</a>{{else}}{{$erc20.To}}{{end}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 text-right" style="padding: .4rem 0;">{{formatAmount $erc20.Tokens}} {{$erc20.Symbol}}</div>
|
||||
</div>
|
||||
{{- end -}}
|
||||
<div class="row" style="padding: 6px 15px;"></div>
|
||||
{{- end -}}
|
||||
<div class="row line-top">
|
||||
<div class="col-xs-6 col-sm-4 col-md-4">
|
||||
{{- if $tx.Fees -}}
|
||||
<span class="txvalues txvalues-default">Fee: {{formatAmount $tx.Fees}} {{$cs}}</span>
|
||||
{{- end -}}
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-8 col-md-8 text-right">
|
||||
{{- if $tx.Confirmations -}}
|
||||
<span class="txvalues txvalues-success">{{$tx.Confirmations}} Confirmations</span>
|
||||
{{- else -}}
|
||||
<span class="txvalues txvalues-danger ng-hide">Unconfirmed Transaction!</span>
|
||||
{{- end -}}
|
||||
<span class="txvalues txvalues-primary">{{formatAmount $tx.ValueOut}} {{$cs}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
Loading…
Reference in New Issue
Block a user