use abstract address for Vout
parent
a8e603d945
commit
b88a88ad55
|
@ -2,6 +2,7 @@ package bchain
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/juju/errors"
|
||||
|
@ -149,6 +150,9 @@ func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) {
|
|||
},
|
||||
Value: pto.Value,
|
||||
}
|
||||
if len(pto.Addresses) == 1 {
|
||||
vout[i].Address = NewBaseAddress(pto.Addresses[0])
|
||||
}
|
||||
}
|
||||
tx := Tx{
|
||||
Blocktime: int64(pt.Blocktime),
|
||||
|
@ -161,3 +165,22 @@ func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) {
|
|||
}
|
||||
return &tx, pt.Height, nil
|
||||
}
|
||||
|
||||
type baseAddress struct {
|
||||
addr string
|
||||
}
|
||||
|
||||
func NewBaseAddress(addr string) Address {
|
||||
return &baseAddress{addr: addr}
|
||||
}
|
||||
|
||||
func (a baseAddress) String() string {
|
||||
return a.addr
|
||||
}
|
||||
|
||||
func (a baseAddress) EncodeAddress(format uint8) (string, error) {
|
||||
if format != 0 {
|
||||
return "", fmt.Errorf("Unknown address format: %d", format)
|
||||
}
|
||||
return a.addr, nil
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package bch
|
||||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/cpacia/bchutil"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
var prefixes []string
|
||||
|
@ -51,7 +54,7 @@ func (p *BCashParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
|||
|
||||
// AddressToOutputScript converts bitcoin address to ScriptPubKey
|
||||
func (p *BCashParser) AddressToOutputScript(address string) ([]byte, error) {
|
||||
if strings.Contains(address, ":") {
|
||||
if isCashAddr(address) {
|
||||
da, err := bchutil.DecodeAddress(address, p.Params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -73,3 +76,75 @@ func (p *BCashParser) AddressToOutputScript(address string) ([]byte, error) {
|
|||
return script, nil
|
||||
}
|
||||
}
|
||||
|
||||
func isCashAddr(addr string) bool {
|
||||
slice := strings.Split(addr, ":")
|
||||
if len(slice) != 2 {
|
||||
return false
|
||||
}
|
||||
for _, prefix := range prefixes {
|
||||
if slice[0] == prefix {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *BCashParser) UnpackTx(buf []byte) (tx *bchain.Tx, height uint32, err error) {
|
||||
tx, height, err = p.BitcoinParser.UnpackTx(buf)
|
||||
|
||||
for i, vout := range tx.Vout {
|
||||
if len(vout.ScriptPubKey.Addresses) == 1 {
|
||||
tx.Vout[i].Address = &bcashAddress{
|
||||
addr: vout.ScriptPubKey.Addresses[0],
|
||||
net: p.Params,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type bcashAddress struct {
|
||||
addr string
|
||||
net *chaincfg.Params
|
||||
}
|
||||
|
||||
func (a *bcashAddress) String() string {
|
||||
return a.addr
|
||||
}
|
||||
|
||||
type AddressFormat = uint8
|
||||
|
||||
const (
|
||||
LegacyAddress AddressFormat = iota
|
||||
CashAddress
|
||||
)
|
||||
|
||||
func (a *bcashAddress) EncodeAddress(format AddressFormat) (string, error) {
|
||||
switch format {
|
||||
case LegacyAddress:
|
||||
return a.String(), nil
|
||||
case CashAddress:
|
||||
da, err := btcutil.DecodeAddress(a.addr, a.net)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var ca btcutil.Address
|
||||
switch da := da.(type) {
|
||||
case *btcutil.AddressPubKeyHash:
|
||||
ca, err = bchutil.NewCashAddressPubKeyHash(da.Hash160()[:], a.net)
|
||||
case *btcutil.AddressScriptHash:
|
||||
ca, err = bchutil.NewCashAddressScriptHash(da.Hash160()[:], a.net)
|
||||
default:
|
||||
err = fmt.Errorf("Unknown address type: %T", da)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ca.String(), nil
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("Unknown address format: %d", format)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,5 +169,12 @@ func (p *BitcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
|||
return nil, 0, err
|
||||
}
|
||||
tx.Blocktime = bt
|
||||
|
||||
for i, vout := range tx.Vout {
|
||||
if len(vout.ScriptPubKey.Addresses) == 1 {
|
||||
tx.Vout[i].Address = bchain.NewBaseAddress(vout.ScriptPubKey.Addresses[0])
|
||||
}
|
||||
}
|
||||
|
||||
return tx, height, nil
|
||||
}
|
||||
|
|
|
@ -37,10 +37,16 @@ type ScriptPubKey struct {
|
|||
Addresses []string `json:"addresses,omitempty"`
|
||||
}
|
||||
|
||||
type Address interface {
|
||||
String() string
|
||||
EncodeAddress(format uint8) (string, error)
|
||||
}
|
||||
|
||||
type Vout struct {
|
||||
Value float64 `json:"value"`
|
||||
N uint32 `json:"n"`
|
||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
||||
Address Address
|
||||
}
|
||||
|
||||
// Tx is blockchain transaction
|
||||
|
|
Loading…
Reference in New Issue