/// <summary> /// Deploy Contract, return signed transaction /// </summary> /// <param name="contractScript">contract script</param> /// <param name="manifest">contract manifest</param> /// <param name="key">sender KeyPair</param> /// <returns></returns> public Transaction CreateDeployContractTx(byte[] contractScript, ContractManifest manifest, KeyPair key) { byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitSysCall(ApplicationEngine.System_Contract_Create, contractScript, manifest.ToString()); script = sb.ToArray(); } UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; Transaction tx = new TransactionManager(rpcClient) .MakeTransaction(script, signers) .AddSignature(key) .Sign() .Tx; return(tx); }
public void Test_InvocationCounter() { _engine.AddEntryScript("./TestClasses/Contract_Runtime.cs"); // We need a new TestEngine because invocationCounter it's shared between them var contract = _engine.EntryScriptHash; var engine = new TestEngine(TriggerType.Application, new DummyVerificable(), new TestDataCache()); engine.Snapshot.ContractAdd(new ContractState() { Hash = contract, Nef = _engine.Nef, Manifest = ContractManifest.FromJson(_engine.Manifest), }); using (ScriptBuilder sb = new()) { // First sb.EmitDynamicCall(contract, "getInvocationCounter"); // Second sb.EmitDynamicCall(contract, "getInvocationCounter"); engine.LoadScript(sb.ToArray()); } // Check Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(2, engine.ResultStack.Count); var item = engine.ResultStack.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0x02, item.GetInteger()); item = engine.ResultStack.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0x01, item.GetInteger()); }
public void TestGetContractState() { var sb = new ScriptBuilder(); sb.EmitSysCall(InteropService.System_Runtime_GetInvocationCounter); ContractState state = new ContractState { Script = new byte[] { (byte)OpCode.DROP, (byte)OpCode.DROP }.Concat(sb.ToArray()).ToArray(), Manifest = ContractManifest.CreateDefault(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01")) }; JObject response = CreateResponse(1); response["result"] = state.ToJson(); MockResponse(response.ToString()); var result = rpc.GetContractState("17694b31cc7ee215cea2ded146e0b2b28768fc46"); Assert.AreEqual(state.Script.ToHexString(), result.Script.ToHexString()); Assert.AreEqual(state.Manifest.Abi.EntryPoint.Name, result.Manifest.Abi.EntryPoint.Name); }
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.AddValt(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); 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; }
public void Test_InvocationCounter() { // We need a new TestEngine because invocationCounter it's shared between them var contract = _engine.EntryScriptHash; var engine = new TestEngine(TriggerType.Application, new DummyVerificable()); engine.Snapshot.Contracts.Add(contract, new Ledger.ContractState() { Script = _engine.InvocationStack.Peek().Script, Manifest = ContractManifest.FromJson(JObject.Parse(_engine.Build("./TestClasses/Contract_Runtime.cs").finalManifest)), }); using (ScriptBuilder sb = new ScriptBuilder()) { // First sb.EmitAppCall(contract, "getInvocationCounter"); // Second sb.EmitAppCall(contract, "getInvocationCounter"); engine.LoadScript(sb.ToArray()); } // Check Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(2, engine.ResultStack.Count); var item = engine.ResultStack.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0x02, item.GetInteger()); item = engine.ResultStack.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0x01, item.GetInteger()); }
public void TestContract_Create() { var engine = GetEngine(false, true); var script = new byte[1024 * 1024 + 1]; engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); string manifestStr = new string(new char[ContractManifest.MaxLength + 1]); script = new byte[] { 0x01 }; engine.CurrentContext.EvaluationStack.Push(manifestStr); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); var manifest = ContractManifest.CreateDefault(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01")); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); manifest.Abi.Hash = script.ToScriptHash(); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeTrue(); var mockSnapshot = new Mock <Snapshot>(); var state = TestUtils.GetContract(); mockSnapshot.SetupGet(p => p.Contracts).Returns(new TestDataCache <UInt160, ContractState>(state.ScriptHash, state)); engine = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0); engine.LoadScript(new byte[] { 0x01 }); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(state.Script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); }
public void TestContract_Create() { var engine = GetEngine(false, true); var script = new byte[1024 * 1024 + 1]; engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); string manifestStr = new string(new char[ContractManifest.MaxLength + 1]); script = new byte[] { 0x01 }; engine.CurrentContext.EvaluationStack.Push(manifestStr); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); var manifest = ContractManifest.CreateDefault(UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01")); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); manifest.Abi.Hash = script.ToScriptHash(); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeTrue(); var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract(); snapshot.Contracts.Add(state.ScriptHash, state); engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); engine.LoadScript(new byte[] { 0x01 }); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(state.Script); InteropService.Invoke(engine, InteropService.Neo_Contract_Create).Should().BeFalse(); }
public async Task TestDeployContract() { byte[] script; var manifest = new ContractManifest() { Permissions = new[] { ContractPermission.DefaultPermission }, Abi = new ContractAbi() { Hash = new byte[1].ToScriptHash(), Events = new ContractEventDescriptor[0], Methods = new ContractMethodDescriptor[0] }, Groups = new ContractGroup[0], SafeMethods = WildcardContainer <string> .Create(), Trusts = WildcardContainer <UInt160> .Create(), SupportedStandards = new string[] { "NEP-10" }, Extra = null, }; manifest.Features = ContractFeatures.HasStorage | ContractFeatures.Payable; using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitSysCall(ApplicationEngine.System_Contract_Create, new byte[1], manifest.ToString()); script = sb.ToArray(); } UT_TransactionManager.MockInvokeScript(rpcClientMock, script, new ContractParameter()); ContractClient contractClient = new ContractClient(rpcClientMock.Object); var result = await contractClient.CreateDeployContractTxAsync(new byte[1], manifest, keyPair1); Assert.IsNotNull(result); }
public void TestGetHash() { var temp = ContractManifest.CreateDefault(UInt160.Zero); Assert.AreEqual(temp.Abi.Hash, temp.Hash); }
public void TestIsAllowed() { ContractManifest contractManifest1 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission1 = ContractPermission.DefaultPermission; contractPermission1.Contract = ContractPermissionDescriptor.Create(UInt160.Zero); Assert.AreEqual(true, contractPermission1.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest1 }, "AAA")); contractPermission1.Contract = ContractPermissionDescriptor.CreateWildcard(); ContractManifest contractManifest2 = TestUtils.CreateDefaultManifest(); ContractPermission contractPermission2 = ContractPermission.DefaultPermission; contractPermission2.Contract = ContractPermissionDescriptor.Create(UInt160.Parse("0x0000000000000000000000000000000000000001")); Assert.AreEqual(false, contractPermission2.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest2 }, "AAA")); contractPermission2.Contract = ContractPermissionDescriptor.CreateWildcard(); Random random3 = new Random(); byte[] privateKey3 = new byte[32]; random3.NextBytes(privateKey3); ECPoint publicKey3 = ECCurve.Secp256r1.G * privateKey3; ContractManifest contractManifest3 = TestUtils.CreateDefaultManifest(); contractManifest3.Groups = new ContractGroup[] { new ContractGroup() { PubKey = publicKey3 } }; ContractPermission contractPermission3 = ContractPermission.DefaultPermission; contractPermission3.Contract = ContractPermissionDescriptor.Create(publicKey3); Assert.AreEqual(true, contractPermission3.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest3 }, "AAA")); contractPermission3.Contract = ContractPermissionDescriptor.CreateWildcard(); Random random4 = new Random(); byte[] privateKey41 = new byte[32]; random4.NextBytes(privateKey41); ECPoint publicKey41 = ECCurve.Secp256r1.G * privateKey41; byte[] privateKey42 = new byte[32]; random4.NextBytes(privateKey42); ECPoint publicKey42 = ECCurve.Secp256r1.G * privateKey42; ContractManifest contractManifest4 = TestUtils.CreateDefaultManifest(); contractManifest4.Groups = new ContractGroup[] { new ContractGroup() { PubKey = publicKey42 } }; ContractPermission contractPermission4 = ContractPermission.DefaultPermission; contractPermission4.Contract = ContractPermissionDescriptor.Create(publicKey41); Assert.AreEqual(false, contractPermission4.IsAllowed(new ContractState() { Hash = UInt160.Zero, Manifest = contractManifest4 }, "AAA")); contractPermission4.Contract = ContractPermissionDescriptor.CreateWildcard(); }
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) { 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); Check(nef.Script, parsedManifest.Abi); 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 entryScript = _engine.ScriptEntry; 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-1.0", Tokens = System.Array.Empty <MethodToken>() }; nef.CheckSum = NefFile.ComputeChecksum(nef); var hash = Helper.GetContractHash((_engine.ScriptContainer as Transaction).Sender, nef.CheckSum, manifest.Name); // 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(nef.ToJson().AsString(), itemArray[3].GetSpan().AsSerializable <NefFile>().ToJson().AsString()); // Nef var ritem = new ContractManifest(); ((IInteroperable)ritem).FromStackItem(itemArray[4]); Assert.AreEqual(manifest.ToString(), ritem.ToString()); // Manifest // Call _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "oldContract", (byte)CallFlags.All, 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", entryScript.nefFile); 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); }
public void Test_CreateCallDestroy() { // Create TestEngine engine = new(); engine.AddEntryScript("./TestClasses/Contract_Create.cs"); var manifest = ContractManifest.FromJson(engine.Manifest); var nef = new NefFile() { Script = engine.Nef.Script, Compiler = engine.Nef.Compiler, Source = engine.Nef.Source, Tokens = engine.Nef.Tokens }; nef.CheckSum = NefFile.ComputeChecksum(nef); var hash = Helper.GetContractHash((_engine.ScriptContainer as Transaction).Sender, nef.CheckSum, manifest.Name); // 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(nef.ToJson().AsString(), itemArray[3].GetSpan().ToArray().AsSerializable <NefFile>().ToJson().AsString()); // Nef var ritem = new ContractManifest(); ((IInteroperable)ritem).FromStackItem(itemArray[4]); Assert.AreEqual(manifest.ToString(), ritem.ToString()); // Manifest // Call _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "oldContract", (byte)CallFlags.All, new Array()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(ByteString)); Assert.AreEqual(manifest.Name, item.GetString()); // Destroy _engine.Reset(); result = _engine.ExecuteTestCaseStandard("destroy", _engine.Nef); 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); }
public async Task <object> DeployContract(string nefPath, string manifestPath = null, bool sendTx = false, UInt160 sender = null) { if (CurrentWallet == null) { return(Error(ErrorCode.WalletNotOpen)); } if (nefPath.IsNull()) { return(Error(ErrorCode.ParameterIsNull, "nefPath is empty.")); } if (manifestPath.IsNull()) { manifestPath = Path.ChangeExtension(nefPath, ".manifest.json"); } // Read nef NefFile nefFile = ReadNefFile(nefPath); // Read manifest ContractManifest manifest = ReadManifestFile(manifestPath); // Basic script checks await CheckBadOpcode(nefFile.Script); // Build script using ScriptBuilder sb = new ScriptBuilder(); sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nefFile.ToArray(), manifest.ToJson().ToString()); //sb.EmitAppCall(NativeContract.Management.Hash, "deploy", nefFile.ToArray(), manifest.ToJson().ToString()); var script = sb.ToArray(); Transaction tx; try { tx = CurrentWallet.MakeTransaction(Helpers.GetDefaultSnapshot(), script, sender); } catch (InvalidOperationException ex) { return(Error(ErrorCode.EngineFault, ex.GetExMessage())); } catch (Exception ex) { if (ex.Message.Contains("Insufficient GAS")) { return(Error(ErrorCode.GasNotEnough)); } throw; } UInt160 hash = SmartContract.Helper.GetContractHash(tx.Sender, nefFile.CheckSum, manifest.Name); var oldContract = hash.GetContract(); if (oldContract != null) { return(Error(ErrorCode.ContractAlreadyExist)); } var result = new DeployResultModel { ContractHash = hash, GasConsumed = new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals) }; if (sendTx) { var(signSuccess, context) = CurrentWallet.TrySignTx(tx); if (!signSuccess) { return(Error(ErrorCode.SignFail, context.SafeSerialize())); } await tx.Broadcast(); result.TxId = tx.Hash; } return(result); }
public void Runtime_GetNotifications_Test() { UInt160 scriptHash2; var snapshot = Blockchain.Singleton.GetSnapshot(); using (var script = new ScriptBuilder()) { // Drop arguments script.Emit(OpCode.NIP); // Notify method script.EmitSysCall(InteropService.Runtime.Notify); // Add return script.EmitPush(true); // Mock contract scriptHash2 = script.ToArray().ToScriptHash(); snapshot.Contracts.Delete(scriptHash2); snapshot.Contracts.Add(scriptHash2, new Neo.Ledger.ContractState() { Script = script.ToArray(), Manifest = ContractManifest.CreateDefault(scriptHash2), }); } // Wrong length using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true)) using (var script = new ScriptBuilder()) { // Retrive script.EmitPush(1); script.EmitSysCall(InteropService.Runtime.GetNotifications); // Execute engine.LoadScript(script.ToArray()); Assert.AreEqual(VMState.FAULT, engine.Execute()); } // All test using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true)) using (var script = new ScriptBuilder()) { // Notification 1 -> 13 script.EmitPush(13); script.EmitSysCall(InteropService.Runtime.Notify); // Call script script.EmitAppCall(scriptHash2, "test"); // Drop return script.Emit(OpCode.DROP); // Receive all notifications script.Emit(OpCode.PUSHNULL); script.EmitSysCall(InteropService.Runtime.GetNotifications); // Execute engine.LoadScript(script.ToArray()); var currentScriptHash = engine.EntryScriptHash; Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); Assert.AreEqual(2, engine.Notifications.Count); Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(VM.Types.Array)); var array = (VM.Types.Array)engine.ResultStack.Pop(); // Check syscall result AssertNotification(array[1], scriptHash2, "test"); AssertNotification(array[0], currentScriptHash, 13); // Check notifications Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash); Assert.AreEqual("test", engine.Notifications[1].State.GetString()); Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash); Assert.AreEqual(13, engine.Notifications[0].State.GetBigInteger()); } // Script notifications using (var engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0, true)) using (var script = new ScriptBuilder()) { // Notification 1 -> 13 script.EmitPush(13); script.EmitSysCall(InteropService.Runtime.Notify); // Call script script.EmitAppCall(scriptHash2, "test"); // Drop return script.Emit(OpCode.DROP); // Receive all notifications script.EmitPush(scriptHash2.ToArray()); script.EmitSysCall(InteropService.Runtime.GetNotifications); // Execute engine.LoadScript(script.ToArray()); var currentScriptHash = engine.EntryScriptHash; Assert.AreEqual(VMState.HALT, engine.Execute()); Assert.AreEqual(1, engine.ResultStack.Count); Assert.AreEqual(2, engine.Notifications.Count); Assert.IsInstanceOfType(engine.ResultStack.Peek(), typeof(VM.Types.Array)); var array = (VM.Types.Array)engine.ResultStack.Pop(); // Check syscall result AssertNotification(array[0], scriptHash2, "test"); // Check notifications Assert.AreEqual(scriptHash2, engine.Notifications[1].ScriptHash); Assert.AreEqual("test", engine.Notifications[1].State.GetString()); Assert.AreEqual(currentScriptHash, engine.Notifications[0].ScriptHash); Assert.AreEqual(13, engine.Notifications[0].State.GetBigInteger()); } // Clean storage snapshot.Contracts.Delete(scriptHash2); }
void ICloneable <ContractState> .FromReplica(ContractState replica) { Id = replica.Id; Script = replica.Script; Manifest = replica.Manifest.Clone(); }
public void Test_Update() { // Create var script = _engine.Build("./TestClasses/Contract_CreateAndUpdate.cs"); var manifest = ContractManifest.FromJson(JObject.Parse(script.finalManifest)); var scriptUpdate = _engine.Build("./TestClasses/Contract_Update.cs"); var manifestUpdate = ContractManifest.FromJson(JObject.Parse(scriptUpdate.finalManifest)); // Check first _engine.Reset(); var result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); Assert.AreEqual(0, result.Count); _engine.Reset(); _ = _engine.ExecuteTestCaseStandard("call", manifestUpdate.Hash.ToArray(), "newContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); // Create _engine.Reset(); result = _engine.ExecuteTestCaseStandard("create", script.finalNEF, 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(script.finalNEF, itemArray[0]); // Script Assert.AreEqual(manifest.ToString(), itemArray[1].GetString()); // Manifest Assert.AreEqual(false, itemArray[2]); // HasStorage Assert.AreEqual(false, itemArray[3]); // Payable // Call & Update _engine.Reset(); var args = new Array { scriptUpdate.finalNEF, manifestUpdate.ToJson().ToString() }; result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", args); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(123, item.GetInteger()); // Call Again _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", manifestUpdate.Hash.ToArray(), "newContract", new Array()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(124, item.GetInteger()); // Check again for failures _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); Assert.AreEqual(0, result.Count); }
void ISerializable.Deserialize(BinaryReader reader) { Id = reader.ReadInt32(); Script = reader.ReadVarBytes(); Manifest = reader.ReadSerializable <ContractManifest>(); }
private byte[] LoadDeploymentScript(string nefFilePath, string manifestFilePath, out NefFile nef, out ContractManifest manifest) { 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)); } manifest = ContractManifest.Parse(File.ReadAllBytes(manifestFilePath)); // Read nef info = new FileInfo(nefFilePath); if (!info.Exists || info.Length >= Transaction.MaxTransactionSize) { throw new ArgumentException(nameof(nefFilePath)); } using (var stream = new BinaryReader(File.OpenRead(nefFilePath), Utility.StrictUTF8, false)) { nef = stream.ReadSerializable <NefFile>(); } // Basic script checks Script script = new Script(nef.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 using (ScriptBuilder sb = new ScriptBuilder()) { sb.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", nef.ToArray(), manifest.ToJson().ToString()); return(sb.ToArray()); } }
public void Test_Update() { // Create var script = _engine.Build("./TestClasses/Contract_CreateAndUpdate.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); var scriptUpdate = _engine.Build("./TestClasses/Contract_Update.cs"); var manifestUpdate = ContractManifest.FromJson(JObject.Parse(scriptUpdate.finalManifest)); // 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 & Update _engine.Reset(); nef.Script = scriptUpdate.finalNEFScript; nef.CheckSum = NefFile.ComputeChecksum(nef); var args = new Array { nef.ToArray(), manifestUpdate.ToJson().ToString() }; result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "oldContract", args); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(123, item.GetInteger()); // Call Again _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "newContract", new Array()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(124, item.GetInteger()); // Check again for failures _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", hash.ToArray(), "oldContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); Assert.AreEqual(0, result.Count); }
public void TestGetSize() { var temp = ContractManifest.CreateDefault(UInt160.Zero); Assert.AreEqual(366, temp.Size); }
public void Test_Update() { // Create byte[] scriptUpdate; using (var scriptBuilder = new ScriptBuilder()) { // Drop arguments scriptBuilder.Emit(VM.OpCode.DROP); scriptBuilder.Emit(VM.OpCode.DROP); // Return 124 scriptBuilder.EmitPush(123); scriptBuilder.Emit(VM.OpCode.INC); scriptUpdate = scriptBuilder.ToArray(); } var manifestUpdate = ContractManifest.CreateDefault(scriptUpdate.ToScriptHash()); byte[] script; using (var scriptBuilder = new ScriptBuilder()) { // Drop arguments scriptBuilder.Emit(VM.OpCode.DROP); scriptBuilder.Emit(VM.OpCode.DROP); // Return 123 scriptBuilder.EmitPush(123); // Update scriptBuilder.EmitSysCall(InteropService.Neo_Contract_Update, scriptUpdate, manifestUpdate.ToJson().ToString()); script = scriptBuilder.ToArray(); } var manifest = ContractManifest.CreateDefault(script.ToScriptHash()); // Check first _engine.Reset(); var result = _engine.ExecuteTestCaseStandard("Call", manifest.Hash.ToArray()); Assert.AreEqual(VMState.FAULT, _engine.State); _engine.Reset(); result = _engine.ExecuteTestCaseStandard("Call", manifestUpdate.Hash.ToArray()); Assert.AreEqual(VMState.FAULT, _engine.State); // Create _engine.Reset(); result = _engine.ExecuteTestCaseStandard("Create", script, manifest.ToJson().ToString()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); var item = result.Pop(); Assert.IsInstanceOfType(item, typeof(InteropInterface <Ledger.ContractState>)); Assert.AreEqual(manifest.Hash, ((InteropInterface <Ledger.ContractState>)item).GetInterface <Ledger.ContractState>().ScriptHash); // Call & Update _engine.Reset(); result = _engine.ExecuteTestCaseStandard("Call", manifest.Hash.ToArray(), Null.Null, Null.Null); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(ByteArray)); Assert.AreEqual(123, item.GetBigInteger()); // Call Again _engine.Reset(); result = _engine.ExecuteTestCaseStandard("Call", manifestUpdate.Hash.ToArray(), Null.Null, Null.Null); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(124, item.GetBigInteger()); // Check again for failures _engine.Reset(); result = _engine.ExecuteTestCaseStandard("Call", manifest.Hash.ToArray()); Assert.AreEqual(VMState.FAULT, _engine.State); }
public void TestGenerator() { ContractManifest contractManifest = new ContractManifest(); Assert.IsNotNull(contractManifest); }
public async Task <object> UpdateContract(UInt160 contractHash, string nefPath, string manifestPath = null, bool sendTx = false, UInt160[] cosigners = null) { if (CurrentWallet == null) { return(Error(ErrorCode.WalletNotOpen)); } if (nefPath.IsNull()) { return(Error(ErrorCode.ParameterIsNull, "nefPath is empty.")); } if (manifestPath.IsNull()) { manifestPath = Path.ChangeExtension(nefPath, ".manifest.json"); } // Read nef NefFile nefFile = ReadNefFile(nefPath); // Read manifest ContractManifest manifest = ReadManifestFile(manifestPath); // Basic script checks await CheckBadOpcode(nefFile.Script); // Build script using ScriptBuilder sb = new ScriptBuilder(); sb.EmitDynamicCall(contractHash, "update", nefFile.ToArray(), manifest.ToJson().ToString(), null); var script = sb.ToArray(); var singers = new List <Signer> { }; if (cosigners != null) { singers.AddRange(cosigners.Select(s => new Signer() { Account = s, Scopes = WitnessScope.Global })); } Transaction tx; try { tx = CurrentWallet.MakeTransaction(Helpers.GetDefaultSnapshot(), script, null, singers.ToArray()); } catch (InvalidOperationException ex) { return(Error(ErrorCode.EngineFault, ex.GetExMessage())); } catch (Exception ex) { if (ex.Message.Contains("Insufficient GAS")) { return(Error(ErrorCode.GasNotEnough)); } throw; } var result = new DeployResultModel { ContractHash = contractHash, GasConsumed = new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals) }; if (sendTx) { var(signSuccess, context) = CurrentWallet.TrySignTx(tx); if (!signSuccess) { return(Error(ErrorCode.SignFail, context.SafeSerialize())); } await tx.Broadcast(); result.TxId = tx.Hash; } return(result); }
public void GetContract() { var contract = new ContractState() { Hash = new byte[] { 0x01, 0x02, 0x03 }.ToScriptHash(), Nef = new NefFile() { Script = new byte[] { 0x01, 0x02, 0x03 }, Compiler = "neon-test", Tokens = System.Array.Empty <MethodToken>() }, Manifest = new ContractManifest() { Name = "Name", SupportedStandards = System.Array.Empty <string>(), Groups = System.Array.Empty <ContractGroup>(), Trusts = WildcardContainer <ContractPermissionDescriptor> .Create(), Permissions = System.Array.Empty <ContractPermission>(), Abi = new ContractAbi() { Methods = System.Array.Empty <ContractMethodDescriptor>(), Events = System.Array.Empty <ContractEventDescriptor>(), }, } }; _engine.Snapshot.ContractAdd(contract); // Not found _engine.Reset(); var result = _engine.ExecuteTestCaseStandard("getContract", new ByteString(UInt160.Zero.ToArray()), new ByteString(new byte[20])); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); var item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Null)); // Found + Manifest _engine.Reset(); result = _engine.ExecuteTestCaseStandard("getContract", new ByteString(contract.Hash.ToArray()), new ByteString(Utility.StrictUTF8.GetBytes("Manifest"))); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Struct)); var ritem = new ContractManifest(); ((IInteroperable)ritem).FromStackItem(item); Assert.AreEqual(contract.Manifest.ToString(), ritem.ToString()); // Found + UpdateCounter _engine.Reset(); result = _engine.ExecuteTestCaseStandard("getContract", new ByteString(contract.Hash.ToArray()), new ByteString(Utility.StrictUTF8.GetBytes("UpdateCounter"))); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0, item.GetInteger()); // Found + Id _engine.Reset(); result = _engine.ExecuteTestCaseStandard("getContract", new ByteString(contract.Hash.ToArray()), new ByteString(Utility.StrictUTF8.GetBytes("Id"))); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(0, item.GetInteger()); // Found + Hash _engine.Reset(); result = _engine.ExecuteTestCaseStandard("getContract", new ByteString(contract.Hash.ToArray()), new ByteString(Utility.StrictUTF8.GetBytes("Hash"))); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(ByteString)); CollectionAssert.AreEqual(contract.Hash.ToArray(), item.GetSpan().ToArray()); // Found + Uknown property _engine.Reset(); _ = _engine.ExecuteTestCaseStandard("getContract", new ByteString(contract.Hash.ToArray()), new ByteString(Utility.StrictUTF8.GetBytes("ASD"))); Assert.AreEqual(VMState.FAULT, _engine.State); }
public void Test_Update() { // Create var script = _engine.Build("./TestClasses/Contract_CreateAndUpdate.cs"); var manifest = ContractManifest.FromJson(JObject.Parse(script.finalManifest)); var scriptUpdate = _engine.Build("./TestClasses/Contract_Update.cs"); var manifestUpdate = ContractManifest.FromJson(JObject.Parse(scriptUpdate.finalManifest)); // Check first _engine.Reset(); var result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); Assert.AreEqual(0, result.Count); _engine.Reset(); _ = _engine.ExecuteTestCaseStandard("call", manifestUpdate.Hash.ToArray(), "newContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); // Create _engine.Reset(); result = _engine.ExecuteTestCaseStandard("create", script.finalNEF, manifest.ToJson().ToString()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); var item = result.Pop(); Assert.IsTrue(item.Type == VM.Types.StackItemType.InteropInterface); var ledger = (item as InteropInterface).GetInterface <Ledger.ContractState>(); Assert.AreEqual(manifest.Hash, ledger.ScriptHash); // Call & Update _engine.Reset(); var args = new Array { scriptUpdate.finalNEF, manifestUpdate.ToJson().ToString() }; result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", args); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(123, item.GetBigInteger()); // Call Again _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", manifestUpdate.Hash.ToArray(), "newContract", new Array()); Assert.AreEqual(VMState.HALT, _engine.State); Assert.AreEqual(1, result.Count); item = result.Pop(); Assert.IsInstanceOfType(item, typeof(Integer)); Assert.AreEqual(124, item.GetBigInteger()); // Check again for failures _engine.Reset(); result = _engine.ExecuteTestCaseStandard("call", manifest.Hash.ToArray(), "oldContract", new Array()); Assert.AreEqual(VMState.FAULT, _engine.State); Assert.AreEqual(0, result.Count); }
public void TestContract_Update() { var engine = GetEngine(false, true); var script = new byte[1024 * 1024 + 1]; engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeFalse(); string manifestStr = new string(new char[ContractManifest.MaxLength + 1]); script = new byte[] { 0x01 }; engine.CurrentContext.EvaluationStack.Push(manifestStr); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeFalse(); manifestStr = ""; engine.CurrentContext.EvaluationStack.Push(manifestStr); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeFalse(); var manifest = ContractManifest.CreateDefault(script.ToScriptHash()); 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; byte[] signature = Crypto.Sign(script.ToScriptHash().ToArray(), privkey, pubkey.EncodePoint(false).Skip(1).ToArray()); manifest.Groups = new ContractGroup[] { new ContractGroup() { PubKey = pubkey, Signature = signature } }; var snapshot = Blockchain.Singleton.GetSnapshot(); var state = TestUtils.GetContract(); state.Manifest.Features = ContractFeatures.HasStorage; var storageItem = new StorageItem { Value = new byte[] { 0x01 }, IsConstant = false }; var storageKey = new StorageKey { ScriptHash = state.ScriptHash, Key = new byte[] { 0x01 } }; snapshot.Contracts.Add(state.ScriptHash, state); snapshot.Storages.Add(storageKey, storageItem); engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); engine.LoadScript(state.Script); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeTrue(); // Remove Storage flag with something stored state.Manifest.Features = ContractFeatures.NoProperty; snapshot.Contracts.Add(state.ScriptHash, state); snapshot.Storages.Add(storageKey, storageItem); engine = new ApplicationEngine(TriggerType.Application, null, snapshot, 0); engine.LoadScript(state.Script); engine.CurrentContext.EvaluationStack.Push(manifest.ToString()); engine.CurrentContext.EvaluationStack.Push(script); InteropService.Invoke(engine, InteropService.Neo_Contract_Update).Should().BeFalse(); }
public async Task <object> DeployContract(string nefPath, string manifestPath = null, bool sendTx = false) { if (CurrentWallet == null) { return(Error(ErrorCode.WalletNotOpen)); } if (nefPath.IsNull()) { return(Error(ErrorCode.ParameterIsNull, "nefPath is empty.")); } if (manifestPath.IsNull()) { manifestPath = Path.ChangeExtension(nefPath, ".manifest.json"); } // Read nef NefFile nefFile = ReadNefFile(nefPath); using var snapshot = Blockchain.Singleton.GetSnapshot(); var oldContract = snapshot.Contracts.TryGet(nefFile.ScriptHash); if (oldContract != null) { return(Error(ErrorCode.ContractAlreadyExist)); } // Read manifest ContractManifest manifest = ReadManifestFile(manifestPath); // Basic script checks await CheckBadOpcode(nefFile.Script); // Build script using ScriptBuilder sb = new ScriptBuilder(); sb.EmitSysCall(InteropService.Contract.Create, nefFile.Script, manifest.ToJson().ToString()); var script = sb.ToArray(); Transaction tx; try { tx = CurrentWallet.MakeTransaction(script); } catch (InvalidOperationException) { return(Error(ErrorCode.EngineFault)); } catch (Exception ex) { if (ex.Message.Contains("Insufficient GAS")) { return(Error(ErrorCode.GasNotEnough)); } throw; } var result = new DeployResultModel { ContractHash = nefFile.ScriptHash, GasConsumed = new BigDecimal(tx.SystemFee, NativeContract.GAS.Decimals) }; if (sendTx) { var(signSuccess, context) = CurrentWallet.TrySignTx(tx); if (!signSuccess) { return(Error(ErrorCode.SignFail, context.SafeSerialize())); } await tx.Broadcast(); result.TxId = tx.Hash; } return(result); }
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); }
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), Encoding.UTF8, false)) { file = stream.ReadSerializable <NefFile>(); } // Basic script checks using (var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 0, true)) { var context = engine.LoadScript(file.Script); while (context.InstructionPointer <= context.Script.Length) { // Check bad opcodes var ci = context.CurrentInstruction; if (ci == null || !Enum.IsDefined(typeof(OpCode), ci.OpCode)) { throw new FormatException($"OpCode not found at {context.InstructionPointer}-{((byte)ci.OpCode).ToString("x2")}"); } context.InstructionPointer += ci.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()); } }