From ce5462118c84a1cb2f894e2f56ddc069cdeddeea Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Thu, 28 Jun 2018 21:18:52 +0200 Subject: [PATCH] Add initial implementation of tx explorer --- api/worker.go | 33 ++++++---- server/public.go | 29 +++++---- static/css/main.css | 112 +++++++++++++++++++++++++++++++-- static/templates/base.html | 13 ++-- static/templates/tx.html | 59 ++++++++++------- static/templates/txdetail.html | 79 ++++++++++++++++++++++- 6 files changed, 263 insertions(+), 62 deletions(-) diff --git a/api/worker.go b/api/worker.go index 0f22255b..14ef57cb 100644 --- a/api/worker.go +++ b/api/worker.go @@ -49,18 +49,21 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool) vin.N = i vin.Vout = bchainVin.Vout vin.ScriptSig.Hex = bchainVin.ScriptSig.Hex - otx, _, err := w.txCache.GetTransaction(bchainVin.Txid, bestheight) - if err != nil { - return nil, err - } - if len(otx.Vout) > int(vin.Vout) { - vout := &otx.Vout[vin.Vout] - vin.Value = vout.Value - valIn += vout.Value - vin.ValueSat = int64(vout.Value*1E8 + 0.5) - if vout.Address != nil { - a := vout.Address.String() - vin.Addr = a + // bchainVin.Txid=="" is coinbase transaction + if bchainVin.Txid != "" { + otx, _, err := w.txCache.GetTransaction(bchainVin.Txid, bestheight) + if err != nil { + return nil, err + } + if len(otx.Vout) > int(vin.Vout) { + vout := &otx.Vout[vin.Vout] + vin.Value = vout.Value + valIn += vout.Value + vin.ValueSat = int64(vout.Value*1E8 + 0.5) + if vout.Address != nil { + a := vout.Address.String() + vin.Addr = a + } } } } @@ -77,9 +80,13 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool) // TODO } } + // for coinbase transactions valIn is 0 + fees = valIn - valOut + if fees < 0 { + fees = 0 + } // for now do not return size, we would have to compute vsize of segwit transactions // size:=len(bchainTx.Hex) / 2 - fees = valIn - valOut r := &Tx{ Blockhash: blockhash, Blockheight: int(height), diff --git a/server/public.go b/server/public.go index 5de9c817..b517e5fc 100644 --- a/server/public.go +++ b/server/public.go @@ -89,19 +89,28 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch // default handler serveMux.HandleFunc(path, s.index) - templateFuncMap := template.FuncMap{ - "formatUnixTime": formatUnixTime, - } - - s.txTpl = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html")) + s.txTpl = parseTemplates() return s, nil } +func parseTemplates() (txTpl *template.Template) { + templateFuncMap := template.FuncMap{ + "formatUnixTime": formatUnixTime, + "formatAmount": formatAmount, + } + txTpl = template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html")) + return +} + func formatUnixTime(ut int64) string { return time.Unix(ut, 0).Format(time.RFC1123) } +func formatAmount(a float64) string { + return fmt.Sprintf("%0.8f", a) +} + // Run starts the server func (s *PublicServer) Run() error { if s.certFiles == "" { @@ -173,7 +182,8 @@ func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) { bestheight, _, err := s.db.GetBestBlock() if err == nil { tx, err = s.api.GetTransaction(txid, bestheight, true) - } else { + } + if err != nil { glog.Error(err) } } @@ -181,16 +191,13 @@ func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) { // temporarily reread the template on each request // to reflect changes during development - templateFuncMap := template.FuncMap{ - "formatUnixTime": formatUnixTime, - } - txTpl := template.Must(template.New("tx").Funcs(templateFuncMap).ParseFiles("./static/templates/tx.html", "./static/templates/txdetail.html", "./static/templates/base.html")) + s.txTpl = parseTemplates() data := struct { CoinName string Specific *api.Tx }{s.is.Coin, tx} - if err := txTpl.ExecuteTemplate(w, "base.html", data); err != nil { + if err := s.txTpl.ExecuteTemplate(w, "base.html", data); err != nil { glog.Error(err) } } diff --git a/static/css/main.css b/static/css/main.css index 988ea8b6..8265aadd 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -4,28 +4,52 @@ html, body { body { width: 100%; - min-width: 727px; min-height: 100%; background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif; - font-size: 14px; + font-size: 11px; +} + +a { + color: #428bca; + text-decoration: none; +} + +.octicon { + color: #777; + display: inline-block; + vertical-align: text-top; + fill: currentColor; + height: 16px; } @media (min-width: 768px) { .container { - width: 750px; + max-width: 750px; } } @media (min-width: 992px) { + body { + font-size: 12px; + } .container { - width: 970px; + max-width: 970px; + } + .octicon { + height: 24px; } } @media (min-width: 1200px) { + body { + font-size: 14px; + } .container { - width: 1170px; + max-width: 1170px; + } + .octicon { + height: 32px; } } @@ -73,6 +97,82 @@ body { overflow: hidden; } -.value-group { +.alert-data { + color: #383d41; + background-color: #f4f4f4; + border-color: #d6d8db; + padding: 15px; +} + +.line-top { + border-top: 1px solid #EAEAEA; + padding: 15px 0 0; +} + +.line-mid { + padding: 15px; +} + +.line-bot { + border-bottom: 2px solid #EAEAEA; + padding: 0 0 15px; +} + +.txvalues { + display: inline-block; + padding: .7em 2em; + font-size: 13px; + font-weight: 100; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} + +.txvalues-default { + background-color: #EBEBEB; + color: #333; +} + +.txvalues-success { + background-color: dimgray; +} + +.txvalues-primary { + background-color: #000; +} + +.txvalues-danger { + background-color: #AC0015; + text-transform: uppercase; +} + +.ellipsis { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.data-div { margin: 20px 0; +} + +.data-table { + table-layout: fixed; + border-radius: .25rem; + background: white; +} + +.data-table td, .data-table th { + padding: .4rem; +} + +.data { + font-weight: bold; +} + +.alert .data-table { + margin: 0; } \ No newline at end of file diff --git a/static/templates/base.html b/static/templates/base.html index 4dc8accb..2bf99835 100644 --- a/static/templates/base.html +++ b/static/templates/base.html @@ -2,7 +2,6 @@ - @@ -50,19 +49,19 @@
{{template "specific" .Specific}} -
+