Пример #1
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);
        }
        private ContractTask Update(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data)
        {
            if (nefFile is null && manifest is null) throw new ArgumentException();

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

            var contract = engine.Snapshot.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}");

                // Update nef
                contract.Nef = nefFile.AsSerializable<NefFile>();
            }
            if (manifest != null)
            {
                if (manifest.Length == 0)
                    throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
                ContractManifest manifest_new = ContractManifest.Parse(manifest);
                if (manifest_new.Name != contract.Manifest.Name)
                    throw new InvalidOperationException("The name of the contract can't be changed.");
                if (!manifest_new.IsValid(contract.Hash))
                    throw new InvalidOperationException($"Invalid Manifest Hash: {contract.Hash}");
                contract.Manifest = manifest_new;
            }
            Helper.Check(contract.Nef.Script, contract.Manifest.Abi);
            contract.UpdateCounter++; // Increase update counter
            return OnDeploy(engine, contract, data, true);
        }
Пример #3
0
        public void ParseFromJson_Extra()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":{""key"":""value""}}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(json, json);
            Assert.AreEqual("value", manifest.Extra["key"].AsString(), false);
        }
Пример #4
0
        public void ParseFromJson_Extra()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":{""key"":""value""}}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(json, json);
            Assert.AreEqual("value", manifest.Extra["key"].AsString(), false);
        }
Пример #5
0
        private byte[] LoadDeploymentScript(string nefFilePath, string manifestFilePath, out UInt160 scriptHash)
        {
            if (string.IsNullOrEmpty(manifestFilePath))
            {
                manifestFilePath = Path.ChangeExtension(nefFilePath, ".manifest.json");
            }

            // Read manifest

            var info = new FileInfo(manifestFilePath);

            if (!info.Exists || info.Length >= Transaction.MaxTransactionSize)
            {
                throw new ArgumentException(nameof(manifestFilePath));
            }

            var manifest = ContractManifest.Parse(File.ReadAllBytes(manifestFilePath));

            // Read nef

            info = new FileInfo(nefFilePath);
            if (!info.Exists || info.Length >= Transaction.MaxTransactionSize)
            {
                throw new ArgumentException(nameof(nefFilePath));
            }

            NefFile file;

            using (var stream = new BinaryReader(File.OpenRead(nefFilePath), Utility.StrictUTF8, false))
            {
                file = stream.ReadSerializable <NefFile>();
            }

            // Basic script checks

            Script script = new Script(file.Script);

            for (var i = 0; i < script.Length;)
            {
                // Check bad opcodes

                Instruction inst = script.GetInstruction(i);
                if (inst is null || !Enum.IsDefined(typeof(OpCode), inst.OpCode))
                {
                    throw new FormatException($"OpCode not found at {i}-{((byte)inst.OpCode).ToString("x2")}");
                }
                i += inst.Size;
            }

            // Build script

            scriptHash = file.ScriptHash;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitSysCall(ApplicationEngine.System_Contract_Create, file.Script, manifest.ToJson().ToString());
                return(sb.ToArray());
            }
        }
Пример #6
0
        private void Update(ApplicationEngine engine, byte[] nefFile, byte[] manifest, StackItem data)
        {
            if (nefFile is null && manifest is null)
            {
                throw new ArgumentException();
            }

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

            var contract = engine.Snapshot.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}");
                }

                // Update nef
                contract.Nef = nefFile.AsSerializable <NefFile>();
            }
            if (manifest != null)
            {
                if (manifest.Length == 0)
                {
                    throw new ArgumentException($"Invalid Manifest Length: {manifest.Length}");
                }
                ContractManifest manifest_new = ContractManifest.Parse(manifest);
                if (manifest_new.Name != contract.Manifest.Name)
                {
                    throw new InvalidOperationException("The name of the contract can't be changed.");
                }
                if (!manifest_new.IsValid(contract.Hash))
                {
                    throw new InvalidOperationException($"Invalid Manifest Hash: {contract.Hash}");
                }
                contract.Manifest = manifest_new;
            }
            Check(contract.Nef.Script, contract.Manifest.Abi);
            contract.UpdateCounter++; // Increase update counter
            if (nefFile != null)
            {
                ContractMethodDescriptor md = contract.Manifest.Abi.GetMethod("_deploy", 2);
                if (md != null)
                {
                    engine.CallFromNativeContract(Hash, contract.Hash, md.Name, data, true);
                }
            }
            engine.SendNotification(Hash, "Update", new VM.Types.Array {
                contract.Hash.ToArray()
            });
        }
Пример #7
0
        public void ParseFromJson_Default()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);
            Assert.AreEqual(manifest.ToString(), ContractManifest.CreateDefault(UInt160.Zero).ToString());
            Assert.IsTrue(manifest.IsValid(UInt160.Zero));
        }
Пример #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
        public void ParseFromJson_Default()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMethod"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":true}],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToJson().ToString(), json);
            Assert.AreEqual(manifest.ToJson().ToString(), TestUtils.CreateDefaultManifest().ToJson().ToString());
            Assert.IsTrue(manifest.IsValid(UInt160.Zero));
        }
Пример #10
0
        public void ParseFromJson_Default()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);
            Assert.AreEqual(manifest.ToString(), TestUtils.CreateDefaultManifest(UInt160.Zero).ToString());
            Assert.IsTrue(manifest.IsValid(UInt160.Zero));
        }
Пример #11
0
        void IInteroperable.FromStackItem(StackItem stackItem)
        {
            Array array = (Array)stackItem;

            Id            = (int)array[0].GetInteger();
            UpdateCounter = (ushort)array[1].GetInteger();
            Hash          = new UInt160(array[2].GetSpan());
            Script        = array[3].GetSpan().ToArray();
            Manifest      = ContractManifest.Parse(array[4].GetSpan());
        }
Пример #12
0
        public static async Task <(NefFile nefFile, ContractManifest manifest)> LoadContractAsync(this IFileSystem fileSystem, string contractPath)
        {
            var nefTask = Task.Run(() =>
            {
                using var stream = fileSystem.File.OpenRead(contractPath);
                using var reader = new System.IO.BinaryReader(stream, System.Text.Encoding.UTF8, false);
                return(reader.ReadSerializable <NefFile>());
            });

            var manifestTask = fileSystem.File.ReadAllBytesAsync(fileSystem.Path.ChangeExtension(contractPath, ".manifest.json"))
                               .ContinueWith(t => ContractManifest.Parse(t.Result), default, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
Пример #13
0
        public void ParseFromJson_SafeMethods()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToJson().ToString(), json);

            var check = TestUtils.CreateDefaultManifest();

            Assert.AreEqual(manifest.ToJson().ToString(), check.ToJson().ToString());
        }
Пример #14
0
        public void ParseFromJson_Features()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToJson().ToString(), json);

            var check = TestUtils.CreateDefaultManifest(UInt160.Zero);

            check.Features = ContractFeatures.HasStorage | ContractFeatures.Payable;
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #15
0
        public void ParseFromJson_Features()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":true,""payable"":true},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[]}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToJson().ToString(), json);

            var check = ContractManifest.CreateDefault(UInt160.Zero);

            check.Features = ContractFeatures.HasStorage | ContractFeatures.Payable;
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #16
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);
        }
Пример #17
0
        public void ParseFromJson_SafeMethods()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[""balanceOf""],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = TestUtils.CreateDefaultManifest(UInt160.Zero);

            check.SafeMethods = WildcardContainer <string> .Create("balanceOf");

            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #18
0
        public void ParseFromJson_SafeMethods()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[""balanceOf""],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = ContractManifest.CreateDefault(UInt160.Zero);

            check.SafeMethods = WildcardContainer <string> .Create("balanceOf");

            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #19
0
        public void ParseFromJson_Trust()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMethod"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":true}],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToJson().ToString(), json);

            var check = TestUtils.CreateDefaultManifest();

            check.Trusts = WildcardContainer <ContractPermissionDescriptor> .Create(ContractPermissionDescriptor.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")));

            Assert.AreEqual(manifest.ToJson().ToString(), check.ToJson().ToString());
        }
Пример #20
0
        public void ParseFromJson_Trust()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[""0x0000000000000000000000000000000000000001""],""safemethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = TestUtils.CreateDefaultManifest(UInt160.Zero);

            check.Trusts = WildcardContainer <UInt160> .Create(UInt160.Parse("0x0000000000000000000000000000000000000001"));

            Assert.AreEqual(manifest.ToString(), check.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 ParseFromJson_Groups()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[{""pubkey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safemethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = TestUtils.CreateDefaultManifest(UInt160.Zero);

            check.Groups = new ContractGroup[] { new ContractGroup()
                                                 {
                                                     PubKey = ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", ECCurve.Secp256r1), Signature = "41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".HexToBytes()
                                                 } };
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #23
0
        public void ParseFromJson_Groups()
        {
            var json     = @"{""groups"":[{""pubKey"":""03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"",""signature"":""QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==""}],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = ContractManifest.CreateDefault(UInt160.Zero);

            check.Groups = new ContractGroup[] { new ContractGroup()
                                                 {
                                                     PubKey = ECPoint.Parse("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c", ECCurve.Secp256r1), Signature = "41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".HexToBytes()
                                                 } };
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #24
0
        public void Init()
        {
            var _        = TestBlockchain.TheNeoSystem;
            var snapshot = new TestDataCache(null);

            _engine = new TestEngine(TriggerType.Application, snapshot: snapshot);
            _engine.AddEntryScript("./TestClasses/Contract_StdLib.cs");
            scriptHash = _engine.ScriptEntry.finalNEFScript.ToScriptHash();

            snapshot.ContractAdd(new ContractState()
            {
                Hash     = scriptHash,
                Nef      = _engine.ScriptEntry.nefFile,
                Manifest = ContractManifest.Parse(_engine.ScriptEntry.finalManifest)
            });
        }
Пример #25
0
        public void Init()
        {
            var _        = TestBlockchain.TheNeoSystem;
            var snapshot = Blockchain.Singleton.GetSnapshot().Clone();

            snapshot.BlockHashIndex.Get().Index = 1234;

            _engine = new TestEngine(TriggerType.Application, snapshot: snapshot);
            _engine.AddEntryScript("./TestClasses/Contract_Callback.cs");
            scriptHash = _engine.ScriptEntry.finalNEF.ToScriptHash();

            snapshot.Contracts.Add(scriptHash, new ContractState()
            {
                Script   = _engine.ScriptEntry.finalNEF,
                Manifest = ContractManifest.Parse(_engine.ScriptEntry.finalManifest)
            });
        }
Пример #26
0
        public void ParseFromJson_Permissions()
        {
            var json     = @"{""groups"":[],""features"":{""storage"":false,""payable"":false},""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""entryPoint"":{""name"":""Main"",""parameters"":[{""name"":""operation"",""type"":""String""},{""name"":""args"",""type"":""Array""}],""returnType"":""Any""},""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safeMethods"":[]}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = ContractManifest.CreateDefault(UInt160.Zero);

            check.Permissions = new[]
            {
                new ContractPermission()
                {
                    Contract = ContractPermissionDescriptor.Create(UInt160.Zero),
                    Methods  = WildCardContainer <string> .Create("method1", "method2")
                }
            };
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #27
0
        public void ParseFromJson_Permissions()
        {
            var json     = @"{""name"":""testManifest"",""groups"":[],""supportedstandards"":[],""abi"":{""hash"":""0x0000000000000000000000000000000000000000"",""methods"":[],""events"":[]},""permissions"":[{""contract"":""0x0000000000000000000000000000000000000000"",""methods"":[""method1"",""method2""]}],""trusts"":[],""safemethods"":[],""extra"":null}";
            var manifest = ContractManifest.Parse(json);

            Assert.AreEqual(manifest.ToString(), json);

            var check = TestUtils.CreateDefaultManifest(UInt160.Zero);

            check.Permissions = new[]
            {
                new ContractPermission()
                {
                    Contract = ContractPermissionDescriptor.Create(UInt160.Zero),
                    Methods  = WildcardContainer <string> .Create("method1", "method2")
                }
            };
            Assert.AreEqual(manifest.ToString(), check.ToString());
        }
Пример #28
0
        private static bool Contract_Create(ApplicationEngine engine)
        {
            if (engine.Trigger != TriggerType.Application)
            {
                return(false);
            }
            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }

            var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString();

            if (manifest.Length > ContractManifest.MaxLength)
            {
                return(false);
            }

            UInt160       hash     = script.ToScriptHash();
            ContractState contract = engine.Snapshot.Contracts.TryGet(hash);

            if (contract != null)
            {
                return(false);
            }
            contract = new ContractState
            {
                Script   = script,
                Manifest = ContractManifest.Parse(manifest)
            };

            if (!contract.Manifest.IsValid(hash))
            {
                return(false);
            }

            engine.Snapshot.Contracts.Add(hash, contract);
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(contract));
            return(true);
        }
Пример #29
0
        private ContractManifest ReadManifestFile(string manifestPath)
        {
            var maniFileInfo = new FileInfo(manifestPath);

            if (!maniFileInfo.Exists)
            {
                throw new WsException(ErrorCode.FileNotExist, $"Manifest file does not exist:{manifestPath}");
            }
            if (maniFileInfo.Length >= Transaction.MaxTransactionSize)
            {
                throw new WsException(ErrorCode.ExceedMaxTransactionSize);
            }
            try
            {
                return(ContractManifest.Parse(File.ReadAllBytes(manifestPath)));
            }
            catch (Exception)
            {
                throw new WsException(ErrorCode.InvalidManifestFile);
            }
        }
Пример #30
0
        private static bool Contract_Update(ApplicationEngine engine)
        {
            if (engine.Trigger != TriggerType.Application)
            {
                return(false);
            }

            byte[] script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
            if (script.Length > 1024 * 1024)
            {
                return(false);
            }
            var manifest = engine.CurrentContext.EvaluationStack.Pop().GetString();

            if (manifest.Length > ContractManifest.MaxLength)
            {
                return(false);
            }

            var contract = engine.Snapshot.Contracts.TryGet(engine.CurrentScriptHash);

            if (contract is null)
            {
                return(false);
            }

            if (script.Length > 0)
            {
                UInt160 hash_new = script.ToScriptHash();
                if (hash_new.Equals(engine.CurrentScriptHash))
                {
                    return(false);
                }
                if (engine.Snapshot.Contracts.TryGet(hash_new) != null)
                {
                    return(false);
                }
                contract = new ContractState
                {
                    Script   = script,
                    Manifest = contract.Manifest
                };
                contract.Manifest.Abi.Hash = hash_new;
                engine.Snapshot.Contracts.Add(hash_new, contract);
                if (contract.HasStorage)
                {
                    foreach (var pair in engine.Snapshot.Storages.Find(engine.CurrentScriptHash.ToArray()).ToArray())
                    {
                        engine.Snapshot.Storages.Add(new StorageKey
                        {
                            ScriptHash = hash_new,
                            Key        = pair.Key.Key
                        }, new StorageItem
                        {
                            Value      = pair.Value.Value,
                            IsConstant = false
                        });
                    }
                }
                Contract_Destroy(engine);
            }
            if (manifest.Length > 0)
            {
                contract          = engine.Snapshot.Contracts.GetAndChange(contract.ScriptHash);
                contract.Manifest = ContractManifest.Parse(manifest);
                if (!contract.Manifest.IsValid(contract.ScriptHash))
                {
                    return(false);
                }
            }

            return(true);
        }