/// <inheritdoc /> public IContractInvocationResult InvokeConstructor(IReadOnlyList <object> parameters) { // If it's a constructor we need to append the ISmartContractState to the start of the parameters array object[] invokeParams = { this.State }; if (parameters != null) { invokeParams = invokeParams.Concat(parameters).ToArray(); } Type[] types = invokeParams.Select(p => p.GetType()).ToArray(); ConstructorInfo methodToInvoke = this.Type.GetConstructor(types); if (methodToInvoke == null) { return(ContractInvocationResult.Failure(ContractInvocationErrorType.MethodDoesNotExist)); } IContractInvocationResult result = this.InvokeInternal(methodToInvoke, invokeParams); this.initialized = result.IsSuccess; return(result); }
public void SmartContracts_GasInjector_SingleParamConstructorGasInjectedSuccess() { ContractCompilationResult compilationResult = ContractCompiler.Compile(TestSingleConstructorSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.InvokeConstructor(null); // TODO: Un-hard-code this. // Constructor: 15 // Property setter: 12 // Storage: 150 // "string newString = this.Owner + 1;": 36 Assert.Equal((Gas)213, this.gasMeter.GasConsumed); }
public void TestGasInjector_OutOfGasFails() { ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/OutOfGasTest.cs"); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var callData = new MethodCall("UseAllGas"); IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); // Because our contract contains an infinite loop, we want to kill our test after // some amount of time without achieving a result. 3 seconds is an arbitrarily high enough timeout // for the method body to have finished execution while minimising the amount of time we spend // running tests // If you're running with the debugger on this will obviously be a source of failures IContractInvocationResult result = TimeoutHelper.RunCodeWithTimeout(5, () => contract.Invoke(callData)); Assert.False(result.IsSuccess); Assert.Equal((RuntimeObserver.Gas) 0, this.gasMeter.GasAvailable); Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed); Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed); }
public void TestGasInjector_OutOfGasFails() { SmartContractCompilationResult compilationResult = SmartContractCompiler.CompileFile("SmartContracts/OutOfGasTest.cs"); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var callData = new MethodCall("UseAllGas"); IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes); module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.Invoke(callData); Assert.False(result.IsSuccess); Assert.Equal((Gas)0, this.gasMeter.GasAvailable); Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed); Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed); }
public void TestGasInjector_ContractMethodWithRecursion_GasInjectionSucceeds() { ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/Recursion.cs"); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var callData = new MethodCall(nameof(Recursion.DoRecursion)); IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); assembly.Value.SetObserver(new Observer(this.gasMeter, new MemoryMeter(ReflectionVirtualMachine.MemoryUnitLimit))); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.Invoke(callData); Assert.True(result.IsSuccess); Assert.True(this.gasMeter.GasConsumed > 0); }
private void AssertPasses(IContract contract, string methodName) { var callData = new MethodCall(methodName); IContractInvocationResult result = contract.Invoke(callData); Assert.True(result.IsSuccess); }
private void AssertFailsDueToMemory(IContract contract, string methodName) { var callData = new MethodCall(methodName); IContractInvocationResult result = contract.Invoke(callData); Assert.False(result.IsSuccess); Assert.Equal(ContractInvocationErrorType.OverMemoryLimit, result.InvocationErrorType); }
public void Invoke_Method_With_Null_Params() { var methodCall = new MethodCall("Test1"); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.True(result.IsSuccess); Assert.True(this.instance.Test1Called); Assert.Equal(0, this.instance.ConstructorCalledCount); }
public void Invoke_Private_Method_Fails() { var methodCall = new MethodCall("TestPrivate"); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.Equal(ContractInvocationErrorType.MethodDoesNotExist, result.InvocationErrorType); }
public void Invoke_Method_Throws_OutOfGasException() { var methodCall = new MethodCall("TestOutOfGas"); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.Equal(ContractInvocationErrorType.OutOfGas, result.InvocationErrorType); }
public void EmptyMethodName_DoesNot_Invoke_Receive() { IContract receiveContract = Contract.CreateUninitialized(typeof(HasNoReceive), this.state, this.address); var methodCall = MethodCall.Receive(); IContractInvocationResult result = receiveContract.Invoke(methodCall); Assert.False(result.IsSuccess); }
public void Invoke_Method_With_Empty_Optional_Param() { // Method binding should fail when a method has an optional param that is not provided var methodCall = new MethodCall("TestOptionalParam"); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.Equal(ContractInvocationErrorType.MethodDoesNotExist, result.InvocationErrorType); }
public void Invoke_Method_With_Null_Param() { var param = (string)null; var methodCall = new MethodCall("Test2", new object[] { param }); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.Equal(ContractInvocationErrorType.ParameterTypesDontMatch, result.InvocationErrorType); }
public void Invoke_Constructor_With_Null_Params() { IContractInvocationResult result = this.contract.InvokeConstructor(null); Assert.Equal(ContractInvocationErrorType.None, result.InvocationErrorType); Assert.True(result.IsSuccess); // We expect the count to be 2 because we call the constructor when setting up the test as well Assert.Equal(1, this.instance.ConstructorCalledCount); Assert.Equal(this.state, this.instance.State); }
public void Invoke_Method_With_One_Params() { var param = 9999; var methodCall = new MethodCall("Test2", new object[] { param }); IContractInvocationResult result = this.contract.Invoke(methodCall); Assert.True(result.IsSuccess); Assert.Equal(param, result.Return); }
public void EmptyMethodName_Invokes_Receive() { IContract receiveContract = Contract.CreateUninitialized(typeof(HasReceive), this.state, this.address); var receiveInstance = (HasReceive)receiveContract.GetPrivateFieldValue("instance"); var methodCall = MethodCall.Receive(); IContractInvocationResult result = receiveContract.Invoke(methodCall); Assert.True(result.IsSuccess); Assert.True(receiveInstance.ReceiveInvoked); }
public void Non_Existent_Method_DoesNot_Invoke_Receive() { IContract receiveContract = Contract.CreateUninitialized(typeof(HasReceive), this.state, this.address); var receiveInstance = (HasReceive)receiveContract.GetPrivateFieldValue("instance"); var methodCall = new MethodCall("DoesntExist"); IContractInvocationResult result = receiveContract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.False(receiveInstance.ReceiveInvoked); Assert.Equal(ContractInvocationErrorType.MethodDoesNotExist, result.InvocationErrorType); }
/// <summary> /// Invokes a method on an existing smart contract /// </summary> public VmExecutionResult ExecuteMethod(ISmartContractState contractState, RuntimeObserver.IGasMeter gasMeter, MethodCall methodCall, byte[] contractCode, string typeName) { ContractByteCode code; // Code we're loading from database - can assume it's valid. using (IContractModuleDefinition moduleDefinition = this.moduleDefinitionReader.Read(contractCode).Value) { var observer = new Observer(gasMeter, new MemoryMeter(MemoryUnitLimit)); var rewriter = new ObserverRewriter(observer); if (!this.Rewrite(moduleDefinition, rewriter)) { return(VmExecutionResult.Fail(VmExecutionErrorKind.RewriteFailed, "Rewrite module failed")); } Result <ContractByteCode> getCodeResult = this.GetByteCode(moduleDefinition); if (!getCodeResult.IsSuccess) { return(VmExecutionResult.Fail(VmExecutionErrorKind.RewriteFailed, "Serialize module failed")); } code = getCodeResult.Value; } Result <IContract> contractLoadResult = this.Load( code, typeName, contractState.Message.ContractAddress.ToUint160(), contractState); if (!contractLoadResult.IsSuccess) { return(VmExecutionResult.Fail(VmExecutionErrorKind.LoadFailed, contractLoadResult.Error)); } IContract contract = contractLoadResult.Value; this.LogExecutionContext(contract.State.Block, contract.State.Message, contract.Address); IContractInvocationResult invocationResult = contract.Invoke(methodCall); if (!invocationResult.IsSuccess) { this.logger.LogTrace("(-)[CALLCONTRACT_INSTANTIATION_FAILED]"); return(GetInvocationVmErrorResult(invocationResult)); } this.logger.LogTrace("[CALL_CONTRACT_INSTANTIATION_SUCCEEDED]"); return(VmExecutionResult.Ok(invocationResult.Return, typeName)); }
public void Invoke_Constructor_With_Too_Many_Params_None_Correct() { IContractInvocationResult result = this.contract.InvokeConstructor( new List <object> { "123", "abc" }); Assert.Equal(ContractInvocationErrorType.MethodDoesNotExist, result.InvocationErrorType); Assert.False(result.IsSuccess); Assert.Equal(0, this.instance.ConstructorCalledCount); }
public void EmptyMethodName_WithParams_DoesNot_Invoke_Receive() { IContract receiveContract = Contract.CreateUninitialized(typeof(HasReceive), this.state, this.address); var receiveInstance = (HasReceive)receiveContract.GetPrivateFieldValue("instance"); var parameters = new object[] { 1, "1" }; var methodCall = new MethodCall(MethodCall.ExternalReceiveHandlerName, parameters); IContractInvocationResult result = receiveContract.Invoke(methodCall); Assert.False(result.IsSuccess); Assert.False(receiveInstance.ReceiveInvoked); Assert.Equal(ContractInvocationErrorType.MethodDoesNotExist, result.InvocationErrorType); }
public void Invoke_Constructor_With_One_Params() { var param = 99999; IContractInvocationResult result = this.contract.InvokeConstructor(new List <object> { param }); Assert.Equal(ContractInvocationErrorType.None, result.InvocationErrorType); Assert.True(result.IsSuccess); Assert.Equal(1, this.instance.ConstructorCalledCount); Assert.Equal(param, this.instance.Param); Assert.Equal(this.state, this.instance.State); }
private static VmExecutionResult GetInvocationVmErrorResult(IContractInvocationResult invocationResult) { if (invocationResult.InvocationErrorType == ContractInvocationErrorType.OutOfGas) { return(VmExecutionResult.Fail(VmExecutionErrorKind.OutOfGas, invocationResult.ErrorMessage)); } if (invocationResult.InvocationErrorType == ContractInvocationErrorType.OverMemoryLimit) { return(VmExecutionResult.Fail(VmExecutionErrorKind.OutOfResources, invocationResult.ErrorMessage)); } return(VmExecutionResult.Fail(VmExecutionErrorKind.InvocationFailed, invocationResult.ErrorMessage)); }
/// <summary> /// Invokes a method on an existing smart contract /// </summary> public VmExecutionResult ExecuteMethod(ISmartContractState contractState, MethodCall methodCall, byte[] contractCode, string typeName) { this.logger.LogTrace("(){0}:{1}", nameof(methodCall.Name), methodCall.Name); ContractByteCode code; // Code we're loading from database - can assume it's valid. using (IContractModuleDefinition moduleDefinition = this.moduleDefinitionReader.Read(contractCode).Value) { var observer = new Observer(contractState.GasMeter, MemoryUnitLimit); var rewriter = new ObserverRewriter(observer); moduleDefinition.Rewrite(rewriter); code = moduleDefinition.ToByteCode(); } Result <IContract> contractLoadResult = this.Load( code, typeName, contractState.Message.ContractAddress.ToUint160(this.network), contractState); if (!contractLoadResult.IsSuccess) { LogErrorMessage(contractLoadResult.Error); this.logger.LogTrace("(-)[LOAD_CONTRACT_FAILED]"); return(VmExecutionResult.Fail(VmExecutionErrorKind.LoadFailed, contractLoadResult.Error)); } IContract contract = contractLoadResult.Value; LogExecutionContext(this.logger, contract.State.Block, contract.State.Message, contract.Address); IContractInvocationResult invocationResult = contract.Invoke(methodCall); if (!invocationResult.IsSuccess) { this.logger.LogTrace("(-)[CALLCONTRACT_INSTANTIATION_FAILED]"); return(GetInvocationVmErrorResult(invocationResult)); } this.logger.LogTrace("[CALL_CONTRACT_INSTANTIATION_SUCCEEDED]"); this.logger.LogTrace("(-)"); return(VmExecutionResult.Ok(invocationResult.Return, typeName)); }
/// <summary> /// Invokes a method on an existing smart contract /// </summary> public VmExecutionResult ExecuteMethod(ISmartContractState contractState, MethodCall methodCall, byte[] contractCode, string typeName) { this.logger.LogTrace("(){0}:{1}", nameof(methodCall.Name), methodCall.Name); ContractByteCode code; using (IContractModuleDefinition moduleDefinition = this.moduleDefinitionReader.Read(contractCode)) { moduleDefinition.InjectMethodGas(typeName, methodCall); code = moduleDefinition.ToByteCode(); } Result <IContract> contractLoadResult = this.Load( code, typeName, contractState.Message.ContractAddress.ToUint160(this.network), contractState); if (!contractLoadResult.IsSuccess) { // TODO this is temporary until we improve error handling overloads var exception = new Exception(contractLoadResult.Error); LogException(exception); this.logger.LogTrace("(-)[LOAD_CONTRACT_FAILED]"); return(VmExecutionResult.Error(exception)); } IContract contract = contractLoadResult.Value; LogExecutionContext(this.logger, contract.State.Block, contract.State.Message, contract.Address); IContractInvocationResult invocationResult = contract.Invoke(methodCall); if (!invocationResult.IsSuccess) { this.logger.LogTrace("(-)[CALLCONTRACT_INSTANTIATION_FAILED]"); return(VmExecutionResult.Error(new Exception("Method invocation failed!"))); } this.logger.LogTrace("[CALL_CONTRACT_INSTANTIATION_SUCCEEDED]"); this.logger.LogTrace("(-)"); return(VmExecutionResult.Success(invocationResult.Return, typeName)); }
public void TestGasInjector_NestedType_GasInjectionSucceeds() { ContractCompilationResult compilationResult = ContractCompiler.Compile(@" using System; using Stratis.SmartContracts; public class Test : SmartContract { public Test(ISmartContractState state): base(state) { var other = new Other.NestedOther(); other.Loop(); } } public static class Other { public struct NestedOther { public void Loop() { while(true) {}} } } "); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); assembly.Value.SetObserver(new Observer(this.gasMeter, new MemoryMeter(ReflectionVirtualMachine.MemoryUnitLimit))); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.InvokeConstructor(null); Assert.False(result.IsSuccess); Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed); }
public void SmartContracts_GasInjector_MultipleParamConstructorGasInjectedSuccess() { ContractCompilationResult compilationResult = ContractCompiler.Compile(TestMultipleConstructorSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.InvokeConstructor(new[] { "Test Owner" }); // Number here shouldn't be hardcoded - note this is really only to let us know of consensus failure Assert.Equal((RuntimeObserver.Gas) 328, this.gasMeter.GasConsumed); }
public void TestGasInjector() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(AppContext.BaseDirectory); int aimGasAmount; using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule( new MemoryStream(originalAssemblyBytes), new ReaderParameters { AssemblyResolver = resolver })) { TypeDefinition contractType = moduleDefinition.GetType(ContractName); MethodDefinition testMethod = contractType.Methods.FirstOrDefault(x => x.Name == MethodName); aimGasAmount = testMethod?.Body?.Instructions? .Count ?? 10000000; } var callData = new MethodCall("TestMethod", new object[] { 1 }); IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes); module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.Invoke(callData); Assert.Equal((ulong)aimGasAmount, this.state.GasMeter.GasConsumed); }
public void TestGasInjector() { ContractCompilationResult compilationResult = ContractCompiler.Compile(TestSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(AppContext.BaseDirectory); using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule( new MemoryStream(originalAssemblyBytes), new ReaderParameters { AssemblyResolver = resolver })) { TypeDefinition contractType = moduleDefinition.GetType(ContractName); MethodDefinition testMethod = contractType.Methods.FirstOrDefault(x => x.Name == MethodName); } var callData = new MethodCall("TestMethod", new object[] { 1 }); IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode()); assembly.Value.SetObserver(new Observer(this.gasMeter, new MemoryMeter(ReflectionVirtualMachine.MemoryUnitLimit))); IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.Invoke(callData); // Number here shouldn't be hardcoded - note this is really only to let us know of consensus failure Assert.Equal(22uL, this.gasMeter.GasConsumed); }
/// <summary> /// Creates a new instance of a smart contract by invoking the contract's constructor /// </summary> public VmExecutionResult Create(IStateRepository repository, ISmartContractState contractState, byte[] contractCode, object[] parameters, string typeName = null) { this.logger.LogTrace("()"); string typeToInstantiate; ContractByteCode code; // Decompile the contract execution code Result <IContractModuleDefinition> moduleResult = this.moduleDefinitionReader.Read(contractCode); if (moduleResult.IsFailure) { this.logger.LogTrace("(-)[CONTRACT_BYTECODE_INVALID]"); return(VmExecutionResult.Error(new ContractErrorMessage("Contract bytecode is not valid IL."))); } // Validate contract execution code using (IContractModuleDefinition moduleDefinition = moduleResult.Value) { SmartContractValidationResult validation = moduleDefinition.Validate(this.validator); // If validation failed, refund the sender any remaining gas. if (!validation.IsValid) { this.logger.LogTrace("(-)[CONTRACT_VALIDATION_FAILED]"); // TODO: List errors by string. return(VmExecutionResult.Error(new ContractErrorMessage(new SmartContractValidationException(validation.Errors).ToString()))); } typeToInstantiate = typeName ?? moduleDefinition.ContractType.Name; var observer = new Observer(contractState.GasMeter, MemoryUnitLimit); var rewriter = new ObserverRewriter(observer); moduleDefinition.Rewrite(rewriter); code = moduleDefinition.ToByteCode(); } Result <IContract> contractLoadResult = this.Load( code, typeToInstantiate, contractState.Message.ContractAddress.ToUint160(this.network), contractState); if (!contractLoadResult.IsSuccess) { LogErrorMessage(contractLoadResult.Error); this.logger.LogTrace("(-)[LOAD_CONTRACT_FAILED]"); return(VmExecutionResult.Error(new ContractErrorMessage(contractLoadResult.Error))); } IContract contract = contractLoadResult.Value; LogExecutionContext(this.logger, contract.State.Block, contract.State.Message, contract.Address); // Set the code and the Type before the method is invoked repository.SetCode(contract.Address, contractCode); repository.SetContractType(contract.Address, typeToInstantiate); // Invoke the constructor of the provided contract code IContractInvocationResult invocationResult = contract.InvokeConstructor(parameters); if (!invocationResult.IsSuccess) { this.logger.LogTrace("[CREATE_CONTRACT_INSTANTIATION_FAILED]"); return(VmExecutionResult.Error(invocationResult.ErrorMessage)); } this.logger.LogTrace("[CREATE_CONTRACT_INSTANTIATION_SUCCEEDED]"); this.logger.LogTrace("(-):{0}={1}", nameof(contract.Address), contract.Address); return(VmExecutionResult.Success(invocationResult.Return, typeToInstantiate)); }
/// <summary> /// Creates a new instance of a smart contract by invoking the contract's constructor /// </summary> public VmExecutionResult Create(IStateRepository repository, ISmartContractState contractState, RuntimeObserver.IGasMeter gasMeter, byte[] contractCode, object[] parameters, string typeName = null) { string typeToInstantiate; ContractByteCode code; // Decompile the contract execution code Result <IContractModuleDefinition> moduleResult = this.moduleDefinitionReader.Read(contractCode); if (moduleResult.IsFailure) { this.logger.LogTrace(moduleResult.Error); this.logger.LogTrace("(-)[CONTRACT_BYTECODE_INVALID]"); return(VmExecutionResult.Fail(VmExecutionErrorKind.LoadFailed, "Contract bytecode is not valid IL.")); } // Validate contract execution code using (IContractModuleDefinition moduleDefinition = moduleResult.Value) { SmartContractValidationResult validation = moduleDefinition.Validate(this.validator); // If validation failed, refund the sender any remaining gas. if (!validation.IsValid) { this.logger.LogTrace("(-)[CONTRACT_VALIDATION_FAILED]"); return(VmExecutionResult.Fail(VmExecutionErrorKind.ValidationFailed, new SmartContractValidationException(validation.Errors).ToString())); } typeToInstantiate = typeName ?? moduleDefinition.ContractType.Name; var observer = new Observer(gasMeter, new MemoryMeter(MemoryUnitLimit)); var rewriter = new ObserverRewriter(observer); if (!this.Rewrite(moduleDefinition, rewriter)) { return(VmExecutionResult.Fail(VmExecutionErrorKind.RewriteFailed, "Rewrite module failed")); } Result <ContractByteCode> getCodeResult = this.GetByteCode(moduleDefinition); if (!getCodeResult.IsSuccess) { return(VmExecutionResult.Fail(VmExecutionErrorKind.RewriteFailed, "Serialize module failed")); } code = getCodeResult.Value; } Result <IContract> contractLoadResult = this.Load( code, typeToInstantiate, contractState.Message.ContractAddress.ToUint160(), contractState); if (!contractLoadResult.IsSuccess) { return(VmExecutionResult.Fail(VmExecutionErrorKind.LoadFailed, contractLoadResult.Error)); } IContract contract = contractLoadResult.Value; this.LogExecutionContext(contract.State.Block, contract.State.Message, contract.Address); // Set the code and the Type before the method is invoked repository.SetCode(contract.Address, contractCode); repository.SetContractType(contract.Address, typeToInstantiate); // Invoke the constructor of the provided contract code IContractInvocationResult invocationResult = contract.InvokeConstructor(parameters); if (!invocationResult.IsSuccess) { this.logger.LogTrace("[CREATE_CONTRACT_INSTANTIATION_FAILED]"); return(GetInvocationVmErrorResult(invocationResult)); } this.logger.LogTrace("[CREATE_CONTRACT_INSTANTIATION_SUCCEEDED]"); return(VmExecutionResult.Ok(invocationResult.Return, typeToInstantiate)); }