public async Task <IActionResult> CallMethod([FromRoute] string address, [FromRoute] string method, [FromBody] JObject requestData) { var contractCode = this.stateRoot.GetCode(address.ToUint160(this.network)); Result <IContractAssembly> loadResult = this.loader.Load((ContractByteCode)contractCode); IContractAssembly assembly = loadResult.Value; Type type = assembly.DeployedType; MethodInfo methodInfo = type.GetMethod(method); if (methodInfo == null) { throw new Exception("Method does not exist on contract."); } ParameterInfo[] parameters = methodInfo.GetParameters(); if (!this.ValidateParams(requestData, parameters)) { throw new Exception("Parameters don't match method signature."); } // Map the JObject to the parameter + types expected by the call. string[] methodParams = parameters.Map(requestData); BuildCallContractTransactionRequest request = this.MapCallRequest(address, method, methodParams, this.Request.Headers); // Proxy to the actual SC controller. return(this.smartContractWalletController.Call(request)); }
/// <summary> /// Loads the contract bytecode and returns an <see cref="IContract"/> representing an uninitialized contract instance. /// </summary> private Result <IContract> Load( ContractByteCode byteCode, string typeName, uint160 address, ISmartContractState contractState) { Result <IContractAssembly> assemblyLoadResult = this.assemblyLoader.Load(byteCode); if (!assemblyLoadResult.IsSuccess) { return(Result.Fail <IContract>(assemblyLoadResult.Error)); } IContractAssembly contractAssembly = assemblyLoadResult.Value; Type type = contractAssembly.GetType(typeName); if (type == null) { return(Result.Fail <IContract>("Type not found!")); } IContract contract = Contract.CreateUninitialized(type, contractState, address); return(Result.Ok(contract)); }
public Task <IActionResult> ContractSwaggerDoc(string address) { var code = this.stateRepository.GetCode(address.ToUint160(this.network)); if (code == null) { throw new Exception("Contract does not exist"); } Result <IContractAssembly> assemblyLoadResult = this.loader.Load((ContractByteCode)code); if (assemblyLoadResult.IsFailure) { throw new Exception("Error loading assembly"); } IContractAssembly assembly = assemblyLoadResult.Value; // Default wallet is the first wallet as ordered by name. string defaultWalletName = this.walletmanager.GetWalletsNames().OrderBy(n => n).First(); // Default address is the first address with a balance, or string.Empty if no addresses have been created. // Ordering this way is consistent with the wallet UI, ie. whatever appears first in the wallet will appear first here. string defaultAddress = this.walletmanager.GetAccountAddressesWithBalance(defaultWalletName).FirstOrDefault()?.Address ?? string.Empty; var swaggerGen = new ContractSwaggerDocGenerator(this.options, address, assembly, defaultWalletName, defaultAddress); OpenApiDocument doc = swaggerGen.GetSwagger("contracts"); // TODO confirm v2/v3 var outputString = doc.Serialize(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json); return(Task.FromResult <IActionResult>(Ok(outputString))); }
public ContractSwaggerDocGenerator(SwaggerGeneratorOptions options, string address, IContractAssembly assembly, string defaultWalletName = "", string defaultSenderAddress = "") { this.options = options; this.address = address; this.assembly = assembly; this.defaultWalletName = defaultWalletName; this.defaultSenderAddress = defaultSenderAddress; }
public static IEnumerable <PropertyInfo> GetPublicGetterProperties(this IContractAssembly contractAssembly) { Type deployedType = contractAssembly.DeployedType; if (deployedType == null) { return(new List <PropertyInfo>()); } return(deployedType .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) .Where(p => p.GetGetMethod() != null)); }
/// <summary> /// Gets the public methods defined by the contract, ignoring property getters/setters. /// </summary> /// <returns></returns> public static IEnumerable <MethodInfo> GetPublicMethods(this IContractAssembly contractAssembly) { Type deployedType = contractAssembly.DeployedType; if (deployedType == null) { return(new List <MethodInfo>()); } return(deployedType .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance) // Get only the methods declared on the contract type .Where(m => !m.IsSpecialName)); // Ignore property setters/getters }
public void ContractAssemblyLoaderIsForwardCompatibleWithSmartContractAndStandardsUpdates() { // Create the byte code of a contract that contains new data types that are not (normally) supported by the current node. ContractCompilationResult result = ContractCompiler.Compile(this.testContract); byte[] bytes = result.Compilation; // Test that the node is able to load the futuristic contract. ContractAssemblyLoader loader = new ContractAssemblyLoader(); CSharpFunctionalExtensions.Result <IContractAssembly> result2 = loader.Load(new ContractByteCode(bytes)); IContractAssembly assembly = result2.Value; Assert.Equal("FruitVendor", assembly.Assembly.GetTypes().First().Name); }
/// <summary> /// Loads the contract bytecode and returns an <see cref="IContract"/> representing an uninitialized contract instance. /// </summary> private Result <IContract> Load( ContractByteCode byteCode, string typeName, uint160 address, ISmartContractState contractState) { Result <IContractAssembly> assemblyLoadResult = this.assemblyLoader.Load(byteCode); if (!assemblyLoadResult.IsSuccess) { this.logger.LogTrace(assemblyLoadResult.Error); return(Result.Fail <IContract>(assemblyLoadResult.Error)); } IContractAssembly contractAssembly = assemblyLoadResult.Value; Type type = contractAssembly.GetType(typeName); if (type == null) { const string typeNotFoundError = "Type not found!"; this.logger.LogTrace(typeNotFoundError); return(Result.Fail <IContract>(typeNotFoundError)); } IContract contract; try { contract = Contract.CreateUninitialized(type, contractState, address); } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(Result.Fail <IContract>("Exception occurred while instantiating contract instance")); } return(Result.Ok(contract)); }
/// <summary> /// Maps a contract assembly to its schemas. /// </summary> /// <param name="assembly"></param> /// <returns></returns> public IDictionary <string, OpenApiSchema> Map(IContractAssembly assembly) { return(this.Map(assembly.GetPublicMethods())); }
public void Separate_Threads_Have_Different_Observer_Instances() { // Create a contract assembly. ContractCompilationResult compilationResult = ContractCompiler.Compile(TestSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value; module.Rewrite(this.rewriter); CSharpFunctionalExtensions.Result <IContractAssembly> assemblyLoadResult = this.assemblyLoader.Load(module.ToByteCode()); IContractAssembly assembly = assemblyLoadResult.Value; var threadCount = 10; var observers = new Observer[threadCount]; var countdown = new CountdownEvent(threadCount); var threads = new Thread[threadCount]; for (var i = 0; i < threadCount; i++) { // Create a fake observer with a counter. var observer = new Observer(new GasMeter((Gas)1000000), new MemoryMeter(1000000)); observers[i] = observer; // Set a different observer on each thread. // Invoke the same method on each thread. Thread newThread = new Thread(() => { assembly.SetObserver(observer); Assert.Same(observer, assembly.GetObserver()); var callData = new MethodCall("TestMethod", new object[] { 1 }); IContract contract = Contract.CreateUninitialized(assembly.GetType(module.ContractType.Name), this.state, null); IContractInvocationResult result = contract.Invoke(callData); countdown.Signal(); }); newThread.Name = i.ToString(); threads[i] = newThread; } // Start the threads on a separate loop to ensure all time is spent on processing. foreach (Thread thread in threads) { thread.Start(); } countdown.Wait(); foreach (Observer observer in observers) { Assert.Equal(observers[0].GasMeter.GasConsumed, observer.GasMeter.GasConsumed); Assert.Equal(observers[0].MemoryMeter.MemoryConsumed, observer.MemoryMeter.MemoryConsumed); } }
public CachedAssemblyPackage(IContractAssembly assembly) { this.Assembly = assembly; }