WIP: next hard fork #5
4 changed files with 49 additions and 14 deletions
|
@ -2198,7 +2198,10 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
|||
// to sign itself.
|
||||
subScript = removeOpcodeByData(subScript, fullSigBytes)
|
||||
|
||||
hash = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx)
|
||||
hash, err = calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256())
|
||||
|
@ -2467,7 +2470,10 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
hash, err = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var valid bool
|
||||
|
|
|
@ -863,8 +863,13 @@ func TestCalcSignatureHash(t *testing.T) {
|
|||
}
|
||||
|
||||
hashType := SigHashType(testVecF64ToUint32(test[3].(float64)))
|
||||
hash := calcSignatureHash(parsedScript, hashType, &tx,
|
||||
hash, err := calcSignatureHash(parsedScript, hashType, &tx,
|
||||
int(test[2].(float64)))
|
||||
if err != nil {
|
||||
t.Errorf("TestCalcSignatureHash failed test #%d: "+
|
||||
"Failed to compute sighash: %v", i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
expectedHash, _ := chainhash.NewHashFromStr(test[4].(string))
|
||||
if !bytes.Equal(hash, expectedHash[:]) {
|
||||
|
|
|
@ -572,13 +572,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse output script: %v", err)
|
||||
}
|
||||
return calcSignatureHash(parsedScript, hashType, tx, idx), nil
|
||||
return calcSignatureHash(parsedScript, hashType, tx, idx)
|
||||
}
|
||||
|
||||
// calcSignatureHash will, given a script and hash type for the current script
|
||||
// engine instance, calculate the signature hash to be used for signing and
|
||||
// verification.
|
||||
func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
|
||||
// calcSignatureHashRaw computes the signature hash for the specified input of
|
||||
// the target transaction observing the desired signature hash type.
|
||||
func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
|
||||
// The SigHashSingle signature type signs only the corresponding input
|
||||
// and output (the output with the same index number as the input).
|
||||
//
|
||||
|
@ -606,17 +605,24 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
|||
}
|
||||
|
||||
// Remove all instances of OP_CODESEPARATOR from the script.
|
||||
script = removeOpcode(script, OP_CODESEPARATOR)
|
||||
filteredScript := make([]byte, 0, len(sigScript))
|
||||
const scriptVersion = 0
|
||||
tokenizer := MakeScriptTokenizer(scriptVersion, sigScript)
|
||||
var prevOffset int32
|
||||
for tokenizer.Next() {
|
||||
if tokenizer.Opcode() != OP_CODESEPARATOR {
|
||||
filteredScript = append(filteredScript,
|
||||
sigScript[prevOffset:tokenizer.ByteIndex()]...)
|
||||
}
|
||||
prevOffset = tokenizer.ByteIndex()
|
||||
}
|
||||
|
||||
// Make a shallow copy of the transaction, zeroing out the script for
|
||||
// all inputs that are not currently being processed.
|
||||
txCopy := shallowCopyTx(tx)
|
||||
for i := range txCopy.TxIn {
|
||||
if i == idx {
|
||||
// UnparseScript cannot fail here because removeOpcode
|
||||
// above only returns a valid script.
|
||||
sigScript, _ := unparseScript(script)
|
||||
txCopy.TxIn[idx].SignatureScript = sigScript
|
||||
txCopy.TxIn[idx].SignatureScript = filteredScript
|
||||
} else {
|
||||
txCopy.TxIn[i].SignatureScript = nil
|
||||
}
|
||||
|
@ -670,6 +676,21 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
|||
return chainhash.DoubleHashB(wbuf.Bytes())
|
||||
}
|
||||
|
||||
// calcSignatureHash computes the signature hash for the specified input of the
|
||||
// target transaction observing the desired signature hash type.
|
||||
//
|
||||
// DEPRECATED: Use calcSignatureHashRaw instead
|
||||
func calcSignatureHash(prevOutScript []parsedOpcode, hashType SigHashType,
|
||||
tx *wire.MsgTx, idx int) ([]byte, error) {
|
||||
|
||||
sigScript, err := unparseScript(prevOutScript)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return calcSignatureHashRaw(sigScript, hashType, tx, idx), nil
|
||||
}
|
||||
|
||||
// asSmallInt returns the passed opcode, which must be true according to
|
||||
// isSmallInt(), as an integer.
|
||||
func asSmallInt(op *opcode) int {
|
||||
|
|
|
@ -345,7 +345,10 @@ sigLoop:
|
|||
// however, assume no sigs etc are in the script since that
|
||||
// would make the transaction nonstandard and thus not
|
||||
// MultiSigTy, so we just need to hash the full thing.
|
||||
hash := calcSignatureHash(pkPops, hashType, tx, idx)
|
||||
hash, err := calcSignatureHash(pkPops, hashType, tx, idx)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("cannot compute sighash: %v", err))
|
||||
}
|
||||
|
||||
for _, addr := range addresses {
|
||||
// All multisig addresses should be pubkey addresses
|
||||
|
|
Loading…
Reference in a new issue