public ReceiptResponse GetReceiptRPC(string txHash) { 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()) { return(new ReceiptResponse(receipt, new List <LogResponse>(), this.network)); } byte[] contractCode = this.stateRoot.GetCode(address); Assembly assembly = Assembly.Load(contractCode); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network); List <LogResponse> logResponses = this.MapLogResponses(receipt, assembly, deserializer); return(new ReceiptResponse(receipt, logResponses, this.network)); }
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[]>(); Assembly assembly = Assembly.Load(contractCode); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network); 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 = this.MapLogResponses(receipt, assembly, deserializer); var receiptResponse = new ReceiptResponse(receipt, logResponses, this.network); result.Add(receiptResponse); } return(result); }
public void Deserialize_Basic_Log_Success() { var network = new SmartContractsPoATest(); var primitiveSerializer = new ContractPrimitiveSerializer(network); var testStruct = new TestLog { Id = uint.MaxValue, Name = "Test ID", Data = 0xAA, Datas = new byte[] { 0xBB, 0xCC, 0xDD }, Truth = true, Address = "0x0000000000000000000000000000000000000001".HexToAddress() }; var testBytes = primitiveSerializer.Serialize(testStruct); var serializer = new ApiLogDeserializer(primitiveSerializer, network); dynamic deserializedLog = serializer.DeserializeLogData(testBytes, typeof(TestLog)); Assert.Equal(testStruct.Id, deserializedLog.Id); Assert.Equal(testStruct.Name, deserializedLog.Name); Assert.Equal(testStruct.Data, deserializedLog.Data); Assert.True(testStruct.Datas.SequenceEqual((byte[])deserializedLog.Datas)); Assert.Equal(testStruct.Truth, deserializedLog.Truth); Assert.Equal(testStruct.Address.ToUint160().ToBase58Address(network), deserializedLog.Address); }
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); }
public IActionResult GetReceipt([FromQuery] string txHash) { uint256 txHashNum = new uint256(txHash); Receipt receipt = this.receiptRepository.Retrieve(txHashNum); if (receipt == null) { this.logger.LogTrace("(-)[RECEIPT_NOT_FOUND]"); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "The receipt was not found.", "No stored transaction could be found for the supplied hash.")); } uint160 address = receipt.NewContractAddress ?? receipt.To; if (!receipt.Logs.Any()) { return(this.Json(new ReceiptResponse(receipt, new List <LogResponse>(), this.network))); } byte[] contractCode = this.stateRoot.GetCode(address); Assembly assembly = Assembly.Load(contractCode); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network); List <LogResponse> logResponses = this.MapLogResponses(receipt, assembly, deserializer); var receiptResponse = new ReceiptResponse(receipt, logResponses, this.network); return(this.Json(receiptResponse)); }
public async Task <IActionResult> ReceiptSearch([FromQuery] string contractAddress, [FromQuery] string eventName) { uint160 address = contractAddress.ToUint160(this.network); byte[] contractCode = this.stateRoot.GetCode(address); if (contractCode == null || !contractCode.Any()) { return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.InternalServerError, "No code exists", $"No contract execution code exists at {address}")); } Assembly assembly = Assembly.Load(contractCode); var deserializer = new ApiLogDeserializer(this.primitiveSerializer, this.network); List <Receipt> receipts = this.SearchReceipts(contractAddress, eventName); var result = new List <ReceiptResponse>(); foreach (Receipt receipt in receipts) { List <LogResponse> logResponses = this.MapLogResponses(receipt, assembly, deserializer); var receiptResponse = new ReceiptResponse(receipt, logResponses, this.network); result.Add(receiptResponse); } return(this.Json(result)); }
public void Deserialize_Basic_Log_Success() { var network = new SmartContractsRegTest(); var primitiveSerializer = new ContractPrimitiveSerializer(network); var testStruct = new TestLog { Id = uint.MaxValue, Name = "Test ID", Data = 0xAA, Datas = new byte[] { 0xBB, 0xCC, 0xDD }, Truth = true, Address = "0x0000000000000000000000000000000000000001".HexToAddress(), Value128 = 123, Value256 = 456 }; var testBytes = primitiveSerializer.Serialize(testStruct); var serializer = new ApiLogDeserializer(primitiveSerializer, network, Mock.Of <IStateRepositoryRoot>(), Mock.Of <IContractAssemblyCache>()); dynamic deserializedLog = serializer.DeserializeLogData(testBytes, typeof(TestLog)); Assert.Equal(testStruct.Id, deserializedLog.Id); Assert.Equal(testStruct.Name, deserializedLog.Name); Assert.Equal(testStruct.Data, deserializedLog.Data); Assert.True(testStruct.Datas.SequenceEqual((byte[])deserializedLog.Datas)); Assert.Equal(testStruct.Truth, deserializedLog.Truth); Assert.Equal(testStruct.Address.ToUint160().ToBase58Address(network), deserializedLog.Address); Assert.Equal(testStruct.Value128.ToString(), deserializedLog.Value128.ToString()); Assert.Equal(testStruct.Value256.ToString(), deserializedLog.Value256.ToString()); }
public void MapTransferInfo_Success() { var network = new SmartContractsRegTest(); var primitiveSerializer = new ContractPrimitiveSerializerV2(network); 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>(); var serializer = new ApiLogDeserializer(primitiveSerializer, network, stateRoot.Object, assemblyCache.Object); var transferInfos = new List <TransferInfo> { new TransferInfo(uint160.Zero, uint160.One, 12345), new TransferInfo(uint160.One, uint160.Zero, 12345), }; List <SmartContracts.Models.TransferResponse> result = serializer.MapTransferInfo(transferInfos.ToArray()); for (var i = 0; i < transferInfos.Count; i++) { Assert.Equal(transferInfos[i].From.ToBase58Address(network), result[i].From); Assert.Equal(transferInfos[i].To.ToBase58Address(network), result[i].To); Assert.Equal(transferInfos[i].Value, result[i].Value); } }
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"))); } }
private List <LogResponse> MapLogResponses(Receipt receipt, Assembly assembly, ApiLogDeserializer deserializer) { var logResponses = new List <LogResponse>(); foreach (Log log in receipt.Logs) { var logResponse = new LogResponse(log, this.network); logResponses.Add(logResponse); if (log.Topics.Count == 0) { continue; } // Get receipt struct name string eventTypeName = Encoding.UTF8.GetString(log.Topics[0]); // Find the type in the module def Type eventType = assembly.DefinedTypes.FirstOrDefault(t => t.Name == eventTypeName); if (eventType == null) { // Couldn't match the type, continue? continue; } // Deserialize it dynamic deserialized = deserializer.DeserializeLogData(log.Data, eventType); logResponse.Log = deserialized; } return(logResponses); }
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())); } }