An open API service indexing awesome lists of open source software.

https://github.com/wolfstudy/tx_unsignature

the project will analyze the not signature transaction
https://github.com/wolfstudy/tx_unsignature

Last synced: about 1 year ago
JSON representation

the project will analyze the not signature transaction

Awesome Lists containing this project

README

          

# tx_unsignature
the project will analyze the not signature transaction

the project use btcd(golang) lib

and fix the code.
in opcode.go add follow code on `func opcodeCheckMultiSig()`

```
var Result [][]string //by wolf4j
func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
numKeys, err := vm.dstack.PopInt()
if err != nil {
return err
}

numPubKeys := int(numKeys.Int32())
if numPubKeys < 0 {
str := fmt.Sprintf("number of pubkeys %d is negative",
numPubKeys)
return scriptError(ErrInvalidPubKeyCount, str)
}
if numPubKeys > MaxPubKeysPerMultiSig {
str := fmt.Sprintf("too many pubkeys: %d > %d",
numPubKeys, MaxPubKeysPerMultiSig)
return scriptError(ErrInvalidPubKeyCount, str)
}
vm.numOps += numPubKeys
if vm.numOps > MaxOpsPerScript {
str := fmt.Sprintf("exceeded max operation limit of %d",
MaxOpsPerScript)
return scriptError(ErrTooManyOperations, str)
}

pubKeys := make([][]byte, 0, numPubKeys)
for i := 0; i < numPubKeys; i++ {
pubKey, err := vm.dstack.PopByteArray()
if err != nil {
return err
}
pubKeys = append(pubKeys, pubKey)
}

numSigs, err := vm.dstack.PopInt()
if err != nil {
return err
}
numSignatures := int(numSigs.Int32())
if numSignatures < 0 {
str := fmt.Sprintf("number of signatures %d is negative",
numSignatures)
return scriptError(ErrInvalidSignatureCount, str)

}
if numSignatures > numPubKeys {
str := fmt.Sprintf("more signatures than pubkeys: %d > %d",
numSignatures, numPubKeys)
return scriptError(ErrInvalidSignatureCount, str)
}

signatures := make([]*parsedSigInfo, 0, numSignatures)
for i := 0; i < numSignatures; i++ {
signature, err := vm.dstack.PopByteArray()
if err != nil {
return err
}
sigInfo := &parsedSigInfo{signature: signature}
signatures = append(signatures, sigInfo)
}

// A bug in the original Satoshi client implementation means one more
// stack value than should be used must be popped. Unfortunately, this
// buggy behavior is now part of the consensus and a hard fork would be
// required to fix it.
dummy, err := vm.dstack.PopByteArray()
if err != nil {
return err
}

// Since the dummy argument is otherwise not checked, it could be any
// value which unfortunately provides a source of malleability. Thus,
// there is a script flag to force an error when the value is NOT 0.
if vm.hasFlag(ScriptStrictMultiSig) && len(dummy) != 0 {
str := fmt.Sprintf("multisig dummy argument has length %d "+
"instead of 0", len(dummy))
return scriptError(ErrSigNullDummy, str)
}

// Get script starting from the most recent OP_CODESEPARATOR.
script := vm.subScript()

// Remove the signature in pre version 0 segwit scripts since there is
// no way for a signature to sign itself.
if !vm.isWitnessVersionActive(0) {
for _, sigInfo := range signatures {
script = removeOpcodeByData(script, sigInfo.signature)
}
}

success := true
numPubKeys++
pubKeyIdx := -1
signatureIdx := 0
for numSignatures > 0 {
// When there are more signatures than public keys remaining,
// there is no way to succeed since too many signatures are
// invalid, so exit early.
pubKeyIdx++
numPubKeys--
if numSignatures > numPubKeys {
success = false
break
}

sigInfo := signatures[signatureIdx]
pubKey := pubKeys[pubKeyIdx]

// The order of the signature and public key evaluation is
// important here since it can be distinguished by an
// OP_CHECKMULTISIG NOT when the strict encoding flag is set.

rawSig := sigInfo.signature
if len(rawSig) == 0 {
// Skip to the next pubkey if signature is empty.
continue
}

// Split the signature into hash type and signature components.
hashType := SigHashType(rawSig[len(rawSig)-1])
signature := rawSig[:len(rawSig)-1]

// Only parse and check the signature encoding once.
var parsedSig *btcec.Signature
if !sigInfo.parsed {
if err := vm.checkHashTypeEncoding(hashType); err != nil {
return err
}
if err := vm.checkSignatureEncoding(signature); err != nil {
return err
}

// Parse the signature.
var err error
if vm.hasFlag(ScriptVerifyStrictEncoding) ||
vm.hasFlag(ScriptVerifyDERSignatures) {

parsedSig, err = btcec.ParseDERSignature(signature,
btcec.S256())
} else {
parsedSig, err = btcec.ParseSignature(signature,
btcec.S256())
}
sigInfo.parsed = true
if err != nil {
continue
}
sigInfo.parsedSignature = parsedSig
} else {
// Skip to the next pubkey if the signature is invalid.
if sigInfo.parsedSignature == nil {
continue
}

// Use the already parsed signature.
parsedSig = sigInfo.parsedSignature
}

if err := vm.checkPubKeyEncoding(pubKey); err != nil {
return err
}

// Parse the pubkey.
parsedPubKey, err := btcec.ParsePubKey(pubKey, btcec.S256())
if err != nil {
continue
}

// Generate the signature hash based on the signature hash type.
var hash []byte
if vm.isWitnessVersionActive(0) {
var sigHashes *TxSigHashes
if vm.hashCache != nil {
sigHashes = vm.hashCache
} else {
sigHashes = NewTxSigHashes(&vm.tx)
}

hash, err = calcWitnessSignatureHash(script, sigHashes, hashType,
&vm.tx, vm.txIdx, vm.inputAmount)
if err != nil {
return err
}
} else {
hash = calcSignatureHash(script, hashType, &vm.tx, vm.txIdx)
}

var valid bool
if vm.sigCache != nil {
var sigHash chainhash.Hash
copy(sigHash[:], hash)

valid = vm.sigCache.Exists(sigHash, parsedSig, parsedPubKey)
if !valid && parsedSig.Verify(hash, parsedPubKey) {
vm.sigCache.Add(sigHash, parsedSig, parsedPubKey)
valid = true
}
} else {
valid = parsedSig.Verify(hash, parsedPubKey)
// by wolf4j
if valid {
publicKey := hex.EncodeToString(parsedPubKey.SerializeCompressed())
Result[vm.txIdx] = append(Result[vm.txIdx], publicKey)
fmt.Println("matched public key...")
}
}

if valid {
// PubKey verified, move on to the next signature.
signatureIdx++
numSignatures--
}
}

if !success && vm.hasFlag(ScriptVerifyNullFail) {
for _, sig := range signatures {
if len(sig.signature) > 0 {
str := "not all signatures empty on failed checkmultisig"
return scriptError(ErrNullFail, str)
}
}
}

vm.dstack.PushBool(success)
return nil
}

```