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
- Host: GitHub
- URL: https://github.com/wolfstudy/tx_unsignature
- Owner: wolfstudy
- License: apache-2.0
- Created: 2018-01-03T09:08:06.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-01-06T07:59:54.000Z (over 8 years ago)
- Last Synced: 2025-03-13T03:29:18.097Z (over 1 year ago)
- Language: Go
- Size: 13.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
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
}
```