Process OP_RETURN script in Bcash

pull/56/head
Martin Boehm 2018-09-03 14:10:28 +02:00
parent fe4b366875
commit 1b69a62ab8
4 changed files with 109 additions and 59 deletions

View File

@ -223,7 +223,7 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
valInSat.Add(&valInSat, &vin.ValueSat)
vin.Addresses, vin.Searchable, err = tai.Addresses(w.chainParser)
if err != nil {
glog.Errorf("tai.Addresses error %v, tx %v, input %v", err, txid, i)
glog.Errorf("tai.Addresses error %v, tx %v, input %v, tai %+v", err, txid, i, tai)
}
}
vouts := make([]Vout, len(ta.Outputs))
@ -236,7 +236,7 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
valOutSat.Add(&valOutSat, &vout.ValueSat)
vout.ScriptPubKey.Addresses, vout.ScriptPubKey.Searchable, err = tao.Addresses(w.chainParser)
if err != nil {
glog.Errorf("tai.Addresses error %v, tx %v, output %v", err, txid, i)
glog.Errorf("tai.Addresses error %v, tx %v, output %v, tao %+v", err, txid, i, tao)
}
}
// for coinbase transactions valIn is 0

View File

@ -126,6 +126,15 @@ func isCashAddr(addr string) bool {
func (p *BCashParser) outputScriptToAddresses(script []byte) ([]string, bool, error) {
a, err := bchutil.ExtractPkScriptAddrs(script, p.Params)
if err != nil {
// do not return unknown script type error as error
if err.Error() == "unknown script type" {
// try OP_RETURN script
or := btc.TryParseOPReturn(script)
if or != "" {
return []string{or}, false, nil
}
return []string{}, false, nil
}
return nil, false, err
}
// EncodeAddress returns CashAddr address

View File

@ -82,53 +82,85 @@ func Test_GetAddrDescFromAddress(t *testing.T) {
func Test_GetAddressesFromAddrDesc(t *testing.T) {
mainParserCashAddr, mainParserLegacy, testParserCashAddr, testParserLegacy := setupParsers(t)
tests := []struct {
name string
parser *BCashParser
addresses []string
hex string
wantErr bool
name string
parser *BCashParser
addresses []string
searchable bool
hex string
wantErr bool
}{
{
name: "test-P2PKH-0",
parser: testParserLegacy,
addresses: []string{"mnnAKPTSrWjgoi3uEYaQkHA1QEC5btFeBr"},
hex: "76a9144fa927fd3bcf57d4e3c582c3d2eb2bd3df8df47c88ac",
wantErr: false,
name: "test-P2PKH-0",
parser: testParserLegacy,
addresses: []string{"mnnAKPTSrWjgoi3uEYaQkHA1QEC5btFeBr"},
searchable: true,
hex: "76a9144fa927fd3bcf57d4e3c582c3d2eb2bd3df8df47c88ac",
wantErr: false,
},
{
name: "test-P2PKH-1",
parser: testParserCashAddr,
addresses: []string{"bchtest:qp86jfla8084048rckpv85ht90falr050s03ejaesm"},
hex: "76a9144fa927fd3bcf57d4e3c582c3d2eb2bd3df8df47c88ac",
wantErr: false,
name: "test-P2PKH-1",
parser: testParserCashAddr,
addresses: []string{"bchtest:qp86jfla8084048rckpv85ht90falr050s03ejaesm"},
searchable: true,
hex: "76a9144fa927fd3bcf57d4e3c582c3d2eb2bd3df8df47c88ac",
wantErr: false,
},
{
name: "main-P2PKH-0",
parser: mainParserLegacy,
addresses: []string{"129HiRqekqPVucKy2M8zsqvafGgKypciPp"},
hex: "76a9140c8967e6382c7a2ca64d8e850bfc99b7736e1a0d88ac",
wantErr: false,
name: "main-P2PKH-0",
parser: mainParserLegacy,
addresses: []string{"129HiRqekqPVucKy2M8zsqvafGgKypciPp"},
searchable: true,
hex: "76a9140c8967e6382c7a2ca64d8e850bfc99b7736e1a0d88ac",
wantErr: false,
},
{
name: "main-P2PKH-0",
parser: mainParserCashAddr,
addresses: []string{"bitcoincash:qqxgjelx8qk85t9xfk8g2zlunxmhxms6p55xarv2r5"},
hex: "76a9140c8967e6382c7a2ca64d8e850bfc99b7736e1a0d88ac",
wantErr: false,
name: "main-P2PKH-0",
parser: mainParserCashAddr,
addresses: []string{"bitcoincash:qqxgjelx8qk85t9xfk8g2zlunxmhxms6p55xarv2r5"},
searchable: true,
hex: "76a9140c8967e6382c7a2ca64d8e850bfc99b7736e1a0d88ac",
wantErr: false,
},
{
name: "main-P2SH-0",
parser: mainParserLegacy,
addresses: []string{"3EBEFWPtDYWCNszQ7etoqtWmmygccayLiH"},
hex: "a91488f772450c830a30eddfdc08a93d5f2ae1a30e1787",
wantErr: false,
name: "main-P2SH-0",
parser: mainParserLegacy,
addresses: []string{"3EBEFWPtDYWCNszQ7etoqtWmmygccayLiH"},
searchable: true,
hex: "a91488f772450c830a30eddfdc08a93d5f2ae1a30e1787",
wantErr: false,
},
{
name: "main-P2SH-1",
parser: mainParserCashAddr,
addresses: []string{"bitcoincash:pzy0wuj9pjps5v8dmlwq32fatu4wrgcwzuayq5nfhh"},
hex: "a91488f772450c830a30eddfdc08a93d5f2ae1a30e1787",
wantErr: false,
name: "main-P2SH-1",
parser: mainParserCashAddr,
addresses: []string{"bitcoincash:pzy0wuj9pjps5v8dmlwq32fatu4wrgcwzuayq5nfhh"},
searchable: true,
hex: "a91488f772450c830a30eddfdc08a93d5f2ae1a30e1787",
wantErr: false,
},
{
name: "OP_RETURN ascii",
parser: mainParserCashAddr,
addresses: []string{"OP_RETURN (ahoj)"},
searchable: false,
hex: "6a0461686f6a",
wantErr: false,
},
{
name: "OP_RETURN hex",
parser: mainParserCashAddr,
addresses: []string{"OP_RETURN 07 2020f1686f6a20"},
searchable: false,
hex: "6a072020f1686f6a20",
wantErr: false,
},
{
name: "empty",
parser: mainParserCashAddr,
addresses: []string{},
searchable: false,
hex: "",
wantErr: false,
},
}
@ -143,8 +175,8 @@ func Test_GetAddressesFromAddrDesc(t *testing.T) {
if !reflect.DeepEqual(got, tt.addresses) {
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.addresses)
}
if !reflect.DeepEqual(got2, true) {
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, true)
if !reflect.DeepEqual(got2, tt.searchable) {
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.searchable)
}
})
}

View File

@ -84,6 +84,31 @@ func (p *BitcoinParser) addressToOutputScript(address string) ([]byte, error) {
return script, nil
}
// TryParseOPReturn tries to process OP_RETURN script and return its string representation
func TryParseOPReturn(script []byte) string {
if len(script) > 1 && script[0] == txscript.OP_RETURN {
l := int(script[1])
data := script[2:]
if l == len(data) {
isASCII := true
for _, c := range data {
if c < 32 || c > 127 {
isASCII = false
break
}
}
var ed string
if isASCII {
ed = "(" + string(data) + ")"
} else {
ed = hex.EncodeToString([]byte{byte(l)}) + " " + hex.EncodeToString(data)
}
return "OP_RETURN " + ed
}
}
return ""
}
// outputScriptToAddresses converts ScriptPubKey to bitcoin addresses
func (p *BitcoinParser) outputScriptToAddresses(script []byte) ([]string, bool, error) {
sc, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params)
@ -97,26 +122,10 @@ func (p *BitcoinParser) outputScriptToAddresses(script []byte) ([]string, bool,
var s bool
if sc != txscript.NonStandardTy && sc != txscript.NullDataTy {
s = true
} else {
if len(script) > 1 && script[0] == txscript.OP_RETURN && len(rv) == 0 {
l := int(script[1])
data := script[2:]
if l == len(data) {
isASCII := true
for _, c := range data {
if c < 32 || c > 127 {
isASCII = false
break
}
}
var ed string
if isASCII {
ed = "(" + string(data) + ")"
} else {
ed = hex.EncodeToString([]byte{byte(l)}) + " " + hex.EncodeToString(data)
}
rv = []string{"OP_RETURN " + ed}
}
} else if len(rv) == 0 {
or := TryParseOPReturn(script)
if or != "" {
rv = []string{or}
}
}
return rv, s, nil