Made hashType typed as SigHashType.

This commit is contained in:
Jonathan Gillham 2014-10-11 20:55:28 +01:00
parent 9f47e9369c
commit 37ad7042b6
3 changed files with 43 additions and 38 deletions

View file

@ -1771,7 +1771,7 @@ func opcodeCheckSig(op *parsedOpcode, s *Script) error {
}
// Trim off hashtype from the signature string.
hashType := sigStr[len(sigStr)-1]
hashType := SigHashType(sigStr[len(sigStr)-1])
sigStr = sigStr[:len(sigStr)-1]
// Get script from the last OP_CODESEPARATOR and without any subsequent
@ -1932,7 +1932,8 @@ func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error {
// check signatures.
success := false
hash := calcScriptHash(script, signatures[i].ht, &s.tx, s.txidx)
hash := calcScriptHash(script, SigHashType(signatures[i].ht),
&s.tx, s.txidx)
inner:
// Find first pubkey that successfully validates signature.
// we start off the search from the key that was successful

View file

@ -145,13 +145,16 @@ var ErrUnsupportedAddress = errors.New("unsupported address type")
// This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.
var Bip16Activation = time.Unix(1333238400, 0)
// SigHashType represents hash type bits at the end of a signature.
type SigHashType byte
// Hash type bits from the end of a signature.
const (
SigHashOld = 0x0
SigHashAll = 0x1
SigHashNone = 0x2
SigHashSingle = 0x3
SigHashAnyOneCanPay = 0x80
SigHashOld SigHashType = 0x0
SigHashAll SigHashType = 0x1
SigHashNone SigHashType = 0x2
SigHashSingle SigHashType = 0x3
SigHashAnyOneCanPay SigHashType = 0x80
)
// These are the constants specified for maximums in individual scripts.
@ -805,7 +808,7 @@ func DisasmString(buf []byte) (string, error) {
// calcScriptHash will, given the a script and hashtype for the current
// scriptmachine, calculate the doubleSha256 hash of the transaction and
// script to be used for signature signing and verification.
func calcScriptHash(script []parsedOpcode, hashType byte, tx *btcwire.MsgTx, idx int) []byte {
func calcScriptHash(script []parsedOpcode, hashType SigHashType, tx *btcwire.MsgTx, idx int) []byte {
// remove all instances of OP_CODESEPARATOR still left in the script
script = removeOpcode(script, OP_CODESEPARATOR)
@ -1097,7 +1100,7 @@ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er
// serialized in either a compressed or uncompressed format based on
// compress. This format must match the same format used to generate
// the payment address, or the script validation will fail.
func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType byte, privKey *ecdsa.PrivateKey, compress bool) ([]byte, error) {
func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType SigHashType, privKey *ecdsa.PrivateKey, compress bool) ([]byte, error) {
sig, err := signTxOutput(tx, idx, subscript, hashType, privKey)
if err != nil {
return nil, err
@ -1114,7 +1117,7 @@ func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType byte
return NewScriptBuilder().AddData(sig).AddData(pkData).Script(), nil
}
func signTxOutput(tx *btcwire.MsgTx, idx int, subScript []byte, hashType byte,
func signTxOutput(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType,
key *ecdsa.PrivateKey) ([]byte, error) {
return signTxOutputCustomReader(rand.Reader, tx, idx, subScript,
@ -1122,7 +1125,7 @@ func signTxOutput(tx *btcwire.MsgTx, idx int, subScript []byte, hashType byte,
}
func signTxOutputCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int,
subScript []byte, hashType byte, key *ecdsa.PrivateKey) ([]byte, error) {
subScript []byte, hashType SigHashType, key *ecdsa.PrivateKey) ([]byte, error) {
parsedScript, err := parseScript(subScript)
if err != nil {
return nil, fmt.Errorf("cannot parse output script: %v", err)
@ -1133,10 +1136,11 @@ func signTxOutputCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int,
return nil, fmt.Errorf("cannot sign tx input: %s", err)
}
return append((&btcec.Signature{R: r, S: s}).Serialize(), hashType), nil
return append((&btcec.Signature{R: r, S: s}).Serialize(),
byte(hashType)), nil
}
func p2pkSignatureScript(tx *btcwire.MsgTx, idx int, subScript []byte, hashType byte, privKey *ecdsa.PrivateKey) ([]byte, error) {
func p2pkSignatureScript(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType, privKey *ecdsa.PrivateKey) ([]byte, error) {
sig, err := signTxOutput(tx, idx, subScript, hashType, privKey)
if err != nil {
return nil, err
@ -1149,7 +1153,7 @@ func p2pkSignatureScript(tx *btcwire.MsgTx, idx int, subScript []byte, hashType
// possible. It returns the generated script and a boolean if the script fulfils
// the contract (i.e. nrequired signatures are provided). Since it is arguably
// legal to not be able to sign any of the outputs, no error is returned.
func signMultiSig(tx *btcwire.MsgTx, idx int, subScript []byte, hashType byte,
func signMultiSig(tx *btcwire.MsgTx, idx int, subScript []byte, hashType SigHashType,
addresses []btcutil.Address, nRequired int, kdb KeyDB) ([]byte, bool) {
// We start with a single OP_FALSE to work around the (now standard)
// but in the reference implementation that causes a spurious pop at
@ -1178,7 +1182,7 @@ func signMultiSig(tx *btcwire.MsgTx, idx int, subScript []byte, hashType byte,
}
func sign(net *btcnet.Params, tx *btcwire.MsgTx, idx int, subScript []byte,
hashType byte, kdb KeyDB, sdb ScriptDB) ([]byte, ScriptClass,
hashType SigHashType, kdb KeyDB, sdb ScriptDB) ([]byte, ScriptClass,
[]btcutil.Address, int, error) {
class, addresses, nrequired, err := ExtractPkScriptAddrs(subScript, net)
@ -1355,7 +1359,7 @@ sigLoop:
continue
}
tSig := sig[:len(sig)-1]
hashType := sig[len(sig)-1]
hashType := SigHashType(sig[len(sig)-1])
pSig, err := btcec.ParseDERSignature(tSig, btcec.S256())
if err != nil {
@ -1454,7 +1458,7 @@ func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, error) {
// will be merged in a type-dependant manner with the newly generated.
// signature script.
func SignTxOutput(net *btcnet.Params, tx *btcwire.MsgTx, idx int,
pkScript []byte, hashType byte, kdb KeyDB, sdb ScriptDB,
pkScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB,
previousScript []byte) ([]byte, error) {
sigScript, class, addresses, nrequired, err := sign(net, tx, idx,

View file

@ -2518,7 +2518,7 @@ func TestCheckErrorCondition(t *testing.T) {
type TstSigScript struct {
name string
inputs []TstInput
hashtype byte
hashType btcscript.SigHashType
compress bool
scriptAtWrongIndex bool
}
@ -2577,7 +2577,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: false,
scriptAtWrongIndex: false,
},
@ -2597,7 +2597,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: false,
scriptAtWrongIndex: false,
},
@ -2611,7 +2611,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: true,
scriptAtWrongIndex: false,
},
@ -2631,12 +2631,12 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: true,
scriptAtWrongIndex: false,
},
{
name: "hashtype SigHashNone",
name: "hashType SigHashNone",
inputs: []TstInput{
{
txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript),
@ -2645,12 +2645,12 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashNone,
hashType: btcscript.SigHashNone,
compress: false,
scriptAtWrongIndex: false,
},
{
name: "hashtype SigHashSingle",
name: "hashType SigHashSingle",
inputs: []TstInput{
{
txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript),
@ -2659,12 +2659,12 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashSingle,
hashType: btcscript.SigHashSingle,
compress: false,
scriptAtWrongIndex: false,
},
{
name: "hashtype SigHashAnyoneCanPay",
name: "hashType SigHashAnyoneCanPay",
inputs: []TstInput{
{
txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript),
@ -2673,12 +2673,12 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAnyOneCanPay,
hashType: btcscript.SigHashAnyOneCanPay,
compress: false,
scriptAtWrongIndex: false,
},
{
name: "hashtype non-standard",
name: "hashType non-standard",
inputs: []TstInput{
{
txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript),
@ -2687,7 +2687,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: 0x04,
hashType: 0x04,
compress: false,
scriptAtWrongIndex: false,
},
@ -2701,7 +2701,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: true,
scriptAtWrongIndex: false,
},
@ -2714,7 +2714,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: false,
scriptAtWrongIndex: false,
},
@ -2734,7 +2734,7 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: false,
scriptAtWrongIndex: true,
},
@ -2754,14 +2754,14 @@ var SigScriptTests = []TstSigScript{
indexOutOfRange: false,
},
},
hashtype: btcscript.SigHashAll,
hashType: btcscript.SigHashAll,
compress: false,
scriptAtWrongIndex: true,
},
}
// Test the sigscript generation for valid and invalid inputs, all
// hashtypes, and with and without compression. This test creates
// hashTypes, and with and without compression. This test creates
// sigscripts to spend fake coinbase inputs, as sigscripts cannot be
// created for the MsgTxs in txTests, since they come from the blockchain
// and we don't have the private keys.
@ -2802,7 +2802,7 @@ nexttest:
}
script, err = btcscript.SignatureScript(tx, idx,
SigScriptTests[i].inputs[j].txout.PkScript,
SigScriptTests[i].hashtype, privKey,
SigScriptTests[i].hashType, privKey,
SigScriptTests[i].compress)
if (err == nil) != SigScriptTests[i].inputs[j].sigscriptGenerates {
@ -3239,7 +3239,7 @@ func TestMultiSigScript(t *testing.T) {
}
func signAndCheck(msg string, tx *btcwire.MsgTx, idx int, pkScript []byte,
hashType byte, kdb btcscript.KeyDB, sdb btcscript.ScriptDB,
hashType btcscript.SigHashType, kdb btcscript.KeyDB, sdb btcscript.ScriptDB,
previousScript []byte) error {
sigScript, err := btcscript.SignTxOutput(
@ -3314,7 +3314,7 @@ func TestSignTxOutput(t *testing.T) {
// make key
// make script based on key.
// sign with magic pixie dust.
hashTypes := []byte{
hashTypes := []btcscript.SigHashType{
btcscript.SigHashOld, // no longer used but should act like all
btcscript.SigHashAll,
btcscript.SigHashNone,