public ReceiptResponse GetReceiptAPI([FromQuery] string txHash) { ReceiptResponse receiptResponse; uint256 txHashNum = new uint256(txHash); Receipt receipt = this.receiptRepository.Retrieve(txHashNum); if (receipt == null) { return(null); } uint160 address = receipt.NewContractAddress ?? receipt.To; if (!receipt.Logs.Any()) { receiptResponse = new ReceiptResponse(receipt, new List <LogResponse>(), this.network); } else { var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network, this.stateRoot, this.contractAssemblyCache); List <LogResponse> logResponses = deserializer.MapLogResponses(receipt.Logs); receiptResponse = new ReceiptResponse(receipt, logResponses, this.network); } return(receiptResponse); }
/// <inheritdoc /> public List <ReceiptResponse> ReceiptSearch(string contractAddress, string eventName, List <string> topics = null, int fromBlock = 0, int?toBlock = null) { uint160 address = contractAddress.ToUint160(this.network); byte[] contractCode = this.stateRoot.GetCode(address); if (contractCode == null || !contractCode.Any()) { return(null); } IEnumerable <byte[]> topicsBytes = topics != null?topics.Where(topic => topic != null).Select(t => t.HexToByteArray()) : new List <byte[]>(); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network, this.stateRoot, this.contractAssemblyCache); var receiptSearcher = new ReceiptSearcher(this.chainIndexer, this.blockStore, this.receiptRepository, this.network); List <Receipt> receipts = receiptSearcher.SearchReceipts(contractAddress, eventName, fromBlock, toBlock, topicsBytes); var result = new List <ReceiptResponse>(); foreach (Receipt receipt in receipts) { List <LogResponse> logResponses = deserializer.MapLogResponses(receipt.Logs); var receiptResponse = new ReceiptResponse(receipt, logResponses, this.network); result.Add(receiptResponse); } return(result); }
public void Deserialize_Logs_With_Different_Addresses_From_Cache() { var network = new SmartContractsRegTest(); var primitiveSerializer = new ContractPrimitiveSerializer(network); var testStruct0 = new TestLog { Name = "Test", Value128 = 123, Value256 = 456 }; var testStruct1 = new TestLog { Name = "Test 2", Value128 = 789, Value256 = 101112 }; var testBytes = primitiveSerializer.Serialize(testStruct0); var logs = new Log[] { new Log(uint160.Zero, new List <byte[]> { Encoding.UTF8.GetBytes("TestLog") }, primitiveSerializer.Serialize(testStruct0)), new Log(uint160.One, new List <byte[]> { Encoding.UTF8.GetBytes("TestLog") }, primitiveSerializer.Serialize(testStruct1)), }; var stateRoot = new Mock <IStateRepositoryRoot>(); stateRoot.Setup(r => r.GetCodeHash(It.IsAny <uint160>())).Returns(uint256.Zero.ToBytes()); var assemblyCache = new Mock <IContractAssemblyCache>(); var contractAssembly = new Mock <IContractAssembly>(); // Return this assembly as it will contain the TestLog type. contractAssembly.Setup(s => s.Assembly).Returns(Assembly.GetExecutingAssembly()); assemblyCache.Setup(s => s.Retrieve(It.IsAny <uint256>())).Returns(new CachedAssemblyPackage(contractAssembly.Object)); var serializer = new ApiLogDeserializer(primitiveSerializer, network, stateRoot.Object, assemblyCache.Object); var responses = serializer.MapLogResponses(logs); // Verify that we deserialized the logs correctly. Assert.Equal(testStruct0.Name, ((dynamic)responses[0].Log).Name); Assert.Equal(testStruct1.Name, ((dynamic)responses[1].Log).Name); // Verify that we got the code for both log assemblies. stateRoot.Verify(s => s.GetCodeHash(logs[0].Address), Times.Once); stateRoot.Verify(s => s.GetCodeHash(logs[1].Address), Times.Once); }
public IActionResult LocalCallSmartContractTransaction([FromBody] LocalCallContractRequest request) { if (!this.ModelState.IsValid) { return(ModelStateErrors.BuildErrorResponse(this.ModelState)); } // Rewrite the method name to a property name this.RewritePropertyGetterName(request); try { ContractTxData txData = this.smartContractTransactionService.BuildLocalCallTxData(request); var height = request.BlockHeight.HasValue ? request.BlockHeight.Value : (ulong)this.chainIndexer.Height; ILocalExecutionResult result = this.localExecutor.Execute( height, request.Sender?.ToUint160(this.network) ?? new uint160(), !string.IsNullOrWhiteSpace(request.Amount) ? (Money)request.Amount : 0, txData); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network, result.StateRoot, this.contractAssemblyCache); var response = new LocalExecutionResponse { InternalTransfers = deserializer.MapTransferInfo(result.InternalTransfers.ToArray()), Logs = deserializer.MapLogResponses(result.Logs.ToArray()), GasConsumed = result.GasConsumed, Revert = result.Revert, ErrorMessage = result.ErrorMessage, Return = result.Return // All return values should be primitives, let default serializer handle. }; return(this.Json(response, new JsonSerializerSettings { ContractResolver = new ContractParametersContractResolver(this.network) })); } catch (MethodParameterStringSerializerException e) { return(this.Json(ErrorHelpers.BuildErrorResponse(HttpStatusCode.InternalServerError, e.Message, "Error deserializing method parameters"))); } }
public IActionResult GetContractInfo([FromQuery] string txHash) { try { uint256 txHashNum = new uint256(txHash); Receipt receipt = this.receiptRepository.Retrieve(txHashNum); if (receipt == null) { return(null); } uint160 address = receipt.NewContractAddress ?? receipt.To; string typeName = null; byte[] contractCode = null; uint256 codeHash = null; string csharpCode = null; ulong balance = 0; if (address != null) { IStateRepositoryRoot stateAtHeight = this.stateRoot.GetSnapshotTo(receipt.PostState.ToBytes()); AccountState accountState = stateAtHeight.GetAccountState(address); if (accountState != null) { typeName = accountState.TypeName; balance = stateAtHeight.GetCurrentBalance(address); if (receipt.NewContractAddress != null) { codeHash = new uint256(accountState.CodeHash); contractCode = this.stateRoot.GetCode(receipt.NewContractAddress); Result <string> sourceResult = this.contractDecompiler.GetSource(contractCode); csharpCode = sourceResult.IsSuccess ? sourceResult.Value : sourceResult.Error; } } else { typeName = this.stateRoot.GetAccountState(address)?.TypeName; } } List <LogResponse> logResponses = new List <LogResponse>(); if (receipt.Logs.Any()) { var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network, this.stateRoot, this.contractAssemblyCache); logResponses = deserializer.MapLogResponses(receipt.Logs); } var logEnrichment = contractEnrichmentFactory.GetLogEnrichment(typeName); logEnrichment?.EnrichLogs(receipt, logResponses); return(this.Json(new ContractReceiptResponse(receipt, logResponses, this.network) { ContractCodeType = typeName, ContractBalance = balance, ContractCodeHash = codeHash?.ToString(), ContractBytecode = contractCode?.ToHexString(), ContractCSharp = csharpCode })); } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString())); } }