Refactor tx api
parent
e12641ae7d
commit
81e105dd4f
36
api/types.go
36
api/types.go
|
@ -74,44 +74,34 @@ func (a *Amount) AsBigInt() big.Int {
|
||||||
return big.Int(*a)
|
return big.Int(*a)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScriptSig contains input script
|
|
||||||
type ScriptSig struct {
|
|
||||||
Hex string `json:"hex,omitempty"`
|
|
||||||
Asm string `json:"asm,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vin contains information about single transaction input
|
// Vin contains information about single transaction input
|
||||||
type Vin struct {
|
type Vin struct {
|
||||||
Txid string `json:"txid,omitempty"`
|
Txid string `json:"txid,omitempty"`
|
||||||
Vout uint32 `json:"vout,omitempty"`
|
Vout uint32 `json:"vout,omitempty"`
|
||||||
Sequence int64 `json:"sequence,omitempty"`
|
Sequence int64 `json:"sequence,omitempty"`
|
||||||
N int `json:"n"`
|
N int `json:"n"`
|
||||||
ScriptSig ScriptSig `json:"scriptSig"`
|
|
||||||
AddrDesc bchain.AddressDescriptor `json:"-"`
|
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||||
Addresses []string `json:"addresses"`
|
Addresses []string `json:"addresses"`
|
||||||
Searchable bool `json:"-"`
|
Searchable bool `json:"-"`
|
||||||
ValueSat *Amount `json:"value,omitempty"`
|
ValueSat *Amount `json:"value,omitempty"`
|
||||||
}
|
|
||||||
|
|
||||||
// ScriptPubKey contains output script and addresses derived from it
|
|
||||||
type ScriptPubKey struct {
|
|
||||||
Hex string `json:"hex,omitempty"`
|
Hex string `json:"hex,omitempty"`
|
||||||
Asm string `json:"asm,omitempty"`
|
Asm string `json:"asm,omitempty"`
|
||||||
AddrDesc bchain.AddressDescriptor `json:"-"`
|
|
||||||
Addresses []string `json:"addresses"`
|
|
||||||
Searchable bool `json:"-"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vout contains information about single transaction output
|
// Vout contains information about single transaction output
|
||||||
type Vout struct {
|
type Vout struct {
|
||||||
ValueSat *Amount `json:"value,omitempty"`
|
ValueSat *Amount `json:"value,omitempty"`
|
||||||
N int `json:"n"`
|
N int `json:"n"`
|
||||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
Spent bool `json:"spent,omitempty"`
|
||||||
Spent bool `json:"spent,omitempty"`
|
SpentTxID string `json:"spentTxId,omitempty"`
|
||||||
SpentTxID string `json:"spentTxId,omitempty"`
|
SpentIndex int `json:"spentIndex,omitempty"`
|
||||||
SpentIndex int `json:"spentIndex,omitempty"`
|
SpentHeight int `json:"spentHeight,omitempty"`
|
||||||
SpentHeight int `json:"spentHeight,omitempty"`
|
Hex string `json:"hex,omitempty"`
|
||||||
|
Asm string `json:"asm,omitempty"`
|
||||||
|
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||||
|
Addresses []string `json:"addresses"`
|
||||||
|
Searchable bool `json:"-"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erc20Token contains info about ERC20 token held by an address
|
// Erc20Token contains info about ERC20 token held by an address
|
||||||
|
@ -158,7 +148,7 @@ type Tx struct {
|
||||||
Time int64 `json:"time,omitempty"`
|
Time int64 `json:"time,omitempty"`
|
||||||
Blocktime int64 `json:"blocktime"`
|
Blocktime int64 `json:"blocktime"`
|
||||||
Size int `json:"size,omitempty"`
|
Size int `json:"size,omitempty"`
|
||||||
ValueOutSat *Amount `json:"valueOut,omitempty"`
|
ValueOutSat *Amount `json:"value"`
|
||||||
ValueInSat *Amount `json:"valueIn,omitempty"`
|
ValueInSat *Amount `json:"valueIn,omitempty"`
|
||||||
FeesSat *Amount `json:"fees,omitempty"`
|
FeesSat *Amount `json:"fees,omitempty"`
|
||||||
Hex string `json:"hex,omitempty"`
|
Hex string `json:"hex,omitempty"`
|
||||||
|
|
|
@ -5,13 +5,19 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ScriptSigV1 is used for legacy api v1
|
||||||
|
type ScriptSigV1 struct {
|
||||||
|
Hex string `json:"hex,omitempty"`
|
||||||
|
Asm string `json:"asm,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// VinV1 is used for legacy api v1
|
// VinV1 is used for legacy api v1
|
||||||
type VinV1 struct {
|
type VinV1 struct {
|
||||||
Txid string `json:"txid"`
|
Txid string `json:"txid"`
|
||||||
Vout uint32 `json:"vout"`
|
Vout uint32 `json:"vout"`
|
||||||
Sequence int64 `json:"sequence,omitempty"`
|
Sequence int64 `json:"sequence,omitempty"`
|
||||||
N int `json:"n"`
|
N int `json:"n"`
|
||||||
ScriptSig ScriptSig `json:"scriptSig"`
|
ScriptSig ScriptSigV1 `json:"scriptSig"`
|
||||||
AddrDesc bchain.AddressDescriptor `json:"-"`
|
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||||
Addresses []string `json:"addresses"`
|
Addresses []string `json:"addresses"`
|
||||||
Searchable bool `json:"-"`
|
Searchable bool `json:"-"`
|
||||||
|
@ -19,16 +25,26 @@ type VinV1 struct {
|
||||||
ValueSat big.Int `json:"-"`
|
ValueSat big.Int `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScriptPubKeyV1 is used for legacy api v1
|
||||||
|
type ScriptPubKeyV1 struct {
|
||||||
|
Hex string `json:"hex,omitempty"`
|
||||||
|
Asm string `json:"asm,omitempty"`
|
||||||
|
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||||
|
Addresses []string `json:"addresses"`
|
||||||
|
Searchable bool `json:"-"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// VoutV1 is used for legacy api v1
|
// VoutV1 is used for legacy api v1
|
||||||
type VoutV1 struct {
|
type VoutV1 struct {
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
ValueSat big.Int `json:"-"`
|
ValueSat big.Int `json:"-"`
|
||||||
N int `json:"n"`
|
N int `json:"n"`
|
||||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
ScriptPubKey ScriptPubKeyV1 `json:"scriptPubKey"`
|
||||||
Spent bool `json:"spent"`
|
Spent bool `json:"spent"`
|
||||||
SpentTxID string `json:"spentTxId,omitempty"`
|
SpentTxID string `json:"spentTxId,omitempty"`
|
||||||
SpentIndex int `json:"spentIndex,omitempty"`
|
SpentIndex int `json:"spentIndex,omitempty"`
|
||||||
SpentHeight int `json:"spentHeight,omitempty"`
|
SpentHeight int `json:"spentHeight,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxV1 is used for legacy api v1
|
// TxV1 is used for legacy api v1
|
||||||
|
@ -92,10 +108,13 @@ func (w *Worker) TxToV1(tx *Tx) *TxV1 {
|
||||||
for i := range tx.Vin {
|
for i := range tx.Vin {
|
||||||
v := &tx.Vin[i]
|
v := &tx.Vin[i]
|
||||||
vinV1[i] = VinV1{
|
vinV1[i] = VinV1{
|
||||||
AddrDesc: v.AddrDesc,
|
AddrDesc: v.AddrDesc,
|
||||||
Addresses: v.Addresses,
|
Addresses: v.Addresses,
|
||||||
N: v.N,
|
N: v.N,
|
||||||
ScriptSig: v.ScriptSig,
|
ScriptSig: ScriptSigV1{
|
||||||
|
Asm: v.Asm,
|
||||||
|
Hex: v.Hex,
|
||||||
|
},
|
||||||
Searchable: v.Searchable,
|
Searchable: v.Searchable,
|
||||||
Sequence: v.Sequence,
|
Sequence: v.Sequence,
|
||||||
Txid: v.Txid,
|
Txid: v.Txid,
|
||||||
|
@ -108,14 +127,21 @@ func (w *Worker) TxToV1(tx *Tx) *TxV1 {
|
||||||
for i := range tx.Vout {
|
for i := range tx.Vout {
|
||||||
v := &tx.Vout[i]
|
v := &tx.Vout[i]
|
||||||
voutV1[i] = VoutV1{
|
voutV1[i] = VoutV1{
|
||||||
N: v.N,
|
N: v.N,
|
||||||
ScriptPubKey: v.ScriptPubKey,
|
ScriptPubKey: ScriptPubKeyV1{
|
||||||
Spent: v.Spent,
|
AddrDesc: v.AddrDesc,
|
||||||
SpentHeight: v.SpentHeight,
|
Addresses: v.Addresses,
|
||||||
SpentIndex: v.SpentIndex,
|
Asm: v.Asm,
|
||||||
SpentTxID: v.SpentTxID,
|
Hex: v.Hex,
|
||||||
Value: v.ValueSat.DecimalString(d),
|
Searchable: v.Searchable,
|
||||||
ValueSat: v.ValueSat.AsBigInt(),
|
Type: v.Type,
|
||||||
|
},
|
||||||
|
Spent: v.Spent,
|
||||||
|
SpentHeight: v.SpentHeight,
|
||||||
|
SpentIndex: v.SpentIndex,
|
||||||
|
SpentTxID: v.SpentTxID,
|
||||||
|
Value: v.ValueSat.DecimalString(d),
|
||||||
|
ValueSat: v.ValueSat.AsBigInt(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &TxV1{
|
return &TxV1{
|
||||||
|
|
|
@ -51,7 +51,7 @@ func (w *Worker) getAddressesFromVout(vout *bchain.Vout) (bchain.AddressDescript
|
||||||
// setSpendingTxToVout is helper function, that finds transaction that spent given output and sets it to the output
|
// setSpendingTxToVout is helper function, that finds transaction that spent given output and sets it to the output
|
||||||
// there is no direct index for the operation, it must be found using addresses -> txaddresses -> tx
|
// there is no direct index for the operation, it must be found using addresses -> txaddresses -> tx
|
||||||
func (w *Worker) setSpendingTxToVout(vout *Vout, txid string, height uint32) error {
|
func (w *Worker) setSpendingTxToVout(vout *Vout, txid string, height uint32) error {
|
||||||
err := w.db.GetAddrDescTransactions(vout.ScriptPubKey.AddrDesc, height, ^uint32(0), func(t string, index int32, isOutput bool) error {
|
err := w.db.GetAddrDescTransactions(vout.AddrDesc, height, ^uint32(0), func(t string, index int32, isOutput bool) error {
|
||||||
if isOutput == false {
|
if isOutput == false {
|
||||||
tsp, err := w.db.GetTxAddresses(t)
|
tsp, err := w.db.GetTxAddresses(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -137,7 +137,7 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height uint32,
|
||||||
vin.N = i
|
vin.N = i
|
||||||
vin.Vout = bchainVin.Vout
|
vin.Vout = bchainVin.Vout
|
||||||
vin.Sequence = int64(bchainVin.Sequence)
|
vin.Sequence = int64(bchainVin.Sequence)
|
||||||
vin.ScriptSig.Hex = bchainVin.ScriptSig.Hex
|
vin.Hex = bchainVin.ScriptSig.Hex
|
||||||
if w.chainType == bchain.ChainBitcoinType {
|
if w.chainType == bchain.ChainBitcoinType {
|
||||||
// bchainVin.Txid=="" is coinbase transaction
|
// bchainVin.Txid=="" is coinbase transaction
|
||||||
if bchainVin.Txid != "" {
|
if bchainVin.Txid != "" {
|
||||||
|
@ -195,8 +195,8 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height uint32,
|
||||||
vout.N = i
|
vout.N = i
|
||||||
vout.ValueSat = (*Amount)(&bchainVout.ValueSat)
|
vout.ValueSat = (*Amount)(&bchainVout.ValueSat)
|
||||||
valOutSat.Add(&valOutSat, &bchainVout.ValueSat)
|
valOutSat.Add(&valOutSat, &bchainVout.ValueSat)
|
||||||
vout.ScriptPubKey.Hex = bchainVout.ScriptPubKey.Hex
|
vout.Hex = bchainVout.ScriptPubKey.Hex
|
||||||
vout.ScriptPubKey.AddrDesc, vout.ScriptPubKey.Addresses, vout.ScriptPubKey.Searchable, err = w.getAddressesFromVout(bchainVout)
|
vout.AddrDesc, vout.Addresses, vout.Searchable, err = w.getAddressesFromVout(bchainVout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(2).Infof("getAddressesFromVout error %v, %v, output %v", err, bchainTx.Txid, bchainVout.N)
|
glog.V(2).Infof("getAddressesFromVout error %v, %v, output %v", err, bchainTx.Txid, bchainVout.N)
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height uint32,
|
||||||
if spendingTxs && vout.Spent {
|
if spendingTxs && vout.Spent {
|
||||||
err = w.setSpendingTxToVout(vout, bchainTx.Txid, height)
|
err = w.setSpendingTxToVout(vout, bchainTx.Txid, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("setSpendingTxToVout error %v, %v, output %v", err, vout.ScriptPubKey.AddrDesc, vout.N)
|
glog.Errorf("setSpendingTxToVout error %v, %v, output %v", err, vout.AddrDesc, vout.N)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,7 +337,7 @@ func (w *Worker) getAddressTxids(addrDesc bchain.AddressDescriptor, mempool bool
|
||||||
func (t *Tx) getAddrVoutValue(addrDesc bchain.AddressDescriptor) *big.Int {
|
func (t *Tx) getAddrVoutValue(addrDesc bchain.AddressDescriptor) *big.Int {
|
||||||
var val big.Int
|
var val big.Int
|
||||||
for _, vout := range t.Vout {
|
for _, vout := range t.Vout {
|
||||||
if bytes.Equal(vout.ScriptPubKey.AddrDesc, addrDesc) && vout.ValueSat != nil {
|
if bytes.Equal(vout.AddrDesc, addrDesc) && vout.ValueSat != nil {
|
||||||
val.Add(&val, (*big.Int)(vout.ValueSat))
|
val.Add(&val, (*big.Int)(vout.ValueSat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,7 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
|
||||||
vout.N = i
|
vout.N = i
|
||||||
vout.ValueSat = (*Amount)(&tao.ValueSat)
|
vout.ValueSat = (*Amount)(&tao.ValueSat)
|
||||||
valOutSat.Add(&valOutSat, &tao.ValueSat)
|
valOutSat.Add(&valOutSat, &tao.ValueSat)
|
||||||
vout.ScriptPubKey.Addresses, vout.ScriptPubKey.Searchable, err = tao.Addresses(w.chainParser)
|
vout.Addresses, vout.Searchable, err = tao.Addresses(w.chainParser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("tai.Addresses error %v, tx %v, output %v, tao %+v", err, txid, i, tao)
|
glog.Errorf("tai.Addresses error %v, tx %v, output %v, tao %+v", err, txid, i, tao)
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,7 +397,7 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) {
|
||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
body: []string{
|
||||||
`{"txid":"05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07","vin":[{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vout":2,"n":0,"scriptSig":{},"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"],"value":"9876"}],"vout":[{"value":"9000","n":0,"scriptPubKey":{"hex":"a914e921fc4912a315078f370d959f2c4f7b6d2a683c87","addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"]}}],"blockhash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","blockheight":225494,"confirmations":1,"time":22549400002,"blocktime":22549400002,"valueOut":"9000","valueIn":"9876","fees":"876"}`,
|
`{"txid":"05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07","vin":[{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vout":2,"n":0,"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"],"value":"9876"}],"vout":[{"value":"9000","n":0,"hex":"a914e921fc4912a315078f370d959f2c4f7b6d2a683c87","addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"]}],"blockhash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6","blockheight":225494,"confirmations":1,"time":22549400002,"blocktime":22549400002,"value":"9000","valueIn":"9876","fees":"876"}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -306,7 +306,7 @@ func txToResTx(tx *api.Tx) resTx {
|
||||||
for i := range tx.Vin {
|
for i := range tx.Vin {
|
||||||
vin := &tx.Vin[i]
|
vin := &tx.Vin[i]
|
||||||
txid := vin.Txid
|
txid := vin.Txid
|
||||||
script := vin.ScriptSig.Hex
|
script := vin.Hex
|
||||||
input := txInputs{
|
input := txInputs{
|
||||||
Txid: &txid,
|
Txid: &txid,
|
||||||
Script: &script,
|
Script: &script,
|
||||||
|
@ -323,13 +323,13 @@ func txToResTx(tx *api.Tx) resTx {
|
||||||
outputs := make([]txOutputs, len(tx.Vout))
|
outputs := make([]txOutputs, len(tx.Vout))
|
||||||
for i := range tx.Vout {
|
for i := range tx.Vout {
|
||||||
vout := &tx.Vout[i]
|
vout := &tx.Vout[i]
|
||||||
script := vout.ScriptPubKey.Hex
|
script := vout.Hex
|
||||||
output := txOutputs{
|
output := txOutputs{
|
||||||
Satoshis: (*big.Int)(vout.ValueSat).Int64(),
|
Satoshis: (*big.Int)(vout.ValueSat).Int64(),
|
||||||
Script: &script,
|
Script: &script,
|
||||||
}
|
}
|
||||||
if len(vout.ScriptPubKey.Addresses) > 0 {
|
if len(vout.Addresses) > 0 {
|
||||||
a := vout.ScriptPubKey.Addresses[0]
|
a := vout.Addresses[0]
|
||||||
output.Address = &a
|
output.Address = &a
|
||||||
}
|
}
|
||||||
outputs[i] = output
|
outputs[i] = output
|
||||||
|
@ -412,7 +412,7 @@ func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res r
|
||||||
}
|
}
|
||||||
for i := range tx.Vout {
|
for i := range tx.Vout {
|
||||||
vout := &tx.Vout[i]
|
vout := &tx.Vout[i]
|
||||||
a := addressInSlice(vout.ScriptPubKey.Addresses, addr)
|
a := addressInSlice(vout.Addresses, addr)
|
||||||
if a != "" {
|
if a != "" {
|
||||||
hi := ads[a]
|
hi := ads[a]
|
||||||
if hi == nil {
|
if hi == nil {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
{{if and (ne $a $addr) $vin.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
|
{{if and (ne $a $addr) $vin.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
|
||||||
</span>
|
</span>
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
<span class="float-left">{{- if $vin.ScriptSig.Hex -}}Unparsed address{{- else -}}No Inputs (Newly Generated Coins){{- end -}}</span>
|
<span class="float-left">{{- if $vin.Hex -}}Unparsed address{{- else -}}No Inputs (Newly Generated Coins){{- end -}}</span>
|
||||||
{{- end -}}{{- if $vin.Addresses -}}
|
{{- end -}}{{- if $vin.Addresses -}}
|
||||||
<span class="float-right{{if stringInSlice $addr $vin.Addresses}} text-danger{{end}}">{{formatAmount $vin.ValueSat}} {{$cs}}</span>
|
<span class="float-right{{if stringInSlice $addr $vin.Addresses}} text-danger{{end}}">{{formatAmount $vin.ValueSat}} {{$cs}}</span>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
@ -51,14 +51,14 @@
|
||||||
{{- range $vout := $tx.Vout -}}
|
{{- range $vout := $tx.Vout -}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{- range $a := $vout.ScriptPubKey.Addresses -}}
|
{{- range $a := $vout.Addresses -}}
|
||||||
<span class="ellipsis float-left">
|
<span class="ellipsis float-left">
|
||||||
{{- if and (ne $a $addr) $vout.ScriptPubKey.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
|
{{- if and (ne $a $addr) $vout.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
|
||||||
</span>
|
</span>
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
<span class="float-left">Unparsed address</span>
|
<span class="float-left">Unparsed address</span>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<span class="float-right{{if stringInSlice $addr $vout.ScriptPubKey.Addresses}} text-success{{end}}">
|
<span class="float-right{{if stringInSlice $addr $vout.Addresses}} text-success{{end}}">
|
||||||
{{formatAmount $vout.ValueSat}} {{$cs}} {{if $vout.Spent}}<a class="text-danger" href="{{if $vout.SpentTxID}}/tx/{{$vout.SpentTxID}}{{else}}/spending/{{$tx.Txid}}/{{$vout.N}}{{end}}" title="Spent">➡</a>{{else -}}
|
{{formatAmount $vout.ValueSat}} {{$cs}} {{if $vout.Spent}}<a class="text-danger" href="{{if $vout.SpentTxID}}/tx/{{$vout.SpentTxID}}{{else}}/spending/{{$tx.Txid}}/{{$vout.N}}{{end}}" title="Spent">➡</a>{{else -}}
|
||||||
<span class="text-success" title="Unspent"> <b>×</b></span>
|
<span class="text-success" title="Unspent"> <b>×</b></span>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
|
@ -47,9 +47,9 @@
|
||||||
{{- range $vout := $tx.Vout -}}
|
{{- range $vout := $tx.Vout -}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{- range $a := $vout.ScriptPubKey.Addresses -}}
|
{{- range $a := $vout.Addresses -}}
|
||||||
<span class="ellipsis float-left">
|
<span class="ellipsis float-left">
|
||||||
{{- if and (ne $a $addr) $vout.ScriptPubKey.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
|
{{- if and (ne $a $addr) $vout.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{- end -}}
|
||||||
</span>
|
</span>
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
<span class="float-left">Unparsed address</span>
|
<span class="float-left">Unparsed address</span>
|
||||||
|
|
Loading…
Reference in New Issue