public static KzOp Push(ReadOnlySpan <byte> data) { var code = KzOpcode.OP_INVALIDOPCODE; var val = KzValType.None; if (data.Length == 1 && data[0] <= 16) { code = data[0] == 0 ? KzOpcode.OP_0 : (KzOpcode)(data[0] - 1 + (int)KzOpcode.OP_1); } else { if (data.Length < (int)KzOpcode.OP_PUSHDATA1) { code = (KzOpcode)data.Length; } else if (data.Length <= 0xff) { code = KzOpcode.OP_PUSHDATA1; } else if (data.Length <= 0xffff) { code = KzOpcode.OP_PUSHDATA2; } else { code = KzOpcode.OP_PUSHDATA4; } val = new KzValType(data.ToArray()); } var op = new KzOp(code, val); return(op); }
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 }
public KzValType BitXor(KzValType b) { if (Length != b.Length) { throw new InvalidOperationException(); } var sa = ToSpan(); var sb = b.ToSpan(); var r = new byte[sa.Length]; for (var i = 0; i < sa.Length; i++) { r[i] = (byte)(sa[i] ^ sb[i]); } return(new KzValType(r)); }
public bool BitEquals(KzValType x2) { if (Length != x2.Length) { return(false); } var s1 = ToSpan(); var s2 = x2.ToSpan(); for (var i = 0; i < s1.Length; i++) { if (s1[i] != s2[i]) { return(false); } } return(true); }
public static KzOp Push(long v) { var code = KzOpcode.OP_INVALIDOPCODE; var val = KzValType.None; if (v == -1) { code = KzOpcode.OP_1NEGATE; } else if (v >= 0 && v <= 16) { code = v == 0 ? KzOpcode.OP_0 : (KzOpcode)(v - 1 + (int)KzOpcode.OP_1); } else { var bytes = BitConverter.GetBytes(v).AsSpan(); if (v <= 0xff) { code = KzOpcode.OP_PUSH1; val = new KzValType(bytes.Slice(0, 1).ToArray()); } else if (v <= 0xffff) { code = KzOpcode.OP_PUSH2; val = new KzValType(bytes.Slice(0, 2).ToArray()); } else if (v <= 0xffffff) { code = KzOpcode.OP_PUSH3; val = new KzValType(bytes.Slice(0, 3).ToArray()); } else { code = KzOpcode.OP_PUSH4; val = new KzValType(bytes.Slice(0, 4).ToArray()); } } var op = new KzOp(code, val); return(op); }
public KzBOp(KzValType data) : this() { IsFinal = true; IsRaw = true; Op = new KzOp(KzOpcode.OP_NOP, data); }
public KzOp(KzOpcode code) { _code = code; _data = KzValType.None; }
public KzOp(KzOpcode code, KzValType data) { _code = code; _data = data; }
public bool TryReadOp(ref SequenceReader <byte> r) { _code = KzOpcode.OP_INVALIDOPCODE; _data = KzValType.None; if (!r.TryRead(out byte opcode)) { goto fail; } _code = (KzOpcode)opcode; // Opcodes OP_0 and OP_1 to OP_16 are single byte opcodes that push the corresponding value. // Opcodes from zero to 0x4b [0..75] are single byte push commands where the value is the number of bytes to push. // Opcode 0x4c (76) takes the next byte as the count and should be used for pushing [76..255] bytes. // Opcode 0x4d (77) takes the next two bytes. Used for pushing [256..65536] bytes. // Opcode 0x4e (78) takes the next four bytes. Used for pushing [65537..4,294,967,296] bytes. if (opcode <= (byte)KzOpcode.OP_PUSHDATA4) { var nSize = 0U; if (opcode < (byte)KzOpcode.OP_PUSHDATA1) { nSize = opcode; } else if (opcode == (byte)KzOpcode.OP_PUSHDATA1) { if (!r.TryRead(out byte size1)) { goto fail; } nSize = size1; } else if (opcode == (byte)KzOpcode.OP_PUSHDATA2) { if (!r.TryReadLittleEndian(out UInt16 size2)) { goto fail; } nSize = size2; } else if (opcode == (byte)KzOpcode.OP_PUSHDATA4) { if (!r.TryReadLittleEndian(out UInt32 size4)) { goto fail; } nSize = size4; } if (nSize >= 0) { if (r.Remaining < nSize) { goto fail; } _data = new KzValType(r.Sequence.Slice(r.Position, (Int32)nSize)); r.Advance(nSize); } } return(true); fail: return(false); }