// OP_CHECKSIG // OP_CHECKSIGVERIFY func execCheckSig(ctx *execContext, op Opcode, _ []byte) error { if ctx.stack.height() < 2 { return errStackItemMissing } pk := ctx.stack.pop() sig := ctx.stack.pop() subScript := make([]byte, len(ctx.script)-ctx.separator) copy(subScript, ctx.script[ctx.separator:]) subScript, err := removeSig(subScript, sig) if err != nil { return err } err = checkKeySig(ctx.sctx, pk, sig, subScript, ctx.flags) if op == OP_CHECKSIGVERIFY { if err != nil { return errSigVerify } } else { // OP_CHECKSIG b := klib.ScriptInt(1) if err != nil { b = 0 } ctx.stack.push(b.Bytes()) } return nil }
func (s *Script) AppendPushInt(v int64) { if v == int64(OP_1NEGATE) || (v >= 1 && v <= 16) { s.AppendOp(Opcode(v + int64(OP_1) - 1)) } else { i := klib.ScriptInt(v) s.AppendPushData(i.Bytes()) } }
// OP_CHECKMULTISIG // OP_CHECKMULTISIGVERIFY func execCheckMultiSig(ctx *execContext, op Opcode, _ []byte) error { i := 1 if ctx.stack.height() < i { return errStackItemMissing } kCount := int(klib.ToScriptInt(ctx.stack.top(-i))) if kCount < 0 || kCount > numbers.MaxMultiSigKeyCount { return errKeySigCountOutOfRange } ctx.opCount += kCount if ctx.opCount > numbers.MaxOpcodeCount { return errOpcodeCount } i++ iKey := i i += kCount if ctx.stack.height() < i { return errStackItemMissing } sCount := int(klib.ToScriptInt(ctx.stack.top(-i))) if sCount < 0 || sCount > kCount { return errKeySigCountOutOfRange } i++ iSig := i i += sCount if ctx.stack.height() < i { return errStackItemMissing } subScript := make([]byte, len(ctx.script)-ctx.separator) copy(subScript, ctx.script[ctx.separator:]) for k := 0; k < sCount; k++ { var err error subScript, err = removeSig(subScript, ctx.stack.top(-(iSig + k))) if err != nil { return err } } success := true for success && (sCount > 0) { pk := ctx.stack.top(-iKey) sig := ctx.stack.top(-iSig) err := checkKeySig(ctx.sctx, pk, sig, subScript, ctx.flags) if err == nil { iSig++ sCount-- } iKey++ kCount-- // If there are more signatures left than keys left, // then too many signatures have failed if sCount > kCount { success = false } } // A Satoshi Bug causes CHECKMULTISIG to consume an extra item on the stack // We first clear all the "real" arguments stk := *ctx.stack *ctx.stack = stk[:len(stk)-i+1] // The dummy item is still requried if ctx.stack.empty() { return errStackItemMissing } // Now we check dummy being null when required si := ctx.stack.pop() if (ctx.flags&EvalFlagNullDummy) != 0 && len(si) > 0 { return errDummyArgNotNull } if op == OP_CHECKMULTISIGVERIFY { if !success { return errSigVerify } } else { // OP_CHECKMULTISIG b := klib.ScriptInt(1) if !success { b = 0 } ctx.stack.push(b.Bytes()) } return nil }
func intToStackItem(i int) stackItem { return klib.ScriptInt(i).Bytes() }