Process OP_RETURN script in Bcash
parent
fe4b366875
commit
1b69a62ab8
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue