diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 405fd867..2426974e 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -430,6 +430,9 @@ type ScriptPubKeyResult struct { Hex string `json:"hex,omitempty"` ReqSigs int32 `json:"reqSigs,omitempty"` Type string `json:"type"` + SubType string `json:"subtype"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` Addresses []string `json:"addresses,omitempty"` } @@ -588,6 +591,8 @@ func (v *Vin) MarshalJSON() ([]byte, error) { type PrevOut struct { Addresses []string `json:"addresses,omitempty"` Value float64 `json:"value"` + IsClaim bool `json:"isclaim"` + IsSupport bool `json:"issupport"` } // VinPrevOut is like Vin except it includes PrevOut. It is used by searchrawtransaction diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index 72dcd8d7..af47ccab 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -70,7 +70,7 @@ func TestChainSvrCustomResults(t *testing.T) { }, Sequence: 4294967295, }, - expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0},"sequence":4294967295}`, + expected: `{"txid":"123","vout":1,"scriptSig":{"asm":"0","hex":"00"},"prevOut":{"addresses":["addr1"],"value":0,"isclaim":false,"issupport":false},"sequence":4294967295}`, }, } diff --git a/rpcserver.go b/rpcserver.go index 4502a4cd..3339ca4f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -701,11 +701,12 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap // script doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(v.PkScript) + script := txscript.StripClaimScriptPrefix(v.PkScript) + // Ignore the error here since an error means the script // couldn't parse and there is no additional information about // it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs( - v.PkScript, chainParams) + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, chainParams) // Encode the addresses while checking if the address passes the // filter when needed. @@ -735,9 +736,19 @@ func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap vout.ScriptPubKey.Addresses = encodedAddrs vout.ScriptPubKey.Asm = disbuf vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript) - vout.ScriptPubKey.Type = scriptClass.String() vout.ScriptPubKey.ReqSigs = int32(reqSigs) + if len(script) < len(v.PkScript) { + vout.ScriptPubKey.IsClaim = v.PkScript[0] == txscript.OP_CLAIMNAME || v.PkScript[0] == txscript.OP_UPDATECLAIM + vout.ScriptPubKey.IsSupport = v.PkScript[0] == txscript.OP_SUPPORTCLAIM + vout.ScriptPubKey.SubType = scriptClass.String() + vout.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + vout.ScriptPubKey.Type = scriptClass.String() + } + + // TODO here: isclaim, issupport, subtype, + voutList = append(voutList, vout) } @@ -2778,10 +2789,12 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i // doesn't fully parse, so ignore the error here. disbuf, _ := txscript.DisasmString(pkScript) + script := txscript.StripClaimScriptPrefix(pkScript) + // Get further info about the script. // Ignore the error here since an error means the script couldn't parse // and there is no additional information about it anyways. - scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, + scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, s.cfg.ChainParams) addresses := make([]string, len(addrs)) for i, addr := range addrs { @@ -2796,11 +2809,20 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i Asm: disbuf, Hex: hex.EncodeToString(pkScript), ReqSigs: int32(reqSigs), - Type: scriptClass.String(), Addresses: addresses, }, Coinbase: isCoinbase, } + + if len(script) < len(pkScript) { + txOutReply.ScriptPubKey.IsClaim = pkScript[0] == txscript.OP_CLAIMNAME || pkScript[0] == txscript.OP_UPDATECLAIM + txOutReply.ScriptPubKey.IsSupport = pkScript[0] == txscript.OP_SUPPORTCLAIM + txOutReply.ScriptPubKey.SubType = scriptClass.String() + txOutReply.ScriptPubKey.Type = txscript.ScriptClass.String(0) + } else { + txOutReply.ScriptPubKey.Type = scriptClass.String() + } + return txOutReply, nil } @@ -3012,7 +3034,7 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P // Ignore the error here since an error means the script // couldn't parse and there is no additional information about // it anyways. - _, addrs, _, _ := txscript.ExtractPkScriptAddrs( + class, addrs, _, _ := txscript.ExtractPkScriptAddrs( originTxOut.PkScript, chainParams) // Encode the addresses while checking if the address passes the @@ -3049,6 +3071,9 @@ func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.P vinListEntry.PrevOut = &btcjson.PrevOut{ Addresses: encodedAddrs, Value: btcutil.Amount(originTxOut.Value).ToBTC(), + IsClaim: class == txscript.NonStandardTy && + (originTxOut.PkScript[0] == txscript.OP_CLAIMNAME || originTxOut.PkScript[0] == txscript.OP_UPDATECLAIM), + IsSupport: class == txscript.NonStandardTy && originTxOut.PkScript[0] == txscript.OP_SUPPORTCLAIM, } } } diff --git a/txscript/nameclaim.go b/txscript/nameclaim.go index 0c473848..b4630037 100644 --- a/txscript/nameclaim.go +++ b/txscript/nameclaim.go @@ -56,6 +56,9 @@ func UpdateClaimScript(name string, claimID []byte, value string) ([]byte, error // DecodeClaimScript ... func DecodeClaimScript(script []byte) (*ClaimScript, error) { + if len(script) == 0 { + return nil, ErrNotClaimScript + } op := script[0] if op != OP_CLAIMNAME && op != OP_SUPPORTCLAIM && op != OP_UPDATECLAIM { return nil, ErrNotClaimScript diff --git a/txscript/sign.go b/txscript/sign.go index 42af9686..348a109b 100644 --- a/txscript/sign.go +++ b/txscript/sign.go @@ -157,7 +157,9 @@ func sign(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB) ([]byte, ScriptClass, []btcutil.Address, int, error) { - class, addresses, nrequired, err := ExtractPkScriptAddrs(subScript, + subSubScript := StripClaimScriptPrefix(subScript) + + class, addresses, nrequired, err := ExtractPkScriptAddrs(subSubScript, chainParams) if err != nil { return nil, NonStandardTy, nil, 0, err diff --git a/txscript/standard.go b/txscript/standard.go index 2cad218e..0acce5bc 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -543,9 +543,11 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script var addrs []btcutil.Address var requiredSigs int + stripped := StripClaimScriptPrefix(pkScript) + // No valid addresses or required signatures if the script doesn't // parse. - pops, err := parseScript(pkScript) + pops, err := parseScript(stripped) if err != nil { return NonStandardTy, nil, 0, err } @@ -639,6 +641,10 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script // nonstandard transactions. } + if len(stripped) < len(pkScript) { + scriptClass = NonStandardTy + } + return scriptClass, addrs, requiredSigs, nil }