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.
|
// to sign itself.
|
||||||
subScript = removeOpcodeByData(subScript, fullSigBytes)
|
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())
|
pubKey, err := btcec.ParsePubKey(pkBytes, btcec.S256())
|
||||||
|
@ -2467,7 +2470,10 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
var valid bool
|
||||||
|
|
|
@ -863,8 +863,13 @@ func TestCalcSignatureHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hashType := SigHashType(testVecF64ToUint32(test[3].(float64)))
|
hashType := SigHashType(testVecF64ToUint32(test[3].(float64)))
|
||||||
hash := calcSignatureHash(parsedScript, hashType, &tx,
|
hash, err := calcSignatureHash(parsedScript, hashType, &tx,
|
||||||
int(test[2].(float64)))
|
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))
|
expectedHash, _ := chainhash.NewHashFromStr(test[4].(string))
|
||||||
if !bytes.Equal(hash, expectedHash[:]) {
|
if !bytes.Equal(hash, expectedHash[:]) {
|
||||||
|
|
|
@ -572,13 +572,12 @@ func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse output script: %v", err)
|
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
|
// calcSignatureHashRaw computes the signature hash for the specified input of
|
||||||
// engine instance, calculate the signature hash to be used for signing and
|
// the target transaction observing the desired signature hash type.
|
||||||
// verification.
|
func calcSignatureHashRaw(sigScript []byte, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
|
||||||
func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
|
|
||||||
// The SigHashSingle signature type signs only the corresponding input
|
// The SigHashSingle signature type signs only the corresponding input
|
||||||
// and output (the output with the same index number as the 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.
|
// 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
|
// Make a shallow copy of the transaction, zeroing out the script for
|
||||||
// all inputs that are not currently being processed.
|
// all inputs that are not currently being processed.
|
||||||
txCopy := shallowCopyTx(tx)
|
txCopy := shallowCopyTx(tx)
|
||||||
for i := range txCopy.TxIn {
|
for i := range txCopy.TxIn {
|
||||||
if i == idx {
|
if i == idx {
|
||||||
// UnparseScript cannot fail here because removeOpcode
|
txCopy.TxIn[idx].SignatureScript = filteredScript
|
||||||
// above only returns a valid script.
|
|
||||||
sigScript, _ := unparseScript(script)
|
|
||||||
txCopy.TxIn[idx].SignatureScript = sigScript
|
|
||||||
} else {
|
} else {
|
||||||
txCopy.TxIn[i].SignatureScript = nil
|
txCopy.TxIn[i].SignatureScript = nil
|
||||||
}
|
}
|
||||||
|
@ -670,6 +676,21 @@ func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.Msg
|
||||||
return chainhash.DoubleHashB(wbuf.Bytes())
|
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
|
// asSmallInt returns the passed opcode, which must be true according to
|
||||||
// isSmallInt(), as an integer.
|
// isSmallInt(), as an integer.
|
||||||
func asSmallInt(op *opcode) int {
|
func asSmallInt(op *opcode) int {
|
||||||
|
|
|
@ -345,7 +345,10 @@ sigLoop:
|
||||||
// however, assume no sigs etc are in the script since that
|
// however, assume no sigs etc are in the script since that
|
||||||
// would make the transaction nonstandard and thus not
|
// would make the transaction nonstandard and thus not
|
||||||
// MultiSigTy, so we just need to hash the full thing.
|
// 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 {
|
for _, addr := range addresses {
|
||||||
// All multisig addresses should be pubkey addresses
|
// All multisig addresses should be pubkey addresses
|
||||||
|
|
Loading…
Reference in a new issue