Пример #1
0
        public void TestContract_Update_Invalid()
        {
            var nefFile = new NefFile()
            {
                Script   = new byte[] { 0x01 },
                Version  = new Version(1, 2, 3, 4).ToString(),
                Compiler = ""
            };

            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);

            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            snapshot.PersistingBlock = new Block();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, null, new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), null));
            Assert.ThrowsException <ArgumentException>(() => snapshot.UpdateContract(null, null, null));

            nefFile = new NefFile()
            {
                Script   = new byte[0],
                Version  = new Version(1, 2, 3, 4).ToString(),
                Compiler = ""
            };
            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[0]));
        }
Пример #2
0
        public void TestContract_Update_Invalid()
        {
            var nefFile = new NefFile()
            {
                Script   = new byte[] { 0x01 },
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };

            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);

            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, null, new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), null));
            Assert.ThrowsException <ArgumentException>(() => snapshot.UpdateContract(null, null, null));

            nefFile = new NefFile()
            {
                Script   = new byte[0],
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };
            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nefFile.ToArray(), new byte[0]));
        }
Пример #3
0
        public void TestContract_Update_Invalid()
        {
            var nefFile = new NefFile()
            {
                Script   = new byte[] { 0x01 },
                Version  = new Version(1, 2, 3, 4).ToString(),
                Compiler = ""
            };

            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);
            var nef = nefFile.ToArray();

            var engine = GetEngine(false, true);

            Assert.ThrowsException <InvalidOperationException>(() => engine.UpdateContract(null, new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => engine.UpdateContract(nef, null));
            Assert.ThrowsException <ArgumentException>(() => engine.UpdateContract(null, null));

            nefFile = new NefFile()
            {
                Script   = new byte[0],
                Version  = new Version(1, 2, 3, 4).ToString(),
                Compiler = ""
            };
            nefFile.CheckSum = NefFile.ComputeChecksum(nefFile);
            nef = nefFile.ToArray();

            Assert.ThrowsException <InvalidOperationException>(() => engine.UpdateContract(nef, new byte[] { 0x01 }));
            Assert.ThrowsException <InvalidOperationException>(() => engine.UpdateContract(nef, new byte[0]));
        }
Пример #4
0
        public void TestContract_Update()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            snapshot.PersistingBlock = new Block()
            {
            };

            var nef = new NefFile()
            {
                Script   = new byte[] { 0x01 },
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.UpdateContract(null, nef.ToArray(), new byte[0]));

            var manifest = TestUtils.CreateDefaultManifest();

            byte[]  privkey = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                                0x01,  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
            KeyPair key    = new KeyPair(privkey);
            ECPoint pubkey = key.PublicKey;
            var     state  = TestUtils.GetContract();

            byte[] signature = Crypto.Sign(state.Hash.ToArray(), privkey, pubkey.EncodePoint(false).Skip(1).ToArray());
            manifest.Groups = new ContractGroup[]
            {
                new ContractGroup()
                {
                    PubKey    = pubkey,
                    Signature = signature
                }
            };

            var storageItem = new StorageItem
            {
                Value      = new byte[] { 0x01 },
                IsConstant = false
            };

            var storageKey = new StorageKey
            {
                Id  = state.Id,
                Key = new byte[] { 0x01 }
            };

            snapshot.AddContract(state.Hash, state);
            snapshot.Storages.Add(storageKey, storageItem);
            state.UpdateCounter.Should().Be(0);
            snapshot.UpdateContract(state.Hash, nef.ToArray(), manifest.ToJson().ToByteArray(false));
            var ret = NativeContract.Management.GetContract(snapshot, state.Hash);

            snapshot.Storages.Find(BitConverter.GetBytes(state.Id)).ToList().Count().Should().Be(1);
            ret.UpdateCounter.Should().Be(1);
            ret.Id.Should().Be(state.Id);
            ret.Manifest.ToJson().ToString().Should().Be(manifest.ToJson().ToString());
            ret.Script.ToHexString().Should().Be(nef.Script.ToHexString().ToString());
        }
Пример #5
0
        public BuildScript Build(string filename, bool releaseMode = false, bool optimizer = true)
        {
            var contains = scriptsAll.ContainsKey(filename);

            if (!contains || (contains && scriptsAll[filename].UseOptimizer != optimizer))
            {
                if (Path.GetExtension(filename).ToLowerInvariant() == ".nef")
                {
                    var fileNameManifest = filename;
                    using (BinaryReader reader = new BinaryReader(File.OpenRead(filename)))
                    {
                        NefFile neffile = new NefFile();
                        neffile.Deserialize(reader);
                        fileNameManifest = fileNameManifest.Replace(".nef", ".manifest.json");
                        string      manifestFile   = File.ReadAllText(fileNameManifest);
                        BuildScript buildScriptNef = new BuildNEF(neffile, manifestFile);
                        scriptsAll[filename] = buildScriptNef;
                    }
                }
                else
                {
                    scriptsAll[filename] = NeonTestTool.BuildScript(filename, releaseMode, optimizer);
                }
            }

            return(scriptsAll[filename]);
        }
Пример #6
0
        private ContractState Deploy(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data)
        {
            if (engine.ScriptContainer is not Transaction tx)
            {
                throw new InvalidOperationException();
            }
            if (nefFile.Length == 0)
            {
                throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}");
            }
            if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
            {
                throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
            }

            engine.AddGas(Math.Max(
                              engine.StoragePrice * (nefFile.Length + manifest.Length),
                              GetMinimumDeploymentFee(engine.Snapshot)
                              ));

            NefFile          nef            = nefFile.AsSerializable <NefFile>();
            ContractManifest parsedManifest = ContractManifest.Parse(manifest);
            UInt160          hash           = Helper.GetContractHash(tx.Sender, nef.CheckSum, parsedManifest.Name);
            StorageKey       key            = CreateStorageKey(Prefix_Contract).Add(hash);

            if (engine.Snapshot.Contains(key))
            {
                throw new InvalidOperationException($"Contract Already Exists: {hash}");
            }
            ContractState contract = new ContractState
            {
                Id            = GetNextAvailableId(engine.Snapshot),
                UpdateCounter = 0,
                Nef           = nef,
                Hash          = hash,
                Manifest      = parsedManifest
            };

            if (!contract.Manifest.IsValid(hash))
            {
                throw new InvalidOperationException($"Invalid Manifest Hash: {hash}");
            }

            engine.Snapshot.Add(key, new StorageItem(contract));

            // Execute _deploy

            ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy", 2);

            if (md != null)
            {
                engine.CallFromNativeContract(Hash, hash, md.Name, data, false);
            }

            engine.SendNotification(Hash, "Deploy", new VM.Types.Array {
                contract.Hash.ToArray()
            });

            return(contract);
        }
        public void Test_CreateCallDestroy()
        {
            // Create

            var script   = _engine.Build("./TestClasses/Contract_Create.cs");
            var manifest = ContractManifest.FromJson(JObject.Parse(script.finalManifest));
            var nef      = new NefFile()
            {
                Script = script.finalNEFScript, Compiler = "unit-test", Version = "1.0"
            };
            var hash = Helper.GetContractHash((_engine.ScriptContainer as Transaction).Sender, nef.Script);

            nef.CheckSum = NefFile.ComputeChecksum(nef);

            // Create

            _engine.Reset();
            var result = _engine.ExecuteTestCaseStandard("create", nef.ToArray(), manifest.ToJson().ToString());

            Assert.AreEqual(VMState.HALT, _engine.State);
            Assert.AreEqual(1, result.Count);

            var item = result.Pop();

            Assert.IsInstanceOfType(item, typeof(Array));
            var itemArray = item as Array;

            Assert.AreEqual(1, itemArray[0].GetInteger());                  // Id
            Assert.AreEqual(0, itemArray[1].GetInteger());                  // UpdateCounter
            Assert.AreEqual(hash.ToArray(), itemArray[2]);                  // Hash
            Assert.AreEqual(script.finalNEFScript, itemArray[3]);           // Script
            Assert.AreEqual(manifest.ToString(), itemArray[4].GetString()); // Manifest

            // Call

            _engine.Reset();
            result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "oldContract", new Array());
            Assert.AreEqual(VMState.HALT, _engine.State);
            Assert.AreEqual(1, result.Count);

            item = result.Pop();
            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(123, item.GetInteger());

            // Destroy

            _engine.Reset();
            result = _engine.ExecuteTestCaseStandard("destroy");
            Assert.AreEqual(VMState.HALT, _engine.State);
            Assert.AreEqual(0, result.Count);

            // Check again for failures

            _engine.Reset();
            result = _engine.ExecuteTestCaseStandard("call", hash.ToArray());
            Assert.AreEqual(VMState.FAULT, _engine.State);
            Assert.AreEqual(0, result.Count);
        }
Пример #8
0
        private async ContractTask <ContractState> Deploy(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data)
        {
            if (engine.ScriptContainer is not Transaction tx)
            {
                throw new InvalidOperationException();
            }
            if (nefFile.Length == 0)
            {
                throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}");
            }
            if (manifest.Length == 0)
            {
                throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
            }

            engine.AddGas(Math.Max(
                              engine.StoragePrice * (nefFile.Length + manifest.Length),
                              GetMinimumDeploymentFee(engine.Snapshot)
                              ));

            NefFile          nef            = nefFile.AsSerializable <NefFile>();
            ContractManifest parsedManifest = ContractManifest.Parse(manifest);

            Helper.Check(nef.Script, parsedManifest.Abi);
            UInt160 hash = Helper.GetContractHash(tx.Sender, nef.CheckSum, parsedManifest.Name);

            if (Policy.IsBlocked(engine.Snapshot, hash))
            {
                throw new InvalidOperationException($"The contract {hash} has been blocked.");
            }

            StorageKey key = CreateStorageKey(Prefix_Contract).Add(hash);

            if (engine.Snapshot.Contains(key))
            {
                throw new InvalidOperationException($"Contract Already Exists: {hash}");
            }
            ContractState contract = new()
            {
                Id            = GetNextAvailableId(engine.Snapshot),
                UpdateCounter = 0,
                Nef           = nef,
                Hash          = hash,
                Manifest      = parsedManifest
            };

            if (!contract.Manifest.IsValid(hash))
            {
                throw new InvalidOperationException($"Invalid Manifest Hash: {hash}");
            }

            engine.Snapshot.Add(key, new StorageItem(contract));

            await OnDeploy(engine, contract, data, false);

            return(contract);
        }
Пример #9
0
        protected NativeContract()
        {
            List <ContractMethodMetadata> descriptors = new List <ContractMethodMetadata>();

            foreach (MemberInfo member in GetType().GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
            {
                ContractMethodAttribute attribute = member.GetCustomAttribute <ContractMethodAttribute>();
                if (attribute is null)
                {
                    continue;
                }
                descriptors.Add(new ContractMethodMetadata(member, attribute));
            }
            descriptors = descriptors.OrderBy(p => p.Name).ThenBy(p => p.Parameters.Length).ToList();
            byte[] script;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                foreach (ContractMethodMetadata method in descriptors)
                {
                    method.Descriptor.Offset = sb.Offset;
                    sb.EmitPush(0); //version
                    methods.Add(sb.Offset, method);
                    sb.EmitSysCall(ApplicationEngine.System_Contract_CallNative);
                    sb.Emit(OpCode.RET);
                }
                script = sb.ToArray();
            }
            this.Nef = new NefFile
            {
                Compiler = "neo-core-v3.0",
                Tokens   = Array.Empty <MethodToken>(),
                Script   = script
            };
            this.Nef.CheckSum = NefFile.ComputeChecksum(Nef);
            this.Hash         = Helper.GetContractHash(UInt160.Zero, 0, Name);
            this.Manifest     = new ContractManifest
            {
                Name               = Name,
                Groups             = Array.Empty <ContractGroup>(),
                SupportedStandards = Array.Empty <string>(),
                Abi = new ContractAbi()
                {
                    Events  = Array.Empty <ContractEventDescriptor>(),
                    Methods = descriptors.Select(p => p.Descriptor).ToArray()
                },
                Permissions = new[] { ContractPermission.DefaultPermission },
                Trusts      = WildcardContainer <UInt160> .Create(),
                Extra       = null
            };
            if (ProtocolSettings.Default.NativeActivations.TryGetValue(Name, out uint activationIndex))
            {
                this.ActiveBlockIndex = activationIndex;
            }
            contractsList.Add(this);
            contractsDictionary.Add(Hash, this);
        }
Пример #10
0
        public void TestDeserialize()
        {
            byte[] wrongMagic = { 0x00, 0x00, 0x00, 0x00 };
            using (MemoryStream ms = new(1024))
                using (BinaryWriter writer = new(ms))
                {
                    ((ISerializable)file).Serialize(writer);
                    ms.Seek(0, SeekOrigin.Begin);
                    ms.Write(wrongMagic, 0, 4);
                    ISerializable newFile = new NefFile();
                    Assert.ThrowsException <FormatException>(() =>
                    {
                        MemoryReader reader = new(ms.ToArray());
                        newFile.Deserialize(ref reader);
                        Assert.Fail();
                    });
                }

            file.CheckSum = 0;
            using (MemoryStream ms = new(1024))
                using (BinaryWriter writer = new(ms))
                {
                    ((ISerializable)file).Serialize(writer);
                    ISerializable newFile = new NefFile();
                    Assert.ThrowsException <FormatException>(() =>
                    {
                        MemoryReader reader = new(ms.ToArray());
                        newFile.Deserialize(ref reader);
                        Assert.Fail();
                    });
                }

            file.Script   = Array.Empty <byte>();
            file.CheckSum = NefFile.ComputeChecksum(file);
            using (MemoryStream ms = new(1024))
                using (BinaryWriter writer = new(ms))
                {
                    ((ISerializable)file).Serialize(writer);
                    ISerializable newFile = new NefFile();
                    Assert.ThrowsException <ArgumentException>(() =>
                    {
                        MemoryReader reader = new(ms.ToArray());
                        newFile.Deserialize(ref reader);
                        Assert.Fail();
                    });
                }

            file.Script   = new byte[] { 0x01, 0x02, 0x03 };
            file.CheckSum = NefFile.ComputeChecksum(file);
            var data     = file.ToArray();
            var newFile1 = data.AsSerializable <NefFile>();

            newFile1.Compiler.Should().Be(file.Compiler);
            newFile1.CheckSum.Should().Be(file.CheckSum);
            newFile1.Script.Span.SequenceEqual(file.Script.Span).Should().BeTrue();
        }
Пример #11
0
        public void TestContract_Create()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            snapshot.PersistingBlock = new Block()
            {
            };
            var nef = new NefFile()
            {
                Script   = new byte[byte.MaxValue],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString(),
                Tokens   = System.Array.Empty <MethodToken>()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile  = nef.ToArray();
            var manifest = TestUtils.CreateDefaultManifest();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false)));
            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1]));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000));

            var script_exceedMaxLength = new NefFile()
            {
                Script   = new byte[NefFile.MaxScriptLength - 1],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString(),
                Tokens   = System.Array.Empty <MethodToken>()
            };

            script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));

            var script_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true)));

            var manifest_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength));

            manifest = TestUtils.CreateDefaultManifest();
            var ret = snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false));

            ret.Hash.ToString().Should().Be("0x6410935f6b153eeb85f5d95d926c075b1ef51620");
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));

            var state = TestUtils.GetContract();

            snapshot.AddContract(state.Hash, state);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));
        }
Пример #12
0
        public void TestContract_Update()
        {
            var engine = GetEngine(false, true);
            var nef    = new NefFile()
            {
                Script   = new byte[] { 0x01 },
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile = nef.ToArray();

            Assert.ThrowsException <InvalidOperationException>(() => engine.UpdateContract(nefFile, new byte[0]));

            var manifest = TestUtils.CreateDefaultManifest();

            byte[]  privkey = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
                                0x01,  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
            KeyPair key      = new KeyPair(privkey);
            ECPoint pubkey   = key.PublicKey;
            var     snapshot = Blockchain.Singleton.GetSnapshot();
            var     state    = TestUtils.GetContract();

            byte[] signature = Crypto.Sign(state.Hash.ToArray(), privkey, pubkey.EncodePoint(false).Skip(1).ToArray());
            manifest.Groups = new ContractGroup[]
            {
                new ContractGroup()
                {
                    PubKey    = pubkey,
                    Signature = signature
                }
            };

            var storageItem = new StorageItem
            {
                Value      = new byte[] { 0x01 },
                IsConstant = false
            };

            var storageKey = new StorageKey
            {
                Id  = state.Id,
                Key = new byte[] { 0x01 }
            };

            snapshot.Contracts.Add(state.Hash, state);
            snapshot.Storages.Add(storageKey, storageItem);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot);
            engine.LoadScript(state.Script);
            engine.UpdateContract(nefFile, manifest.ToJson().ToByteArray(false));
            engine.Snapshot.Storages.Find(BitConverter.GetBytes(state.Id)).ToList().Count().Should().Be(1);
        }
Пример #13
0
        public BuildNEF(NefFile nefFile, string manifestFile) : base()
        {
            IsBuild      = true;
            UseOptimizer = false;
            Error        = null;
            finalNEF     = nefFile.Script;
            JObject manifestAbi = JObject.Parse(manifestFile);
            var     abi         = manifestAbi["abi"] as JObject;

            finalABI      = abi;
            finalManifest = manifestFile;
        }
Пример #14
0
        public void TestContract_Create()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            snapshot.PersistingBlock = new Block()
            {
            };
            var nef = new NefFile()
            {
                Script   = new byte[byte.MaxValue],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile  = nef.ToArray();
            var manifest = TestUtils.CreateDefaultManifest();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false)));
            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1]));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000));

            var script_exceedMaxLength = new NefFile()
            {
                Script   = new byte[NefFile.MaxScriptLength - 1],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));

            var script_zeroLength = new byte[] { };

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true)));

            var manifest_zeroLength = new byte[] { };

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength));

            manifest = TestUtils.CreateDefaultManifest();
            var ret = snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false));

            ret.Hash.ToString().Should().Be("0x5756874a149b9de89c7b5d34f9c37db3762f88a2");
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));

            var state = TestUtils.GetContract();

            snapshot.AddContract(state.Hash, state);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));
        }
Пример #15
0
        private ContractState Deploy(ApplicationEngine engine, byte[] nefFile, byte[] manifest)
        {
            if (!(engine.ScriptContainer is Transaction tx))
            {
                throw new InvalidOperationException();
            }
            if (nefFile.Length == 0)
            {
                throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}");
            }
            if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
            {
                throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
            }

            engine.AddGas(engine.StoragePrice * (nefFile.Length + manifest.Length));

            NefFile    nef  = nefFile.AsSerializable <NefFile>();
            UInt160    hash = Helper.GetContractHash(tx.Sender, nef.Script);
            StorageKey key  = CreateStorageKey(Prefix_Contract).Add(hash);

            if (engine.Snapshot.Storages.Contains(key))
            {
                throw new InvalidOperationException($"Contract Already Exists: {hash}");
            }
            ContractState contract = new ContractState
            {
                Id            = GetNextAvailableId(engine.Snapshot),
                UpdateCounter = 0,
                Script        = nef.Script,
                Hash          = hash,
                Manifest      = ContractManifest.Parse(manifest)
            };

            if (!contract.Manifest.IsValid(hash))
            {
                throw new InvalidOperationException($"Invalid Manifest Hash: {hash}");
            }

            engine.Snapshot.Storages.Add(key, new StorageItem(contract));

            // Execute _deploy

            ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy");

            if (md != null)
            {
                engine.CallFromNativeContract(Hash, hash, md.Name, false);
            }

            return(contract);
        }
Пример #16
0
        public void TestContract_Create()
        {
            var nef = new NefFile()
            {
                Script   = new byte[0x01],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile  = nef.ToArray();
            var manifest = TestUtils.CreateDefaultManifest();
            var engine   = GetEngine(false, true);

            Assert.ThrowsException <InvalidOperationException>(() => engine.CreateContract(nefFile, manifest.ToJson().ToByteArray(false)));

            engine = GetEngine(true, true);
            Assert.ThrowsException <ArgumentException>(() => engine.CreateContract(nefFile, new byte[ContractManifest.MaxLength + 1]));

            var script_exceedMaxLength = new NefFile()
            {
                Script   = new byte[NefFile.MaxScriptLength - 1],
                Compiler = "",
                Version  = new Version(1, 2, 3, 4).ToString()
            };

            script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => engine.CreateContract(script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));
            engine = GetEngine(true, true, gas: 2000_00000000);
            Assert.ThrowsException <FormatException>(() => engine.CreateContract(script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));

            var script_zeroLength = new byte[] { };

            Assert.ThrowsException <ArgumentException>(() => engine.CreateContract(script_zeroLength, manifest.ToJson().ToByteArray(true)));

            var manifest_zeroLength = new byte[] { };

            Assert.ThrowsException <ArgumentException>(() => engine.CreateContract(nefFile, manifest_zeroLength));

            manifest = TestUtils.CreateDefaultManifest();
            engine.CreateContract(nefFile, manifest.ToJson().ToByteArray(false));

            var snapshot = Blockchain.Singleton.GetSnapshot();
            var state    = TestUtils.GetContract();

            snapshot.Contracts.Add(state.Hash, state);
            engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, 0);
            engine.LoadScript(new byte[] { 0x01 });

            Assert.ThrowsException <InvalidOperationException>(() => engine.CreateContract(nefFile, manifest.ToJson().ToByteArray(false)));
        }
Пример #17
0
        public void TestDeserialize()
        {
            byte[] wrongMagic = { 0x00, 0x00, 0x00, 0x00 };
            using (MemoryStream ms = new MemoryStream(1024))
                using (BinaryWriter writer = new BinaryWriter(ms))
                    using (BinaryReader reader = new BinaryReader(ms))
                    {
                        ((ISerializable)file).Serialize(writer);
                        ms.Seek(0, SeekOrigin.Begin);
                        ms.Write(wrongMagic, 0, 4);
                        ms.Seek(0, SeekOrigin.Begin);
                        ISerializable newFile = new NefFile();
                        Action        action  = () => newFile.Deserialize(reader);
                        action.Should().Throw <FormatException>();
                    }

            file.CheckSum = 0;
            using (MemoryStream ms = new MemoryStream(1024))
                using (BinaryWriter writer = new BinaryWriter(ms))
                    using (BinaryReader reader = new BinaryReader(ms))
                    {
                        ((ISerializable)file).Serialize(writer);
                        ms.Seek(0, SeekOrigin.Begin);
                        ISerializable newFile = new NefFile();
                        Action        action  = () => newFile.Deserialize(reader);
                        action.Should().Throw <FormatException>();
                    }

            file.CheckSum   = NefFile.ComputeChecksum(file);
            file.ScriptHash = new byte[] { 0x01 }.ToScriptHash();
            using (MemoryStream ms = new MemoryStream(1024))
                using (BinaryWriter writer = new BinaryWriter(ms))
                    using (BinaryReader reader = new BinaryReader(ms))
                    {
                        ((ISerializable)file).Serialize(writer);
                        ms.Seek(0, SeekOrigin.Begin);
                        ISerializable newFile = new NefFile();
                        Action        action  = () => newFile.Deserialize(reader);
                        action.Should().Throw <FormatException>();
                    }

            file.ScriptHash = file.Script.ToScriptHash();
            var data     = file.ToArray();
            var newFile1 = data.AsSerializable <NefFile>();

            newFile1.Version.Should().Be(file.Version);
            newFile1.Compiler.Should().Be(file.Compiler);
            newFile1.ScriptHash.Should().Be(file.ScriptHash);
            newFile1.CheckSum.Should().Be(file.CheckSum);
            newFile1.Script.Should().BeEquivalentTo(file.Script);
        }
Пример #18
0
        public void TestContract_Create()
        {
            var snapshot = TestBlockchain.GetTestSnapshot();
            var nef      = new NefFile()
            {
                Script   = Enumerable.Repeat((byte)OpCode.RET, byte.MaxValue).ToArray(),
                Source   = string.Empty,
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile  = nef.ToArray();
            var manifest = TestUtils.CreateDefaultManifest();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false)));
            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1]));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000));

            var script_exceedMaxLength = new NefFile()
            {
                Script   = new byte[NefFile.MaxScriptLength - 1],
                Source   = string.Empty,
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };

            script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));

            var script_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true)));

            var manifest_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength));

            manifest = TestUtils.CreateDefaultManifest();
            var ret = snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false));

            ret.Hash.ToString().Should().Be("0x7b37d4bd3d87f53825c3554bd1a617318235a685");
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));

            var state = TestUtils.GetContract();

            snapshot.AddContract(state.Hash, state);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));
        }
Пример #19
0
        public void TestGetContractHash()
        {
            var nef = new NefFile()
            {
                Compiler = "test",
                Version  = new System.Version().ToString(),
                Script   = new byte[] { 1, 2, 3 }
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);

            Assert.AreEqual("0xb4b7417195feca1cdb5a99504ab641d8c220ae99", Neo.SmartContract.Helper.GetContractHash(UInt160.Zero, nef.Script).ToString());
            Assert.AreEqual("0xe56e4ee87f89a70e9138432c387ad49f2ee5b55f", Neo.SmartContract.Helper.GetContractHash(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"), nef.Script).ToString());
        }
Пример #20
0
        public void TestGetContractHash()
        {
            var nef = new NefFile()
            {
                Compiler = "test",
                Tokens   = Array.Empty <MethodToken>(),
                Script   = new byte[] { 1, 2, 3 }
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);

            Assert.AreEqual("0x9b9628e4f1611af90e761eea8cc21372380c74b6", Neo.SmartContract.Helper.GetContractHash(UInt160.Zero, nef.CheckSum, "").ToString());
            Assert.AreEqual("0x66eec404d86b918d084e62a29ac9990e3b6f4286", Neo.SmartContract.Helper.GetContractHash(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"), nef.CheckSum, "").ToString());
        }
Пример #21
0
        private void Update(ApplicationEngine engine, byte[] nefFile, byte[] manifest)
        {
            if (nefFile is null && manifest is null)
            {
                throw new ArgumentException();
            }

            engine.AddGas(engine.StoragePrice * ((nefFile?.Length ?? 0) + (manifest?.Length ?? 0)));

            var contract = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Contract).Add(engine.CallingScriptHash))?.GetInteroperable <ContractState>();

            if (contract is null)
            {
                throw new InvalidOperationException($"Updating Contract Does Not Exist: {engine.CallingScriptHash}");
            }

            if (nefFile != null)
            {
                if (nefFile.Length == 0)
                {
                    throw new ArgumentException($"Invalid NefFile Length: {nefFile.Length}");
                }

                NefFile nef = nefFile.AsSerializable <NefFile>();

                // Update script
                contract.Script = nef.Script;
            }
            if (manifest != null)
            {
                if (manifest.Length == 0 || manifest.Length > ContractManifest.MaxLength)
                {
                    throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
                }
                contract.Manifest = ContractManifest.Parse(manifest);
                if (!contract.Manifest.IsValid(contract.Hash))
                {
                    throw new InvalidOperationException($"Invalid Manifest Hash: {contract.Hash}");
                }
            }
            contract.UpdateCounter++; // Increase update counter
            if (nefFile != null)
            {
                ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy");
                if (md != null)
                {
                    engine.CallFromNativeContract(Hash, contract.Hash, md.Name, true);
                }
            }
        }
Пример #22
0
        public void TestGetContractHash()
        {
            var nef = new NefFile()
            {
                Compiler = "test",
                Version  = new System.Version().ToString(),
                Tokens   = Array.Empty <MethodToken>(),
                Script   = new byte[] { 1, 2, 3 }
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);

            Assert.AreEqual("0xb8e95ff7b11c427c29355e3398722d97bd2ca069", Neo.SmartContract.Helper.GetContractHash(UInt160.Zero, nef.Script).ToString());
            Assert.AreEqual("0x435c467b8e15cb9b1474ad7ee817ffdcfededef9", Neo.SmartContract.Helper.GetContractHash(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01"), nef.Script).ToString());
        }
Пример #23
0
        public void TestContract_Create()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot().CreateSnapshot();
            var nef      = new NefFile()
            {
                Script   = new byte[byte.MaxValue],
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            var nefFile  = nef.ToArray();
            var manifest = TestUtils.CreateDefaultManifest();

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(null, nefFile, manifest.ToJson().ToByteArray(false)));
            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, new byte[ContractManifest.MaxLength + 1]));
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(true), 10000000));

            var script_exceedMaxLength = new NefFile()
            {
                Script   = new byte[NefFile.MaxScriptLength - 1],
                Compiler = "",
                Tokens   = System.Array.Empty <MethodToken>()
            };

            script_exceedMaxLength.CheckSum = NefFile.ComputeChecksum(nef);
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, script_exceedMaxLength.ToArray(), manifest.ToJson().ToByteArray(true)));

            var script_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, script_zeroLength, manifest.ToJson().ToByteArray(true)));

            var manifest_zeroLength = System.Array.Empty <byte>();

            Assert.ThrowsException <ArgumentException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest_zeroLength));

            manifest = TestUtils.CreateDefaultManifest();
            var ret = snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false));

            ret.Hash.ToString().Should().Be("0x18e26e71e66fb79347581771c0910df5bea9d24b");
            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));

            var state = TestUtils.GetContract();

            snapshot.AddContract(state.Hash, state);

            Assert.ThrowsException <InvalidOperationException>(() => snapshot.DeployContract(UInt160.Zero, nefFile, manifest.ToJson().ToByteArray(false)));
        }
Пример #24
0
 public void TestSetup()
 {
     manifest = TestUtils.CreateDefaultManifest();
     contract = new ContractState
     {
         Nef = new NefFile
         {
             Compiler = nameof(ScriptBuilder),
             Tokens   = Array.Empty <MethodToken>(),
             Script   = script
         },
         Hash     = script.ToScriptHash(),
         Manifest = manifest
     };
     contract.Nef.CheckSum = NefFile.ComputeChecksum(contract.Nef);
 }
Пример #25
0
        public EvaluationStack ExecuteTestCaseStandard(string methodname, NefFile contract, params StackItem[] args)
        {
            var offset = GetMethodEntryOffset(methodname);

            if (offset == -1)
            {
                throw new Exception("Can't find method : " + methodname);
            }
            var rvcount = GetMethodReturnCount(methodname);

            if (rvcount == -1)
            {
                throw new Exception("Can't find method return count : " + methodname);
            }
            return(ExecuteTestCaseStandard(offset, (ushort)rvcount, contract, args));
        }
Пример #26
0
        public void ParseTest()
        {
            var file = new NefFile()
            {
                Compiler = "".PadLeft(32, ' '),
                Tokens   = Array.Empty <MethodToken>(),
                Script   = new byte[] { 0x01, 0x02, 0x03 }
            };

            file.CheckSum = NefFile.ComputeChecksum(file);

            var data = file.ToArray();

            file = data.AsSerializable <NefFile>();

            Assert.AreEqual("".PadLeft(32, ' '), file.Compiler);
            CollectionAssert.AreEqual(new byte[] { 0x01, 0x02, 0x03 }, file.Script);
        }
Пример #27
0
        internal static ContractState GetContract(string method = "test", int parametersCount = 0)
        {
            NefFile nef = new()
            {
                Compiler = "",
                Source   = "",
                Tokens   = Array.Empty <MethodToken>(),
                Script   = new byte[] { 0x01, 0x01, 0x01, 0x01 }
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            return(new ContractState
            {
                Id = 0x43000000,
                Nef = nef,
                Hash = nef.Script.Span.ToScriptHash(),
                Manifest = CreateManifest(method, ContractParameterType.Any, Enumerable.Repeat(ContractParameterType.Any, parametersCount).ToArray())
            });
        }
Пример #28
0
        internal static ContractState GetContract(byte[] script, ContractManifest manifest = null)
        {
            NefFile nef = new()
            {
                Compiler = "",
                Source   = "",
                Tokens   = Array.Empty <MethodToken>(),
                Script   = script
            };

            nef.CheckSum = NefFile.ComputeChecksum(nef);
            return(new ContractState
            {
                Id = 1,
                Hash = script.ToScriptHash(),
                Nef = nef,
                Manifest = manifest ?? CreateDefaultManifest()
            });
        }
Пример #29
0
        public void ParseTest()
        {
            var file = new NefFile()
            {
                Compiler = "".PadLeft(32, ' '),
                Version  = new Version(1, 2, 3, 4).ToString(),
                Script   = new byte[] { 0x01, 0x02, 0x03 }
            };

            file.CheckSum = NefFile.ComputeChecksum(file);

            var data = file.ToArray();

            file = data.AsSerializable <NefFile>();

            Assert.AreEqual("".PadLeft(32, ' '), file.Compiler);
            Assert.AreEqual(new Version(1, 2, 3, 4).ToString(), file.Version);
            CollectionAssert.AreEqual(new byte[] { 0x01, 0x02, 0x03 }, file.Script);
        }
Пример #30
0
        public EvaluationStack ExecuteTestCaseStandard(int offset, ushort rvcount, NefFile contract, params StackItem[] args)
        {
            var context = InvocationStack.Pop();

            context = CreateContext(context.Script, rvcount, offset);
            LoadContext(context);
            // Mock contract
            var contextState = CurrentContext.GetState <ExecutionContextState>();

            contextState.Contract ??= new ContractState()
            {
                Nef = contract
            };
            for (var i = args.Length - 1; i >= 0; i--)
            {
                this.Push(args[i]);
            }
            var initializeOffset = GetMethodEntryOffset("_initialize");

            if (initializeOffset != -1)
            {
                LoadContext(CurrentContext.Clone(initializeOffset));
            }
            while (true)
            {
                var bfault = (this.State & VMState.FAULT) > 0;
                var bhalt  = (this.State & VMState.HALT) > 0;
                if (bfault || bhalt)
                {
                    break;
                }
                Console.WriteLine("op:[" +
                                  this.CurrentContext.InstructionPointer.ToString("X04") +
                                  "]" +
                                  this.CurrentContext.CurrentInstruction.OpCode);
                this.ExecuteNext();
            }
            return(this.ResultStack);
        }