Esempio n. 1
0
        public async Task DebugTest_TraceTransactionForContractCreation()
        {
            string trHash      = "0x3685d6a6c2c6b27c846fc54b48886e14b3cfde6101973466359474fc27982395";//"0x9351a796b8a85d451fbae62ba26b07173134416d782026c08169dd0743cdc0e2";
            var    transaction = await _web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync(trHash);

            var transactionReciept = await _web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(trHash);

            var result = await _debug.TraceTransactionAsync(transaction.From, transaction.To, transactionReciept.ContractAddress,
                                                            transaction.Value.Value, trHash, false, true, false);
        }
Esempio n. 2
0
        /// <param name="blockHeight">block number to read from blockchain</param>
        /// <exception cref="BlockIsNotYetMinedException"
        /// <returns>BlockContent</returns>
        public async Task <BlockContent> ReadBlockAsync(BigInteger blockHeight)
        {
            var block = await _client.Eth.Blocks
                        .GetBlockWithTransactionsByNumber
                        .SendRequestAsync(new HexBigInteger(blockHeight));

            var logs = new EthGetLogs(_client.Client);

            #region Block

            if (block == null)
            {
                throw new BlockIsNotYetMinedException(blockHeight);
            }

            var blockHash  = block.BlockHash;
            var blockModel = new BlockModel
            {
                TransactionsCount = block.Transactions.Length,
                BlockHash         = blockHash,
                Difficulty        = block.Difficulty,
                ExtraData         = block.ExtraData,
                GasLimit          = block.GasLimit,
                GasUsed           = block.GasUsed,
                LogsBloom         = block.LogsBloom,
                Miner             = block.Miner,
                Nonce             = block.Nonce,
                Number            = block.Number,
                ParentHash        = block.ParentHash,
                ReceiptsRoot      = block.ReceiptsRoot,
                Sha3Uncles        = block.Sha3Uncles,
                Size             = block.Size,
                StateRoot        = block.StateRoot,
                Timestamp        = block.Timestamp,
                TotalDifficulty  = block.TotalDifficulty,
                TransactionsRoot = block.TransactionsRoot
            };

            #endregion

            #region Transactions

            var internalMessages  = new List <InternalMessageModel>();
            var blockTransactions = new Dictionary <string, TransactionModel>(block.Transactions.Length);

            foreach (var transaction in block.Transactions)
            {
                var transactionReciept =
                    await _client.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(transaction.TransactionHash);


                TraceResultModel traceResult = null;
                try
                {
                    traceResult = await _debug.TraceTransactionAsync
                                  (
                        transaction.From,
                        transaction.To,
                        transactionReciept.ContractAddress,
                        transaction.Value.Value,
                        transaction.TransactionHash,
                        false,
                        true,
                        false
                                  );

                    if (traceResult != null && !traceResult.HasError && traceResult.Transfers != null)
                    {
                        internalMessages.AddRange
                        (
                            traceResult.Transfers.Select(x => new InternalMessageModel
                        {
                            BlockNumber     = block.Number.Value,
                            Depth           = x.Depth,
                            FromAddress     = x.FromAddress,
                            MessageIndex    = x.MessageIndex,
                            ToAddress       = x.ToAddress,
                            TransactionHash = x.TransactionHash,
                            Value           = x.Value,
                            Type            = (InternalMessageModelType)x.Type,
                            BlockTimestamp  = blockModel.Timestamp
                        })
                        );
                    }
                }
                catch (Exception)
                {
                }

                var transactionModel = new TransactionModel
                {
                    BlockTimestamp   = block.Timestamp,
                    BlockHash        = transaction.BlockHash,
                    BlockNumber      = transaction.BlockNumber,
                    From             = transaction.From,
                    Gas              = transaction.Gas,
                    GasPrice         = transaction.GasPrice,
                    Input            = transaction.Input,
                    Nonce            = transaction.Nonce,
                    To               = transaction.To,
                    TransactionHash  = transaction.TransactionHash,
                    TransactionIndex = transaction.TransactionIndex,
                    Value            = transaction.Value,
                    GasUsed          = transactionReciept.GasUsed.Value,
                    ContractAddress  = transactionReciept.ContractAddress,
                    HasError         = traceResult?.HasError ?? false
                };

                blockTransactions[transaction.TransactionHash] = transactionModel;
            }

            var addressHistory = ExtractAddressHistory(internalMessages, blockTransactions.Values);

            #endregion

            #region Contracts

            var deployedContracts = new List <DeployedContractModel>();

            foreach (var transaction in blockTransactions.Select(x => x.Value).Where(x => x.ContractAddress != null))
            {
                deployedContracts.Add(new DeployedContractModel
                {
                    Address         = transaction.ContractAddress,
                    BlockHash       = blockHash,
                    BlockNumber     = block.Number.Value.ToString(),
                    BlockTimestamp  = block.Timestamp.Value.ToString(),
                    DeployerAddress = transaction.From,
                    TransactionHash = transaction.TransactionHash
                });
            }

            foreach (var message in internalMessages.Where(x => x.Type == InternalMessageModelType.CREATION))
            {
                deployedContracts.Add(new DeployedContractModel
                {
                    Address         = message.ToAddress,
                    BlockHash       = blockHash,
                    BlockNumber     = block.Number.Value.ToString(),
                    BlockTimestamp  = block.Timestamp.Value.ToString(),
                    DeployerAddress = message.FromAddress,
                    TransactionHash = message.TransactionHash
                });
            }

            // Select contracts with distinct addresses
            deployedContracts = deployedContracts.GroupBy(x => x.Address).Select(x => x.First()).ToList();

            #endregion

            #region Transfers

            var blockNumber = (ulong)blockHeight;
            var filter      = new NewFilterInput
            {
                FromBlock = new BlockParameter(blockNumber),
                ToBlock   = new BlockParameter(blockNumber),
                Topics    = new object[]
                {
                    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
                }
            };

            var transferLogs = await logs.SendRequestAsync(filter);

            var transfers = transferLogs
                            .Where(x => x.Topics.Length == 3)
                            .Select(x =>
            {
                string trHash = x.TransactionHash;
                TransactionModel transaction = null;
                blockTransactions.TryGetValue(trHash, out transaction);

                return(new Erc20TransferHistoryModel
                {
                    BlockHash = x.BlockHash,
                    BlockNumber = (ulong)x.BlockNumber.Value,
                    BlockTimestamp = (ulong)block.Timestamp.Value,
                    ContractAddress = x.Address,
                    From = x.GetAddressFromTopic(1),
                    LogIndex = (uint)x.LogIndex.Value,
                    To = x.GetAddressFromTopic(2),
                    TransactionHash = trHash,
                    TransactionIndex = (uint)x.TransactionIndex.Value,
                    TransferAmount = x.Data.HexToBigInteger(false),
                    GasUsed = transaction?.GasUsed ?? 0,
                    GasPrice = transaction?.GasPrice ?? 0
                });
            })
                            .ToList();

            #endregion

            return(new BlockContent
            {
                AddressHistory = addressHistory,
                BlockModel = blockModel,
                DeployedContracts = deployedContracts,
                InternalMessages = internalMessages,
                Transactions = blockTransactions?.Select(x => x.Value).ToList(),
                Transfers = transfers
            });
        }