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)
|
||||
}
|
||||
|
||||
// ScriptSig contains input script
|
||||
type ScriptSig struct {
|
||||
Hex string `json:"hex,omitempty"`
|
||||
Asm string `json:"asm,omitempty"`
|
||||
}
|
||||
|
||||
// Vin contains information about single transaction input
|
||||
type Vin struct {
|
||||
Txid string `json:"txid,omitempty"`
|
||||
Vout uint32 `json:"vout,omitempty"`
|
||||
Sequence int64 `json:"sequence,omitempty"`
|
||||
N int `json:"n"`
|
||||
ScriptSig ScriptSig `json:"scriptSig"`
|
||||
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||
Addresses []string `json:"addresses"`
|
||||
Searchable bool `json:"-"`
|
||||
ValueSat *Amount `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// ScriptPubKey contains output script and addresses derived from it
|
||||
type ScriptPubKey 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"`
|
||||
}
|
||||
|
||||
// Vout contains information about single transaction output
|
||||
type Vout struct {
|
||||
ValueSat *Amount `json:"value,omitempty"`
|
||||
N int `json:"n"`
|
||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
||||
Spent bool `json:"spent,omitempty"`
|
||||
SpentTxID string `json:"spentTxId,omitempty"`
|
||||
SpentIndex int `json:"spentIndex,omitempty"`
|
||||
SpentHeight int `json:"spentHeight,omitempty"`
|
||||
ValueSat *Amount `json:"value,omitempty"`
|
||||
N int `json:"n"`
|
||||
Spent bool `json:"spent,omitempty"`
|
||||
SpentTxID string `json:"spentTxId,omitempty"`
|
||||
SpentIndex int `json:"spentIndex,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
|
||||
|
@ -158,7 +148,7 @@ type Tx struct {
|
|||
Time int64 `json:"time,omitempty"`
|
||||
Blocktime int64 `json:"blocktime"`
|
||||
Size int `json:"size,omitempty"`
|
||||
ValueOutSat *Amount `json:"valueOut,omitempty"`
|
||||
ValueOutSat *Amount `json:"value"`
|
||||
ValueInSat *Amount `json:"valueIn,omitempty"`
|
||||
FeesSat *Amount `json:"fees,omitempty"`
|
||||
Hex string `json:"hex,omitempty"`
|
||||
|
|
|
@ -5,13 +5,19 @@ import (
|
|||
"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
|
||||
type VinV1 struct {
|
||||
Txid string `json:"txid"`
|
||||
Vout uint32 `json:"vout"`
|
||||
Sequence int64 `json:"sequence,omitempty"`
|
||||
N int `json:"n"`
|
||||
ScriptSig ScriptSig `json:"scriptSig"`
|
||||
ScriptSig ScriptSigV1 `json:"scriptSig"`
|
||||
AddrDesc bchain.AddressDescriptor `json:"-"`
|
||||
Addresses []string `json:"addresses"`
|
||||
Searchable bool `json:"-"`
|
||||
|
@ -19,16 +25,26 @@ type VinV1 struct {
|
|||
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
|
||||
type VoutV1 struct {
|
||||
Value string `json:"value"`
|
||||
ValueSat big.Int `json:"-"`
|
||||
N int `json:"n"`
|
||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
||||
Spent bool `json:"spent"`
|
||||
SpentTxID string `json:"spentTxId,omitempty"`
|
||||
SpentIndex int `json:"spentIndex,omitempty"`
|
||||
SpentHeight int `json:"spentHeight,omitempty"`
|
||||
Value string `json:"value"`
|
||||
ValueSat big.Int `json:"-"`
|
||||
N int `json:"n"`
|
||||
ScriptPubKey ScriptPubKeyV1 `json:"scriptPubKey"`
|
||||
Spent bool `json:"spent"`
|
||||
SpentTxID string `json:"spentTxId,omitempty"`
|
||||
SpentIndex int `json:"spentIndex,omitempty"`
|
||||
SpentHeight int `json:"spentHeight,omitempty"`
|
||||
}
|
||||
|
||||
// TxV1 is used for legacy api v1
|
||||
|
@ -92,10 +108,13 @@ func (w *Worker) TxToV1(tx *Tx) *TxV1 {
|
|||
for i := range tx.Vin {
|
||||
v := &tx.Vin[i]
|
||||
vinV1[i] = VinV1{
|
||||
AddrDesc: v.AddrDesc,
|
||||
Addresses: v.Addresses,
|
||||
N: v.N,
|
||||
ScriptSig: v.ScriptSig,
|
||||
AddrDesc: v.AddrDesc,
|
||||
Addresses: v.Addresses,
|
||||
N: v.N,
|
||||
ScriptSig: ScriptSigV1{
|
||||
Asm: v.Asm,
|
||||
Hex: v.Hex,
|
||||
},
|
||||
Searchable: v.Searchable,
|
||||
Sequence: v.Sequence,
|
||||
Txid: v.Txid,
|
||||
|
@ -108,14 +127,21 @@ func (w *Worker) TxToV1(tx *Tx) *TxV1 {
|
|||
for i := range tx.Vout {
|
||||
v := &tx.Vout[i]
|
||||
voutV1[i] = VoutV1{
|
||||
N: v.N,
|
||||
ScriptPubKey: v.ScriptPubKey,
|
||||
Spent: v.Spent,
|
||||
SpentHeight: v.SpentHeight,
|
||||
SpentIndex: v.SpentIndex,
|
||||
SpentTxID: v.SpentTxID,
|
||||
Value: v.ValueSat.DecimalString(d),
|
||||
ValueSat: v.ValueSat.AsBigInt(),
|
||||
N: v.N,
|
||||
ScriptPubKey: ScriptPubKeyV1{
|
||||
AddrDesc: v.AddrDesc,
|
||||
Addresses: v.Addresses,
|
||||
Asm: v.Asm,
|
||||
Hex: v.Hex,
|
||||
Searchable: v.Searchable,
|
||||
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{
|
||||
|
|
|
@ -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
|
||||
// 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 {
|
||||
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 {
|
||||
tsp, err := w.db.GetTxAddresses(t)
|
||||
if err != nil {
|
||||
|
@ -137,7 +137,7 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height uint32,
|
|||
vin.N = i
|
||||
vin.Vout = bchainVin.Vout
|
||||
vin.Sequence = int64(bchainVin.Sequence)
|
||||
vin.ScriptSig.Hex = bchainVin.ScriptSig.Hex
|
||||
vin.Hex = bchainVin.ScriptSig.Hex
|
||||
if w.chainType == bchain.ChainBitcoinType {
|
||||
// bchainVin.Txid=="" is coinbase transaction
|
||||
if bchainVin.Txid != "" {
|
||||
|
@ -195,8 +195,8 @@ func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height uint32,
|
|||
vout.N = i
|
||||
vout.ValueSat = (*Amount)(&bchainVout.ValueSat)
|
||||
valOutSat.Add(&valOutSat, &bchainVout.ValueSat)
|
||||
vout.ScriptPubKey.Hex = bchainVout.ScriptPubKey.Hex
|
||||
vout.ScriptPubKey.AddrDesc, vout.ScriptPubKey.Addresses, vout.ScriptPubKey.Searchable, err = w.getAddressesFromVout(bchainVout)
|
||||
vout.Hex = bchainVout.ScriptPubKey.Hex
|
||||
vout.AddrDesc, vout.Addresses, vout.Searchable, err = w.getAddressesFromVout(bchainVout)
|
||||
if err != nil {
|
||||
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 {
|
||||
err = w.setSpendingTxToVout(vout, bchainTx.Txid, height)
|
||||
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 {
|
||||
var val big.Int
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
|
|||
vout.N = i
|
||||
vout.ValueSat = (*Amount)(&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 {
|
||||
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,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
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 {
|
||||
vin := &tx.Vin[i]
|
||||
txid := vin.Txid
|
||||
script := vin.ScriptSig.Hex
|
||||
script := vin.Hex
|
||||
input := txInputs{
|
||||
Txid: &txid,
|
||||
Script: &script,
|
||||
|
@ -323,13 +323,13 @@ func txToResTx(tx *api.Tx) resTx {
|
|||
outputs := make([]txOutputs, len(tx.Vout))
|
||||
for i := range tx.Vout {
|
||||
vout := &tx.Vout[i]
|
||||
script := vout.ScriptPubKey.Hex
|
||||
script := vout.Hex
|
||||
output := txOutputs{
|
||||
Satoshis: (*big.Int)(vout.ValueSat).Int64(),
|
||||
Script: &script,
|
||||
}
|
||||
if len(vout.ScriptPubKey.Addresses) > 0 {
|
||||
a := vout.ScriptPubKey.Addresses[0]
|
||||
if len(vout.Addresses) > 0 {
|
||||
a := vout.Addresses[0]
|
||||
output.Address = &a
|
||||
}
|
||||
outputs[i] = output
|
||||
|
@ -412,7 +412,7 @@ func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res r
|
|||
}
|
||||
for i := range tx.Vout {
|
||||
vout := &tx.Vout[i]
|
||||
a := addressInSlice(vout.ScriptPubKey.Addresses, addr)
|
||||
a := addressInSlice(vout.Addresses, addr)
|
||||
if a != "" {
|
||||
hi := ads[a]
|
||||
if hi == nil {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{{if and (ne $a $addr) $vin.Searchable}}<a href="/address/{{$a}}">{{$a}}</a>{{else}}{{$a}}{{end}}
|
||||
</span>
|
||||
{{- 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 -}}
|
||||
<span class="float-right{{if stringInSlice $addr $vin.Addresses}} text-danger{{end}}">{{formatAmount $vin.ValueSat}} {{$cs}}</span>
|
||||
{{- end -}}
|
||||
|
@ -51,14 +51,14 @@
|
|||
{{- range $vout := $tx.Vout -}}
|
||||
<tr>
|
||||
<td>
|
||||
{{- range $a := $vout.ScriptPubKey.Addresses -}}
|
||||
{{- range $a := $vout.Addresses -}}
|
||||
<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>
|
||||
{{- else -}}
|
||||
<span class="float-left">Unparsed address</span>
|
||||
{{- 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 -}}
|
||||
<span class="text-success" title="Unspent"> <b>×</b></span>
|
||||
{{- end -}}
|
||||
|
|
|
@ -47,9 +47,9 @@
|
|||
{{- range $vout := $tx.Vout -}}
|
||||
<tr>
|
||||
<td>
|
||||
{{- range $a := $vout.ScriptPubKey.Addresses -}}
|
||||
{{- range $a := $vout.Addresses -}}
|
||||
<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>
|
||||
{{- else -}}
|
||||
<span class="float-left">Unparsed address</span>
|
||||
|
|
Loading…
Reference in New Issue