예제 #1
0
파일: KzOp.cs 프로젝트: wy000000/KzBsv
        /*
         *  // script.h lines 527-562
         *  bool GetOp2(const_iterator &pc, opcodetype &opcodeRet,
         *      std::vector<uint8_t> *pvchRet) const {
         *      opcodeRet = OP_INVALIDOPCODE;
         *      if (pvchRet) pvchRet->clear();
         *      if (pc >= end()) return false;
         *
         *      // Read instruction
         *      if (end() - pc < 1) return false;
         *      unsigned int opcode = *pc++;
         *
         *      // Immediate operand
         *      if (opcode <= OP_PUSHDATA4) {
         *          unsigned int nSize = 0;
         *          if (opcode < OP_PUSHDATA1) {
         *              nSize = opcode;
         *          } else if (opcode == OP_PUSHDATA1) {
         *              if (end() - pc < 1) return false;
         *              nSize = *pc++;
         *          } else if (opcode == OP_PUSHDATA2) {
         *              if (end() - pc < 2) return false;
         *              nSize = ReadLE16(&pc[0]);
         *              pc += 2;
         *          } else if (opcode == OP_PUSHDATA4) {
         *              if (end() - pc < 4) return false;
         *              nSize = ReadLE32(&pc[0]);
         *              pc += 4;
         *          }
         *          if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
         *              return false;
         *          if (pvchRet) pvchRet->assign(pc, pc + nSize);
         *          pc += nSize;
         *      }
         *
         *      opcodeRet = (opcodetype)opcode;
         *      return true;
         *  }
         */

        public static (bool ok, KzOp op) TryRead(ref ReadOnlySequence <byte> ros, out long consumed)
        {
            var op = new KzOp();
            var ok = op.TryReadOp(ref ros, out consumed);

            return(ok, op);
        }
예제 #2
0
        public int FindAndDelete(KzValType vchSig)
        {
            int nFound = 0;
            var s      = _script;
            var r      = s;

            if (vchSig.Length == 0)
            {
                return(nFound);
            }

            var op       = new KzOp();
            var consumed = 0L;
            var offset   = 0L;

            var o    = vchSig.Sequence;
            var oLen = o.Length;

            do
            {
                offset += consumed;
                while (s.StartsWith(o))
                {
                    r = r.RemoveSlice(offset, oLen);
                    s = s.Slice(oLen);
                    ++nFound;
                }
            } while (op.TryReadOp(ref s, out consumed));

            _script = r;
            return(nFound);

#if false
            CScript    result;
            iterator   pc = begin(), pc2 = begin();
            opcodetype opcode;

            do
            {
                result.insert(result.end(), pc2, pc);
                while (static_cast <size_t>(end() - pc) >= b.size() &&
                       std::equal(b.begin(), b.end(), pc))
                {
                    pc = pc + b.size();
                    ++nFound;
                }
                pc2 = pc;
            } while (GetOp(pc, opcode));

            if (nFound > 0)
            {
                result.insert(result.end(), pc2, end());
                *this = result;
            }
#endif
        }
예제 #3
0
        /// <summary>
        /// Decode script opcodes and push data.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <KzOp> Decode()
        {
            var ros = _script;

            while (ros.Length > 0)
            {
                var op = new KzOp();
                if (!op.TryReadOp(ref ros))
                {
                    goto fail;
                }
                yield return(op);
            }

fail:
            ;
        }
예제 #4
0
        public bool IsPushOnly()
        {
            var ros = _script;
            var op  = new KzOp();

            while (ros.Length > 0)
            {
                if (!op.TryReadOp(ref ros))
                {
                    return(false);
                }
                // Note that IsPushOnly() *does* consider OP_RESERVED to be a push-type
                // opcode, however execution of OP_RESERVED fails, so it's not relevant
                // to P2SH/BIP62 as the scriptSig would fail prior to the P2SH special
                // validation code being executed.
                if (op.Code > KzOpcode.OP_16)
                {
                    return(false);
                }
            }
            return(true);
        }