// reorder signatures to meet order of the keys // remove signatuers made by the same keys // remove exessive signatures (keeps transaction size down) func multisig_reorder(tx *btc.Tx) (all_signed bool) { all_signed = true for i := range tx.TxIn { ms, _ := btc.NewMultiSigFromScript(tx.TxIn[i].ScriptSig) if ms == nil { continue } hash := tx.SignatureHash(ms.P2SH(), i, btc.SIGHASH_ALL) var sigs []*btc.Signature for ki := range ms.PublicKeys { var sig *btc.Signature for si := range ms.Signatures { if btc.EcdsaVerify(ms.PublicKeys[ki], ms.Signatures[si].Bytes(), hash) { //fmt.Println("Key number", ki, "has signature number", si) sig = ms.Signatures[si] break } } if sig != nil { sigs = append(sigs, sig) } else if *verbose { fmt.Println("WARNING: Key number", ki, "has no matching signature") } if !*allowextramsigns && uint(len(sigs)) >= ms.SigsNeeded { break } } if *verbose { if len(ms.Signatures) > len(sigs) { fmt.Println("WARNING: Some signatures are obsolete and will be removed", len(ms.Signatures), "=>", len(sigs)) } else if len(ms.Signatures) < len(sigs) { fmt.Println("It appears that same key is re-used.", len(sigs)-len(ms.Signatures), "more signatures were added") } } ms.Signatures = sigs tx.TxIn[i].ScriptSig = ms.Bytes() if len(sigs) < int(ms.SigsNeeded) { all_signed = false } } return }
// prepare a signed transaction func sign_tx(tx *btc.Tx) (all_signed bool) { var multisig_done bool all_signed = true // go through each input for in := range tx.TxIn { if ms, _ := btc.NewMultiSigFromScript(tx.TxIn[in].ScriptSig); ms != nil { hash := tx.SignatureHash(ms.P2SH(), in, btc.SIGHASH_ALL) for ki := range ms.PublicKeys { k := public_to_key(ms.PublicKeys[ki]) if k != nil { r, s, e := btc.EcdsaSign(k.Key, hash) if e != nil { println("ERROR in sign_tx:", e.Error()) all_signed = false } else { btcsig := &btc.Signature{HashType: 0x01} btcsig.R.Set(r) btcsig.S.Set(s) ms.Signatures = append(ms.Signatures, btcsig) tx.TxIn[in].ScriptSig = ms.Bytes() multisig_done = true } } } } else { uo := getUO(&tx.TxIn[in].Input) if uo == nil { println("ERROR: Unkown input:", tx.TxIn[in].Input.String(), "- missing balance folder?") all_signed = false continue } adr := addr_from_pkscr(uo.Pk_script) if adr == nil { fmt.Println("WARNING: Don't know how to sign input number", in) fmt.Println(" Pk_script:", hex.EncodeToString(uo.Pk_script)) all_signed = false continue } k := hash_to_key(adr.Hash160) if k == nil { fmt.Println("WARNING: You do not have key for", adr.String(), "at input", in) all_signed = false continue } er := tx.Sign(in, uo.Pk_script, btc.SIGHASH_ALL, k.BtcAddr.Pubkey, k.Key) if er != nil { fmt.Println("ERROR: Sign failed for input number", in, er.Error()) all_signed = false } } } // reorder signatures if we signed any multisig inputs if multisig_done && !multisig_reorder(tx) { all_signed = false } if !all_signed { fmt.Println("WARNING: Not all the inputs have been signed") } return }
func evalScript(p []byte, stack *scrStack, tx *btc.Tx, inp int) bool { if DBG_SCR { println("script len", len(p)) } if len(p) > 10000 { if DBG_ERR { println("script too long", len(p)) } return false } defer func() { if r := recover(); r != nil { if DBG_ERR { err, ok := r.(error) if !ok { err = fmt.Errorf("pkg: %v", r) } println("evalScript panic:", err.Error()) } } }() var exestack scrStack var altstack scrStack sta, idx, opcnt := 0, 0, 0 for idx < len(p) { inexec := exestack.nofalse() // Read instruction opcode, pushval, n, e := btc.GetOpcode(p[idx:]) if e != nil { //println(e.Error()) //println("A", idx, hex.EncodeToString(p)) return false } idx += n if DBG_SCR { fmt.Printf("\nExecuting opcode 0x%02x n=%d inexec:%t push:%s..\n", opcode, n, inexec, hex.EncodeToString(pushval)) stack.print() } if pushval != nil && len(pushval) > btc.MAX_SCRIPT_ELEMENT_SIZE { if DBG_ERR { println("pushval too long", len(pushval)) } return false } if opcode > 0x60 { opcnt++ if opcnt > 201 { if DBG_ERR { println("evalScript: too many opcodes A") } return false } } if opcode == 0x7e /*OP_CAT*/ || opcode == 0x7f /*OP_SUBSTR*/ || opcode == 0x80 /*OP_LEFT*/ || opcode == 0x81 /*OP_RIGHT*/ || opcode == 0x83 /*OP_INVERT*/ || opcode == 0x84 /*OP_AND*/ || opcode == 0x85 /*OP_OR*/ || opcode == 0x86 /*OP_XOR*/ || opcode == 0x8d /*OP_2MUL*/ || opcode == 0x8e /*OP_2DIV*/ || opcode == 0x95 /*OP_MUL*/ || opcode == 0x96 /*OP_DIV*/ || opcode == 0x97 /*OP_MOD*/ || opcode == 0x98 /*OP_LSHIFT*/ || opcode == 0x99 /*OP_RSHIFT*/ { if DBG_ERR { println("Unsupported opcode", opcode) } return false } if inexec && 0 <= opcode && opcode <= btc.OP_PUSHDATA4 { stack.push(pushval) if DBG_SCR { fmt.Println("pushed", len(pushval), "bytes") } } else if inexec || (0x63 /*OP_IF*/ <= opcode && opcode <= 0x68 /*OP_ENDIF*/) { switch { case opcode == 0x4f: // OP_1NEGATE stack.pushInt(-1) case opcode >= 0x51 && opcode <= 0x60: // OP_1-OP_16 stack.pushInt(int64(opcode - 0x50)) case opcode == 0x61: // OP_NOP // Do nothing /* - not handled OP_VER = 0x62 */ case opcode == 0x63 || opcode == 0x64: //OP_IF || OP_NOTIF // <expression> if [statements] [else [statements]] endif val := false if inexec { if stack.size() < 1 { if DBG_ERR { println("Stack too short for", opcode) } return false } if opcode == 0x63 /*OP_IF*/ { val = stack.popBool() } else { val = !stack.popBool() } } if DBG_SCR { println(inexec, "if pushing", val, "...") } exestack.pushBool(val) /* - not handled OP_VERIF = 0x65, OP_VERNOTIF = 0x66, */ case opcode == 0x67: //OP_ELSE if exestack.size() == 0 { if DBG_ERR { println("exestack empty in OP_ELSE") } } exestack.pushBool(!exestack.popBool()) case opcode == 0x68: //OP_ENDIF if exestack.size() == 0 { if DBG_ERR { println("exestack empty in OP_ENDIF") } } exestack.pop() case opcode == 0x69: //OP_VERIFY if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } if !stack.topBool(-1) { return false } stack.pop() case opcode == 0x6b: //OP_TOALTSTACK if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } altstack.push(stack.pop()) case opcode == 0x6c: //OP_FROMALTSTACK if altstack.size() < 1 { if DBG_ERR { println("AltStack too short for opcode", opcode) } return false } stack.push(altstack.pop()) case opcode == 0x6d: //OP_2DROP if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pop() stack.pop() case opcode == 0x6e: //OP_2DUP if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x1 := stack.top(-1) x2 := stack.top(-2) stack.push(x2) stack.push(x1) case opcode == 0x6f: //OP_3DUP if stack.size() < 3 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x1 := stack.top(-3) x2 := stack.top(-2) x3 := stack.top(-1) stack.push(x1) stack.push(x2) stack.push(x3) case opcode == 0x70: //OP_2OVER if stack.size() < 4 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x1 := stack.top(-4) x2 := stack.top(-3) stack.push(x1) stack.push(x2) case opcode == 0x71: //OP_2ROT // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if stack.size() < 6 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x6 := stack.pop() x5 := stack.pop() x4 := stack.pop() x3 := stack.pop() x2 := stack.pop() x1 := stack.pop() stack.push(x3) stack.push(x4) stack.push(x5) stack.push(x6) stack.push(x1) stack.push(x2) case opcode == 0x72: //OP_2SWAP // (x1 x2 x3 x4 -- x3 x4 x1 x2) if stack.size() < 4 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x4 := stack.pop() x3 := stack.pop() x2 := stack.pop() x1 := stack.pop() stack.push(x3) stack.push(x4) stack.push(x1) stack.push(x2) case opcode == 0x73: //OP_IFDUP if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } if stack.topBool(-1) { stack.push(stack.top(-1)) } case opcode == 0x74: //OP_DEPTH stack.pushInt(int64(stack.size())) case opcode == 0x75: //OP_DROP if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pop() case opcode == 0x76: //OP_DUP if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } el := stack.pop() stack.push(el) stack.push(el) case opcode == 0x77: //OP_NIP if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x := stack.pop() stack.pop() stack.push(x) case opcode == 0x78: //OP_OVER if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.push(stack.top(-2)) case opcode == 0x79 || opcode == 0x7a: //OP_PICK || OP_ROLL if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } n := stack.popInt() if n < 0 || n >= int64(stack.size()) { if DBG_ERR { println("Wrong n for opcode", opcode) } return false } if opcode == 0x79 /*OP_PICK*/ { stack.push(stack.top(int(-1 - n))) } else if n > 0 { tmp := make([][]byte, n) for i := range tmp { tmp[i] = stack.pop() } xn := stack.pop() for i := len(tmp) - 1; i >= 0; i-- { stack.push(tmp[i]) } stack.push(xn) } case opcode == 0x7b: //OP_ROT if stack.size() < 3 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x3 := stack.pop() x2 := stack.pop() x1 := stack.pop() stack.push(x2) stack.push(x3) stack.push(x1) case opcode == 0x7c: //OP_SWAP if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x1 := stack.pop() x2 := stack.pop() stack.push(x1) stack.push(x2) case opcode == 0x7d: //OP_TUCK if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } x1 := stack.pop() x2 := stack.pop() stack.push(x1) stack.push(x2) stack.push(x1) case opcode == 0x82: //OP_SIZE if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushInt(int64(len(stack.top(-1)))) case opcode == 0x87 || opcode == 0x88: //OP_EQUAL || OP_EQUALVERIFY if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } a := stack.pop() b := stack.pop() if opcode == 0x88 { //OP_EQUALVERIFY if !bytes.Equal(a, b) { return false } } else { stack.pushBool(bytes.Equal(a, b)) } /* - not handled OP_RESERVED1 = 0x89, OP_RESERVED2 = 0x8a, */ case opcode == 0x8b: //OP_1ADD if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushInt(stack.popInt() + 1) case opcode == 0x8c: //OP_1SUB if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushInt(stack.popInt() - 1) case opcode == 0x8f: //OP_NEGATE if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushInt(-stack.popInt()) case opcode == 0x90: //OP_ABS if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } a := stack.popInt() if a < 0 { stack.pushInt(-a) } else { stack.pushInt(a) } case opcode == 0x91: //OP_NOT if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushBool(stack.popInt() == 0) case opcode == 0x92: //OP_0NOTEQUAL if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } stack.pushBool(stack.popBool()) case opcode == 0x93 || //OP_ADD opcode == 0x94 || //OP_SUB opcode == 0x9a || //OP_BOOLAND opcode == 0x9b || //OP_BOOLOR opcode == 0x9c || opcode == 0x9d || //OP_NUMEQUAL || OP_NUMEQUALVERIFY opcode == 0x9e || //OP_NUMNOTEQUAL opcode == 0x9f || //OP_LESSTHAN opcode == 0xa0 || //OP_GREATERTHAN opcode == 0xa1 || //OP_LESSTHANOREQUAL opcode == 0xa2 || //OP_GREATERTHANOREQUAL opcode == 0xa3 || //OP_MIN opcode == 0xa4: //OP_MAX if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } bn2 := stack.popInt() bn1 := stack.popInt() var bn int64 switch opcode { case 0x93: bn = bn1 + bn2 // OP_ADD case 0x94: bn = bn1 - bn2 // OP_SUB case 0x9a: bn = b2i(bn1 != 0 && bn2 != 0) // OP_BOOLAND case 0x9b: bn = b2i(bn1 != 0 || bn2 != 0) // OP_BOOLOR case 0x9c: bn = b2i(bn1 == bn2) // OP_NUMEQUAL case 0x9d: bn = b2i(bn1 == bn2) // OP_NUMEQUALVERIFY case 0x9e: bn = b2i(bn1 != bn2) // OP_NUMNOTEQUAL case 0x9f: bn = b2i(bn1 < bn2) // OP_LESSTHAN case 0xa0: bn = b2i(bn1 > bn2) // OP_GREATERTHAN case 0xa1: bn = b2i(bn1 <= bn2) // OP_LESSTHANOREQUAL case 0xa2: bn = b2i(bn1 >= bn2) // OP_GREATERTHANOREQUAL case 0xa3: // OP_MIN if bn1 < bn2 { bn = bn1 } else { bn = bn2 } case 0xa4: // OP_MAX if bn1 > bn2 { bn = bn1 } else { bn = bn2 } default: panic("invalid opcode") } if opcode == 0x9d { //OP_NUMEQUALVERIFY if bn == 0 { return false } } else { stack.pushInt(bn) } case opcode == 0xa5: //OP_WITHIN if stack.size() < 3 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } bn3 := stack.popInt() bn2 := stack.popInt() bn1 := stack.popInt() stack.pushBool(bn2 <= bn1 && bn1 < bn3) case opcode == 0xa6: //OP_RIPEMD160 if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } rim := ripemd160.New() rim.Write(stack.pop()[:]) stack.push(rim.Sum(nil)[:]) case opcode == 0xa7: //OP_SHA1 if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } sha := sha1.New() sha.Write(stack.pop()[:]) stack.push(sha.Sum(nil)[:]) case opcode == 0xa8: //OP_SHA256 if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } sha := sha256.New() sha.Write(stack.pop()[:]) stack.push(sha.Sum(nil)[:]) case opcode == 0xa9: //OP_HASH160 if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } rim160 := btc.Rimp160AfterSha256(stack.pop()) stack.push(rim160[:]) case opcode == 0xaa: //OP_HASH256 if stack.size() < 1 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } h := btc.Sha2Sum(stack.pop()) stack.push(h[:]) case opcode == 0xab: // OP_CODESEPARATOR sta = idx case opcode == 0xac || opcode == 0xad: // OP_CHECKSIG || OP_CHECKSIGVERIFY if stack.size() < 2 { if DBG_ERR { println("Stack too short for opcode", opcode) } return false } var ok bool pk := stack.pop() si := stack.pop() if len(si) > 9 { sh := tx.SignatureHash(delSig(p[sta:], si), inp, int32(si[len(si)-1])) ok = btc.EcdsaVerify(pk, si, sh) if !ok && DBG_ERR { println("EcdsaVerify fail 1") } } if DBG_SCR { println("ver:", ok) } if opcode == 0xad { if !ok { // OP_CHECKSIGVERIFY return false } } else { // OP_CHECKSIG stack.pushBool(ok) } case opcode == 0xae || opcode == 0xaf: //OP_CHECKMULTISIG || OP_CHECKMULTISIGVERIFY //println("OP_CHECKMULTISIG ...") //stack.print() if stack.size() < 1 { if DBG_ERR { println("OP_CHECKMULTISIG: Stack too short A") } return false } i := 1 keyscnt := stack.topInt(-i) if keyscnt < 0 || keyscnt > 20 { println("OP_CHECKMULTISIG: Wrong number of keys") return false } opcnt += int(keyscnt) if opcnt > 201 { if DBG_ERR { println("evalScript: too many opcodes B") } return false } i++ ikey := i i += int(keyscnt) if stack.size() < i { if DBG_ERR { println("OP_CHECKMULTISIG: Stack too short B") } return false } sigscnt := stack.topInt(-i) if sigscnt < 0 || sigscnt > keyscnt { println("OP_CHECKMULTISIG: sigscnt error") return false } i++ isig := i i += int(sigscnt) if stack.size() < i { if DBG_ERR { println("OP_CHECKMULTISIG: Stack too short C") } return false } xxx := p[sta:] for k := 0; k < int(sigscnt); k++ { xxx = delSig(xxx, stack.top(-isig-k)) } success := true for sigscnt > 0 { pk := stack.top(-ikey) si := stack.top(-isig) if len(si) > 9 && ((len(pk) == 65 && pk[0] == 4) || (len(pk) == 33 && (pk[0]|1) == 3)) { sh := tx.SignatureHash(xxx, inp, int32(si[len(si)-1])) if btc.EcdsaVerify(pk, si, sh) { isig++ sigscnt-- } } ikey++ keyscnt-- // If there are more signatures left than keys left, // then too many signatures have failed if sigscnt > keyscnt { success = false break } } for i > 0 { i-- stack.pop() } if opcode == 0xaf { if !success { // OP_CHECKMULTISIGVERIFY return false } } else { stack.pushBool(success) } case opcode >= 0xb0 && opcode <= 0xb9: //OP_NOP // just do nothing default: if DBG_ERR { fmt.Printf("Unhandled opcode 0x%02x - a handler must be implemented\n", opcode) stack.print() fmt.Println("Rest of the script:", hex.EncodeToString(p[idx:])) } return false } } if DBG_SCR { fmt.Printf("Finished Executing opcode 0x%02x\n", opcode) stack.print() } if stack.size()+altstack.size() > 1000 { if DBG_ERR { println("Stack too big") } return false } } if DBG_SCR { fmt.Println("END OF SCRIPT") stack.print() } if exestack.size() > 0 { if DBG_ERR { println("Unfinished if..") } return false } return true }