コード例 #1
0
        public void Constructor_ScriptNoSizeTest()
        {
            var      scr = new MockSerializableScript(new byte[] { 100, 200 }, 255);
            ReturnOp op  = new ReturnOp(scr, false);

            byte[] expected = new byte[] { 0x6a, 100, 200 };

            Helper.ComparePrivateField(op, "data", expected);
        }
コード例 #2
0
        public void Constructor_EmptyTest()
        {
            ReturnOp op = new ReturnOp();

            Assert.Equal(OP.RETURN, op.OpValue);
            Helper.ComparePrivateField <ReturnOp, byte[]>(op, "data", new byte[1] {
                0x6a
            });
        }
コード例 #3
0
        public void TryRead_NullStreamFailTest()
        {
            ReturnOp         op     = new ReturnOp();
            FastStreamReader stream = null;
            bool             b      = op.TryRead(stream, 3, out string err);

            Assert.False(b);
            Assert.Equal("Stream can not be null.", err);
        }
コード例 #4
0
        public void TryRead_FailTest(byte[] ba, int len, string expErr)
        {
            ReturnOp         op     = new ReturnOp();
            FastStreamReader stream = new FastStreamReader(ba);
            bool             b      = op.TryRead(stream, len, out string err);

            Assert.False(b);
            Assert.Equal(expErr, err);
        }
コード例 #5
0
        public void TryReadTest(byte[] ba, int len, byte[] expData)
        {
            ReturnOp         op     = new ReturnOp();
            FastStreamReader stream = new FastStreamReader(ba);
            bool             b      = op.TryRead(stream, len, out string err);

            Assert.True(b);
            Assert.Null(err);
            Helper.ComparePrivateField(op, "data", expData);
        }
コード例 #6
0
        public void WriteToStreamTest(byte[] ba, byte[] expected)
        {
            ReturnOp   op     = new ReturnOp(ba, false);
            FastStream stream = new FastStream();

            op.WriteToStream(stream);
            byte[] actual = stream.ToByteArray();

            Assert.Equal(expected, actual);
        }
コード例 #7
0
        public void GetHashCodeTest()
        {
            var r1 = new ReturnOp(new byte[] { 1, 2 });
            var r2 = new ReturnOp(new byte[] { 1, 2 });
            var r3 = new ReturnOp(new byte[] { 1, 2, 3 });

            int h1 = r1.GetHashCode();
            int h2 = r2.GetHashCode();
            int h3 = r3.GetHashCode();

            Assert.Equal(h1, h2);
            Assert.NotEqual(h1, h3);
        }
コード例 #8
0
        public override bool SetOperations()
        {
            Errors = null;

            try
            {
                byte[] ba = new byte[0];
                if (!string.IsNullOrEmpty(Data))
                {
                    switch (SelectedEncoder)
                    {
                    case Encoders.UTF8:
                        ba = Encoding.UTF8.GetBytes(Data);
                        break;

                    case Encoders.Base16:
                        if (!Base16.IsValid(Data))
                        {
                            Errors = "Invalid base16 (hexadecimal) string.";
                            return(false);
                        }
                        else
                        {
                            ba = Base16.ToByteArray(Data);
                        }
                        break;

                    default:
                        Errors = "Undefined encoder.";
                        return(false);
                    }
                }

                ReturnOp op = new ReturnOp(ba, true);
                OpsToAdd = new IOperation[1] {
                    op
                };
            }
            catch (Exception ex)
            {
                Errors = $"An unexpected error happened. Message: {ex.Message}";
                return(false);
            }

            return(true);
        }
コード例 #9
0
        public void EqualsTest()
        {
            IOperation r1_1 = new ReturnOp();
            IOperation r1_2 = new ReturnOp();
            IOperation r2_1 = new ReturnOp(new byte[] { 1, 2 }, false);
            IOperation r2_2 = new ReturnOp(new byte[] { 1, 2 }, false);
            IOperation r2_3 = new ReturnOp(new byte[] { 1, 2 }, true);
            IOperation r2_4 = new PushDataOp(new byte[] { 1, 2 });
            string     diff = "ReturnOp";

            Assert.True(r1_1.Equals(r1_1));
            Assert.True(r1_1.Equals(r1_2));
            Assert.False(r1_1.Equals(r2_1));

            Assert.True(r2_1.Equals(r2_1));
            Assert.True(r2_1.Equals(r2_2));
            Assert.False(r2_1.Equals(r2_3));
            Assert.False(r2_1.Equals(r2_4));
            Assert.False(r2_1.Equals(diff));
        }
コード例 #10
0
        private bool TryRead(byte[] data, List <IOperation> opList, ref int offset, out string error)
        {
            if (IsPushOp(data[offset]))
            {
                PushDataOp op = new PushDataOp();
                if (!op.TryRead(data, ref offset, out error, IsWitness))
                {
                    return(false);
                }
                opList.Add(op);
            }
            else if (data[offset] == (byte)OP.RETURN)
            {
                ReturnOp op = new ReturnOp();
                if (!op.TryRead(data, ref offset, out error, len))
                {
                    return(false);
                }
                opList.Add(op);
            }
            else
            {
                switch ((OP)data[offset])
                {
                // Invalid OPs:
                case OP.VerIf:
                case OP.VerNotIf:
                    error = $"Invalid OP was found: {GetOpName((OP)data[offset])}";
                    return(false);

                // Disabled OPs:
                case OP.CAT:
                case OP.SubStr:
                case OP.LEFT:
                case OP.RIGHT:
                case OP.INVERT:
                case OP.AND:
                case OP.OR:
                case OP.XOR:
                case OP.MUL2:
                case OP.DIV2:
                case OP.MUL:
                case OP.DIV:
                case OP.MOD:
                case OP.LSHIFT:
                case OP.RSHIFT:
                    error = $"Disabled OP was found: {GetOpName((OP)data[offset])}";
                    return(false);

                // Special case of IFs:
                case OP.IF:
                    IFOp ifop = new IFOp();
                    List <IOperation> ifOps = new List <IOperation>();
                    offset++;
                    while (data[offset] != (byte)OP.EndIf && data[offset] != (byte)OP.ELSE && offset < endIndex)
                    {
                        if (!TryRead(data, ifOps, ref offset, out error))
                        {
                            return(false);
                        }
                        if (offset > endIndex)
                        {
                            error = "Bad format.";
                            return(false);
                        }
                        if (ifOps.Count == 0)
                        {
                            error = "Empty OP_IF";
                            return(false);
                        }
                    }
                    if (data[offset] == (byte)OP.ELSE)
                    {
                        List <IOperation> elseOps = new List <IOperation>();
                        offset++;
                        while (data[offset] != (byte)OP.EndIf && offset < endIndex)
                        {
                            if (!TryRead(data, elseOps, ref offset, out error))
                            {
                                return(false);
                            }
                        }
                        if (offset > endIndex)
                        {
                            error = "Bad format.";
                            return(false);
                        }
                        if (elseOps.Count == 0)
                        {
                            error = "Empty OP_ELSE";
                            return(false);
                        }
                        ifop.elseOps = elseOps.ToArray();
                    }

                    if (data[offset] != (byte)OP.EndIf)
                    {
                        error = "No OP_ENDIF was found.";    //this may never happen!
                        return(false);
                    }

                    ifop.mainOps = ifOps.ToArray();

                    opList.Add(ifop);
                    break;

                case OP.NotIf:
                    NotIfOp           notifOp = new NotIfOp();
                    List <IOperation> ifOps2  = new List <IOperation>();
                    offset++;
                    while (data[offset] != (byte)OP.EndIf && data[offset] != (byte)OP.ELSE && offset < endIndex)
                    {
                        if (!TryRead(data, ifOps2, ref offset, out error))
                        {
                            return(false);
                        }
                        if (offset > endIndex)
                        {
                            error = "Bad format.";
                            return(false);
                        }
                        if (ifOps2.Count == 0)
                        {
                            error = "Empty OP_IF";
                            return(false);
                        }
                    }
                    if (data[offset] == (byte)OP.ELSE)
                    {
                        List <IOperation> elseOps2 = new List <IOperation>();
                        offset++;
                        while (data[offset] != (byte)OP.EndIf && offset < endIndex)
                        {
                            if (!TryRead(data, elseOps2, ref offset, out error))
                            {
                                return(false);
                            }
                        }
                        if (offset > endIndex)
                        {
                            error = "Bad format.";
                            return(false);
                        }
                        if (elseOps2.Count == 0)
                        {
                            error = "Empty OP_ELSE";
                            return(false);
                        }
                        notifOp.elseOps = elseOps2.ToArray();
                    }

                    if (data[offset] != (byte)OP.EndIf)
                    {
                        error = "No OP_ENDIF was found.";    //this may never happen!
                        return(false);
                    }

                    notifOp.mainOps = ifOps2.ToArray();

                    opList.Add(notifOp);
                    break;

                case OP.ELSE:
                    error = "OP_ELSE found without prior OP_IF or OP_NOTIF.";
                    return(false);

                case OP.EndIf:
                    error = "OP_EndIf found without prior OP_IF or OP_NOTIF.";
                    return(false);

                // From OP_0 to OP_16 except OP_Reserved is already handled.

                case OP.Reserved:
                    opList.Add(new ReservedOp());
                    break;

                case OP.NOP:
                    opList.Add(new NOPOp());
                    break;

                case OP.VER:
                    opList.Add(new VEROp());
                    break;

                // OP.IF and OP.NotIf moved to top
                // OP.VerIf and OP.VerNotIf moved to top (Invalid tx)
                // OP.ELSE and OP.EndIf moved to top

                case OP.VERIFY:
                    opList.Add(new VerifyOp());
                    break;

                // OP.RETURN is already handled

                case OP.ToAltStack:
                    opList.Add(new ToAltStackOp());
                    break;

                case OP.FromAltStack:
                    opList.Add(new FromAltStackOp());
                    break;

                case OP.DROP2:
                    opList.Add(new DROP2Op());
                    break;

                case OP.DUP2:
                    opList.Add(new DUP2Op());
                    break;

                case OP.DUP3:
                    opList.Add(new DUP3Op());
                    break;

                case OP.OVER2:
                    opList.Add(new OVER2Op());
                    break;

                case OP.ROT2:
                    opList.Add(new ROT2Op());
                    break;

                case OP.SWAP2:
                    opList.Add(new SWAP2Op());
                    break;

                case OP.IfDup:
                    opList.Add(new IfDupOp());
                    break;

                case OP.DEPTH:
                    opList.Add(new DEPTHOp());
                    break;

                case OP.DROP:
                    opList.Add(new DROPOp());
                    break;

                case OP.DUP:
                    opList.Add(new DUPOp());
                    break;

                case OP.NIP:
                    opList.Add(new NIPOp());
                    break;

                case OP.OVER:
                    opList.Add(new OVEROp());
                    break;

                case OP.PICK:
                    opList.Add(new PICKOp());
                    break;

                case OP.ROLL:
                    opList.Add(new ROLLOp());
                    break;

                case OP.ROT:
                    opList.Add(new ROTOp());
                    break;

                case OP.SWAP:
                    opList.Add(new SWAPOp());
                    break;

                case OP.TUCK:
                    opList.Add(new TUCKOp());
                    break;

                // OP_ (CAT SubStr LEFT RIGHT INVERT AND OR XOR) are moved to top

                case OP.SIZE:
                    opList.Add(new SizeOp());
                    break;

                case OP.EQUAL:
                    opList.Add(new EqualOp());
                    break;

                case OP.EqualVerify:
                    opList.Add(new EqualVerifyOp());
                    break;

                case OP.Reserved1:
                    opList.Add(new Reserved1Op());
                    break;

                case OP.Reserved2:
                    opList.Add(new Reserved2Op());
                    break;

                case OP.ADD1:
                    opList.Add(new ADD1Op());
                    break;

                case OP.SUB1:
                    opList.Add(new SUB1Op());
                    break;

                // OP.MUL2 and OP.DIV2 are moved to top (disabled op).

                case OP.NEGATE:
                    opList.Add(new NEGATEOp());
                    break;

                case OP.ABS:
                    opList.Add(new ABSOp());
                    break;

                case OP.NOT:
                    opList.Add(new NOTOp());
                    break;

                case OP.NotEqual0:
                    opList.Add(new NotEqual0Op());
                    break;

                case OP.ADD:
                    opList.Add(new AddOp());
                    break;

                case OP.SUB:
                    opList.Add(new SUBOp());
                    break;

                // OP_ (MUL DIV MOD LSHIFT RSHIFT) are moved to top (disabled op).

                case OP.BoolAnd:
                    opList.Add(new BoolAndOp());
                    break;

                case OP.BoolOr:
                    opList.Add(new BoolOrOp());
                    break;

                case OP.NumEqual:
                    opList.Add(new NumEqualOp());
                    break;

                case OP.NumEqualVerify:
                    opList.Add(new NumEqualVerifyOp());
                    break;

                case OP.NumNotEqual:
                    opList.Add(new NumNotEqualOp());
                    break;

                case OP.LessThan:
                    opList.Add(new LessThanOp());
                    break;

                case OP.GreaterThan:
                    opList.Add(new GreaterThanOp());
                    break;

                case OP.LessThanOrEqual:
                    opList.Add(new LessThanOrEqualOp());
                    break;

                case OP.GreaterThanOrEqual:
                    opList.Add(new GreaterThanOrEqualOp());
                    break;

                case OP.MIN:
                    opList.Add(new MINOp());
                    break;

                case OP.MAX:
                    opList.Add(new MAXOp());
                    break;

                case OP.WITHIN:
                    opList.Add(new WITHINOp());
                    break;

                case OP.RIPEMD160:
                    opList.Add(new RipeMd160Op());
                    break;

                case OP.SHA1:
                    opList.Add(new Sha1Op());
                    break;

                case OP.SHA256:
                    opList.Add(new Sha256Op());
                    break;

                case OP.HASH160:
                    opList.Add(new Hash160Op());
                    break;

                case OP.HASH256:
                    opList.Add(new Hash256Op());
                    break;

                //case OP.CodeSeparator:
                //    break;
                case OP.CheckSig:
                    opList.Add(new CheckSigOp());
                    break;

                case OP.CheckSigVerify:
                    opList.Add(new CheckSigVerifyOp());
                    break;

                case OP.CheckMultiSig:
                    opList.Add(new CheckMultiSigOp());
                    break;

                case OP.CheckMultiSigVerify:
                    opList.Add(new CheckMultiSigVerifyOp());
                    break;

                case OP.NOP1:
                    opList.Add(new NOP1Op());
                    break;

                case OP.CheckLocktimeVerify:
                    opList.Add(new CheckLocktimeVerifyOp());
                    break;

                //case OP.CheckSequenceVerify:
                //    break;
                case OP.NOP4:
                    opList.Add(new NOP4Op());
                    break;

                case OP.NOP5:
                    opList.Add(new NOP5Op());
                    break;

                case OP.NOP6:
                    opList.Add(new NOP6Op());
                    break;

                case OP.NOP7:
                    opList.Add(new NOP7Op());
                    break;

                case OP.NOP8:
                    opList.Add(new NOP8Op());
                    break;

                case OP.NOP9:
                    opList.Add(new NOP9Op());
                    break;

                case OP.NOP10:
                    opList.Add(new NOP10Op());
                    break;

                default:
                    error = "Undefined OP code";
                    return(false);
                }

                offset++;
            }

            error = null;
            return(true);
        }
コード例 #11
0
        public void Constructor_DataNoSizeTest(byte[] ba, byte[] expected)
        {
            ReturnOp op = new ReturnOp(ba, false);

            Helper.ComparePrivateField(op, "data", expected);
        }