use abstract address for Vout

indexv1
Jakub Matys 2018-04-19 00:49:56 +01:00
parent a8e603d945
commit b88a88ad55
4 changed files with 112 additions and 1 deletions

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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