예제 #1
0
        public async Task ProcessTransactionAsync(Transaction transaction, TransactionReceipt transactionReceipt, HexBigInteger blockTimestamp)
        {
            if (!IsTransactionForContractCreation(transaction, transactionReceipt))
            {
                return;
            }

            var contractAddress = GetContractAddress(transactionReceipt);
            var code            = await GetCode(contractAddress).ConfigureAwait(false);

            var failedCreatingContract = HasFailedToCreateContract(code);

            if (!failedCreatingContract)
            {
                await _contractRepository.UpsertAsync(contractAddress, code, transaction).ConfigureAwait(false);
            }

            await _transactionRepository.UpsertAsync(contractAddress, code,
                                                     transaction, transactionReceipt,
                                                     failedCreatingContract, blockTimestamp);

            await _addressTransactionRepository.UpsertAsync(
                transaction,
                transactionReceipt,
                failedCreatingContract, blockTimestamp, null, null, false, contractAddress);
        }
        public EthereumTransaction(
            Currency currency,
            Transaction tx,
            TransactionReceipt txReceipt,
            DateTime blockTimeStamp)
        {
            Currency      = currency;
            Id            = tx.TransactionHash;
            From          = tx.From.ToLowerInvariant();
            To            = tx.To.ToLowerInvariant();
            Input         = tx.Input;
            Amount        = tx.Value;
            Nonce         = tx.Nonce;
            GasPrice      = tx.GasPrice;
            GasLimit      = tx.Gas;
            GasUsed       = txReceipt.GasUsed;
            Type          = UnknownTransaction;
            ReceiptStatus = txReceipt.Status != null
                ? txReceipt.Status.Value == BigInteger.One
                : true;
            IsInternal    = false;
            InternalIndex = 0;

            BlockInfo = new BlockInfo
            {
                BlockHeight   = (long)tx.TransactionIndex.Value,
                Fees          = (long)txReceipt.GasUsed.Value,
                Confirmations = (int)txReceipt.Status.Value,
                BlockTime     = blockTimeStamp,
                FirstSeen     = blockTimeStamp
            };
        }
예제 #3
0
        public static Address ExtractInteropAddress(Nethereum.RPC.Eth.DTOs.Transaction tx)
        {
            //Using the transanction from RPC to build a txn for signing / signed
            var transaction = Nethereum.Signer.TransactionFactory.CreateTransaction(tx.To, tx.Gas, tx.GasPrice, tx.Value, tx.Input, tx.Nonce,
                                                                                    tx.R, tx.S, tx.V);

            //Get the account sender recovered
            Nethereum.Signer.EthECKey accountSenderRecovered = null;
            if (transaction is Nethereum.Signer.TransactionChainId)
            {
                var txnChainId = transaction as Nethereum.Signer.TransactionChainId;
                accountSenderRecovered = Nethereum.Signer.EthECKey.RecoverFromSignature(transaction.Signature, transaction.RawHash, txnChainId.GetChainIdAsBigInteger());
            }
            else
            {
                accountSenderRecovered = Nethereum.Signer.EthECKey.RecoverFromSignature(transaction.Signature, transaction.RawHash);
            }
            var pubKey = accountSenderRecovered.GetPubKey();

            var point = Cryptography.ECC.ECPoint.DecodePoint(pubKey, Cryptography.ECC.ECCurve.Secp256k1);

            pubKey = point.EncodePoint(true);

            var bytes = new byte[34];

            bytes[0] = (byte)AddressKind.User;
            ByteArrayUtils.CopyBytes(pubKey, 0, bytes, 1, 33);

            return(Address.FromBytes(bytes));
        }
 public async Task UpsertAsync(string contractAddress, string code, Transaction transaction, TransactionReceipt transactionReceipt, bool failedCreatingContract, HexBigInteger blockTimestamp)
 {
     var transactionEntity = Entities.Transaction.CreateTransaction(Table,
                                                                    transaction, transactionReceipt,
                                                                    failedCreatingContract, blockTimestamp, contractAddress);
     await transactionEntity.InsertOrReplaceAsync().ConfigureAwait(false);
 }
        protected static void EnsureCorrectStoredValues(Transaction transaction, TransactionReceipt receipt, HexBigInteger blockTimestamp, string address, string error, string newContractAddress, bool hasVmStack, ITransactionView storedTransaction)
        {
            Assert.Equal(transaction.BlockHash, storedTransaction.BlockHash);
            Assert.Equal(transaction.TransactionHash, storedTransaction.Hash);
            Assert.Equal(transaction.From, storedTransaction.AddressFrom);
            Assert.Equal((long)transaction.TransactionIndex.Value, storedTransaction.TransactionIndex);
            Assert.Equal(transaction.Value.Value.ToString(), storedTransaction.Value);
            Assert.Equal(transaction.To, storedTransaction.AddressTo);
            Assert.Equal(newContractAddress ?? string.Empty, storedTransaction.NewContractAddress);
            Assert.Equal(transaction.BlockNumber.Value.ToString(), storedTransaction.BlockNumber);
            Assert.Equal((long)transaction.Gas.Value, storedTransaction.Gas);
            Assert.Equal((long)transaction.GasPrice.Value, storedTransaction.GasPrice);
            Assert.Equal(transaction.Input, storedTransaction.Input);
            Assert.Equal((long)transaction.Nonce.Value, storedTransaction.Nonce);
            Assert.False(storedTransaction.Failed);
            Assert.Equal((long)receipt.GasUsed.Value, storedTransaction.GasUsed);
            Assert.Equal((long)receipt.CumulativeGasUsed.Value, storedTransaction.CumulativeGasUsed);
            Assert.False(storedTransaction.HasLog);
            Assert.Equal((long)blockTimestamp.Value, storedTransaction.TimeStamp);
            Assert.Equal(hasVmStack, storedTransaction.HasVmStack);

            if (error == null)
            {
                Assert.True(string.IsNullOrEmpty(storedTransaction.Error));
            }
            else
            {
                Assert.Equal(error, storedTransaction.Error);
            }
        }
        public virtual async Task ProcessTransactionAsync(
            Transaction transaction,
            TransactionReceipt transactionReceipt,
            HexBigInteger blockTimestamp)
        {
            if (!transaction.IsForContractCreation(transactionReceipt))
            {
                return;
            }

            var contractAddress = transactionReceipt.ContractAddress;
            var code            = await _getCodeProxy.GetCode(contractAddress).ConfigureAwait(false);

            var failedCreatingContract = HasFailedToCreateContract(code);

            if (!failedCreatingContract)
            {
                await _contractHandler.HandleAsync(new ContractTransaction(contractAddress, code, transaction))
                .ConfigureAwait(false);
            }

            await _transactionHandler
            .HandleContractCreationTransactionAsync(
                new ContractCreationTransaction(
                    contractAddress,
                    code,
                    transaction,
                    transactionReceipt,
                    failedCreatingContract,
                    blockTimestamp))
            .ConfigureAwait(false);
        }
        public async Task UpsertAsync(Transaction transaction, TransactionReceipt receipt, bool failed, HexBigInteger timeStamp, bool hasVmStack = false, string error = null)
        {
            using (var context = _contextFactory.CreateContext())
            {
                BlockchainStore.Entities.Transaction tx = await FindOrCreate(transaction, context).ConfigureAwait(false);

                tx.Map(transaction);
                tx.Map(receipt);

                tx.Failed     = failed;
                tx.TimeStamp  = (long)timeStamp.Value;
                tx.Error      = error ?? string.Empty;
                tx.HasVmStack = hasVmStack;

                tx.UpdateRowDates();

                if (tx.IsNew())
                {
                    context.Transactions.Add(tx);
                }
                else
                {
                    context.Transactions.Update(tx);
                }

                await context.SaveChangesAsync().ConfigureAwait(false);
            }
        }
        public async Task UpsertAsync(string contractAddress, string code, Transaction transaction, TransactionReceipt receipt, bool failedCreatingContract, HexBigInteger blockTimestamp)
        {
            using (var context = _contextFactory.CreateContext())
            {
                BlockchainStore.Entities.Transaction tx = await FindOrCreate(transaction, context).ConfigureAwait(false);

                tx.Map(transaction);
                tx.Map(receipt);

                tx.NewContractAddress = contractAddress;
                tx.Failed             = false;
                tx.TimeStamp          = (long)blockTimestamp.Value;
                tx.Error      = string.Empty;
                tx.HasVmStack = false;

                tx.UpdateRowDates();

                if (tx.IsNew())
                {
                    context.Transactions.Add(tx);
                }
                else
                {
                    context.Transactions.Update(tx);
                }

                await context.SaveChangesAsync().ConfigureAwait(false);
            }
        }
예제 #9
0
 public async Task <bool> IsTransactionForContractAsync(Transaction transaction)
 {
     if (transaction.To == null)
     {
         return(false);
     }
     return(await _contractRepository.ExistsAsync(transaction.To).ConfigureAwait(false));
 }
예제 #10
0
 public async Task <bool> IsTransactionForContractAsync(Transaction transaction)
 {
     if (transaction.To.IsAnEmptyAddress())
     {
         return(false);
     }
     return(await _contractHandler.ExistsAsync(transaction.To)
            .ConfigureAwait(false));
 }
 public async Task ProcessTransactionAsync(
     Transaction transaction,
     TransactionReceipt transactionReceipt,
     HexBigInteger blockTimestamp)
 {
     await _transactionHandler.HandleTransactionAsync(
         new TransactionWithReceipt(transaction, transactionReceipt, false, blockTimestamp))
     .ConfigureAwait(false);
 }
 public async Task UpsertAsync(Transaction transaction,
                               TransactionReceipt transactionReceipt,
                               bool failed,
                               HexBigInteger timeStamp, bool hasVmStack = false, string error = null)
 {
     var transactionEntity = Entities.Transaction.CreateTransaction(Table, transaction,
                                                                    transactionReceipt,
                                                                    failed, timeStamp, hasVmStack, error);
     await transactionEntity.InsertOrReplaceAsync().ConfigureAwait(false);
 }
예제 #13
0
 protected static void EnsureCorrectStoredValues(
     HexBigInteger blockTimestamp,
     string address,
     Transaction transaction,
     IAddressTransactionView storedTransaction)
 {
     Assert.Equal(transaction.TransactionHash, storedTransaction.Hash);
     Assert.Equal(transaction.BlockNumber.Value.ToString(), storedTransaction.BlockNumber);
     Assert.Equal(address, storedTransaction.Address);
 }
예제 #14
0
        public async Task ProcessTransactionAsync(Transaction transaction, TransactionReceipt transactionReceipt, HexBigInteger blockTimestamp)
        {
            await _transactionRepository.UpsertAsync(transaction,
                                                     transactionReceipt,
                                                     false, blockTimestamp).ConfigureAwait(false);

            await _addressTransactionRepository.UpsertAsync(transaction,
                                                            transactionReceipt,
                                                            false, blockTimestamp, transaction.To).ConfigureAwait(false);
        }
예제 #15
0
 public Task ProcessTransactionAsync(
     Transaction transaction,
     TransactionReceipt transactionReceipt,
     HexBigInteger blockTimestamp)
 {
     return(_transactionHandler.HandleTransactionAsync(
                new TransactionWithReceipt(
                    transaction,
                    transactionReceipt,
                    false,
                    blockTimestamp)));
 }
예제 #16
0
 public static void Map(this TransactionBase to, Nethereum.RPC.Eth.DTOs.Transaction @from)
 {
     to.BlockHash   = @from.BlockHash;
     to.Hash        = @from.TransactionHash;
     to.AddressFrom = @from.From;
     to.Value       = @from.Value.Value.ToString();
     to.AddressTo   = @from.To ?? string.Empty;
     to.BlockNumber = @from.BlockNumber.Value.ToString();
     to.Gas         = @from.Gas.Value.ToString();
     to.GasPrice    = @from.GasPrice.Value.ToString();
     to.Input       = @from.Input ?? string.Empty;
     to.Nonce       = @from.Nonce.Value.ToString();
 }
 public async Task UpsertAsync(Transaction transaction,
                               TransactionReceipt transactionReceipt,
                               bool failedCreatingContract,
                               HexBigInteger blockTimestamp,
                               string address,
                               string error              = null,
                               bool hasVmStack           = false,
                               string newContractAddress = null)
 {
     var entity = AddressTransaction.CreateAddressTransaction(Table, transaction,
                                                              transactionReceipt,
                                                              failedCreatingContract, blockTimestamp, null, null, false, newContractAddress);
     await entity.InsertOrReplaceAsync().ConfigureAwait(false);
 }
예제 #18
0
        public async Task ProcessTransactionAsync(
            Transaction transaction,
            TransactionReceipt transactionReceipt,
            HexBigInteger blockTimestamp)
        {
            var     transactionHash = transaction.TransactionHash;
            var     hasStackTrace   = false;
            JObject stackTrace      = null;
            var     error           = string.Empty;
            var     hasError        = transactionReceipt.Failed();

            if (EnabledVmProcessing)
            {
                try
                {
                    stackTrace = await _web3
                                 .GetTransactionVmStack(transactionHash)
                                 .ConfigureAwait(false);
                }
                catch (Exception)
                {
                }

                if (stackTrace != null)
                {
                    //TODO!  _Remove this debug line
                    //File.WriteAllText($"c:/Temp/StackTrace_{transactionReceipt.BlockNumber.Value}.json", stackTrace.ToString());

                    error         = _vmStackErrorChecker.GetError(stackTrace);
                    hasError      = !string.IsNullOrEmpty(error);
                    hasStackTrace = true;

                    await _transactionVmStackHandler.HandleAsync
                        (new TransactionVmStack(transactionHash, transaction.To, stackTrace))
                    .ConfigureAwait(false);
                }
            }

            var tx = new TransactionWithReceipt(
                transaction,
                transactionReceipt,
                hasError,
                blockTimestamp,
                error,
                hasStackTrace);

            await _transactionHandler.HandleTransactionAsync(tx)
            .ConfigureAwait(false);
        }
        public async Task UpsertAsync(Transaction transaction,
                                      TransactionReceipt transactionReceipt,
                                      bool failedCreatingContract,
                                      HexBigInteger blockTimestamp,
                                      string address,
                                      string error              = null,
                                      bool hasVmStack           = false,
                                      string newContractAddress = null)
        {
            var entity = AddressTransaction.CreateAddressTransaction(transaction,
                                                                     transactionReceipt,
                                                                     failedCreatingContract, blockTimestamp, address, error, hasVmStack, newContractAddress);

            await UpsertAsync(entity);
        }
예제 #20
0
        public void Initialise(Nethereum.RPC.Eth.DTOs.Transaction transaction)
        {
            this.TransactionHash = transaction.TransactionHash;
            this.BlockHash       = transaction.BlockHash;
            this.Nonce           = (ulong)transaction.Nonce.Value;
            this.From            = transaction.From;
            this.To       = transaction.To;
            this.Gas      = (ulong)transaction.Gas.Value;
            this.GasPrice = (ulong)transaction.GasPrice.Value;
            this.Data     = transaction.Input;

            if (transaction.Value != null)
            {
                this.Amount = Web3.Convert.FromWei(transaction.Value.Value);
            }
        }
예제 #21
0
        //Refer to https://medium.com/pixelpoint/track-blockchain-transactions-like-a-boss-with-web3-js-c149045ca9bf

        public static async Task <BigInteger> GetConfirmation(string txid = "", string url = "http://localhost:8510")
        {
            Web3 web = new Web3(url);

            if (string.IsNullOrWhiteSpace(txid))
            {
                txid = "0x3b8e1902c0ad9ca92da71b4802cfd451ff616a56dc3e69319d51cb0ae91c2a13";
            }

            Nethereum.RPC.Eth.DTOs.Transaction trans = await web.Eth.Transactions.GetTransactionByHash.SendRequestAsync(txid).ConfigureAwait(false);

            var blocknumber = await web.Eth.Blocks.GetBlockNumber.SendRequestAsync().ConfigureAwait(false);

            var confirmation = blocknumber.Value - trans.BlockNumber.Value;

            Console.WriteLine($"Confirmation :  {confirmation}");
            return(confirmation);
        }
        public async Task InsertOrUpdate(Transaction transaction)
        {
            using (var context = new BlockchainStoreContext())
            {
                //context.Entry(transaction).State = string.IsNullOrEmpty(transaction.Hash) ?
                //                           EntityState.Added :
                //                           EntityState.Modified;

                try
                {
                    context.Transactions.Add(transaction);
                    await context.SaveChangesAsync();
                }
                catch (System.Exception)
                {
                }
            }
        }
예제 #23
0
        public async Task ProcessTransactionAsync(
            Transaction transaction,
            TransactionReceipt transactionReceipt,
            HexBigInteger blockTimestamp)
        {
            var     transactionHash = transaction.TransactionHash;
            var     hasStackTrace   = false;
            JObject stackTrace      = null;
            var     error           = string.Empty;
            var     hasError        = transactionReceipt.Failed();

            if (EnabledVmProcessing)
            {
                try
                {
                    stackTrace = await _vmStackProxy
                                 .GetTransactionVmStack(transactionHash)
                                 .ConfigureAwait(false);
                }
                catch
                {
                }

                if (stackTrace != null)
                {
                    error         = _vmStackErrorChecker.GetError(stackTrace);
                    hasError      = !string.IsNullOrEmpty(error);
                    hasStackTrace = true;

                    await _transactionVmStackHandler.HandleAsync
                        (new TransactionVmStack(transactionHash, transaction.To, stackTrace));
                }
            }

            await _transactionHandler.HandleTransactionAsync(
                new TransactionWithReceipt(
                    transaction,
                    transactionReceipt,
                    hasError,
                    blockTimestamp,
                    error,
                    hasStackTrace));
        }
예제 #24
0
                public Result(Web3 web3, Nethereum.RPC.Eth.DTOs.Transaction transaction)
                {
                    Task <TransactionReceipt> resultTask = null;

                    if (transaction.BlockNumber == null || transaction.BlockNumber.Value == null)
                    {
                        Status = "pending";
                    }
                    else
                    {
                        resultTask = Task.Run(() =>
                        {
                            TransactionReceipt tempReciept = null;
                            while (tempReciept == null)
                            {
                                tempReciept = web3.Eth.Transactions.GetTransactionReceipt.SendRequestAsync(transaction.TransactionHash).Result;
                            }
                            return(tempReciept);
                        }).
                                     ContinueWith(task =>
                        {
                            var reciept = task.Result;
                            GasUsed     = reciept.GasUsed.Value;
                            Status      = (reciept.Status.Value == 1) ? "success" : "fail";
                            return(reciept);
                        });
                    }

                    TransactionHash  = transaction.TransactionHash;
                    BlockNumber      = transaction.BlockNumber;
                    TransactionIndex = transaction.TransactionIndex.Value;
                    From             = transaction.From;
                    To       = transaction.To;
                    GasPrice = transaction.GasPrice.Value;

                    if (resultTask != null)
                    {
                        resultTask.Wait();
                    }
                }
예제 #25
0
        public EthereumTransaction(
            Currency currency,
            Transaction tx,
            TransactionReceipt txReceipt,
            DateTime blockTimeStamp)
        {
            Currency = currency;
            Id       = tx.TransactionHash;
            Type     = BlockchainTransactionType.Unknown;
            State    = txReceipt.Status != null && txReceipt.Status.Value == BigInteger.One
                ? BlockchainTransactionState.Confirmed
                : (txReceipt.Status != null
                    ? BlockchainTransactionState.Failed
                    : BlockchainTransactionState.Unconfirmed);
            CreationTime = blockTimeStamp;

            From          = tx.From.ToLowerInvariant();
            To            = tx.To.ToLowerInvariant();
            Input         = tx.Input;
            Amount        = tx.Value;
            Nonce         = tx.Nonce;
            GasPrice      = tx.GasPrice;
            GasLimit      = tx.Gas;
            GasUsed       = txReceipt.GasUsed;
            ReceiptStatus = State == BlockchainTransactionState.Confirmed;
            IsInternal    = false;
            InternalIndex = 0;

            BlockInfo = new BlockInfo
            {
                Confirmations = txReceipt.Status != null
                    ? (int)txReceipt.Status.Value
                    : 0,
                BlockHash   = tx.BlockHash,
                BlockHeight = (long)tx.TransactionIndex.Value,
                BlockTime   = blockTimeStamp,
                FirstSeen   = blockTimeStamp
            };
        }
예제 #26
0
        public static Address ExtractInteropAddress(Nethereum.RPC.Eth.DTOs.Transaction tx, Logger logger)
        {
            //Using the transanction from RPC to build a txn for signing / signed
            var transaction = Nethereum.Signer.TransactionFactory.CreateTransaction(tx.To, tx.Gas, tx.GasPrice, tx.Value, tx.Input, tx.Nonce,
                                                                                    tx.R, tx.S, tx.V);

            //Get the account sender recovered
            Nethereum.Signer.EthECKey accountSenderRecovered = null;
            // TODO To be used with Nethereum 4:
            // 1) CreateLegacyTransaction()/LegacyTransactionChainId
            // or
            // 2) var signature = new Nethereum.Signer.EthECDSASignature(new Org.BouncyCastle.Math.BigInteger(tx.R.Replace("0x", ""), 16), new Org.BouncyCastle.Math.BigInteger(tx.S.Replace("0x", ""), 16), new Org.BouncyCastle.Math.BigInteger(tx.V.Replace("0x", ""), 16).ToByteArray());
            // accountSenderRecovered = Nethereum.Signer.EthECKey.RecoverFromSignature(signature, System.Text.Encoding.UTF8.GetBytes(tx.TransactionHash.Replace("0x", "")));

            if (transaction is Nethereum.Signer.TransactionChainId)
            {
                var txnChainId = transaction as Nethereum.Signer.TransactionChainId;
                accountSenderRecovered = Nethereum.Signer.EthECKey.RecoverFromSignature(transaction.Signature, transaction.RawHash, txnChainId.GetChainIdAsBigInteger());
            }
            else
            {
                accountSenderRecovered = Nethereum.Signer.EthECKey.RecoverFromSignature(transaction.Signature, transaction.RawHash);
            }
            var pubKey = accountSenderRecovered.GetPubKey();

            var point = Cryptography.ECC.ECPoint.DecodePoint(pubKey, Cryptography.ECC.ECCurve.Secp256k1);

            pubKey = point.EncodePoint(true);

            var bytes = new byte[34];

            bytes[0] = (byte)AddressKind.User;
            ByteArrayUtils.CopyBytes(pubKey, 0, bytes, 1, 33);

            var address = Address.FromBytes(bytes);

            return(address);
        }
예제 #27
0
        public async Task UpsertAsync()
        {
            var contractAddress = "0x26bc47888b7bfdf77db41ec0a2fb4db00af1c92a";
            var code            = "0x6080604052600436106053576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635589f21d14605857806388a6f572146076578063ddca3f4314609e575b600080fd5b60746004803603810190808035906020019092919050505060c6565b005b348015608157600080fd5b50608860d0565b6040518082815260200191505060405180910390f35b34801560a957600080fd5b5060b060d9565b6040518082815260200191505060405180910390f35b8060008190555050565b60008054905090565b600054815600a165627a7a723058205345477b840b4fb7b6401abdcd3ab98ae1db0d342e6c6b4b45a4e2b10f6ae1f80029";

            var transaction = new Nethereum.RPC.Eth.DTOs.Transaction
            {
                From            = "0xe6de16a66e5cd7270cc36a851818bc092884fe64",
                TransactionHash = "0xcb00b69d2594a3583309f332ada97d0df48bae00170e36a4f7bbdad7783fc7e5"
            };

            var block   = new Block {
            };
            var receipt = new TransactionReceipt {
                ContractAddress = contractAddress
            };
            var transactionReceiptVO = new TransactionReceiptVO(block, transaction, receipt, false);

            var contractCreationVO = new ContractCreationVO(transactionReceiptVO, code, false);

            Assert.False(await _repo.ExistsAsync(contractAddress));
            Assert.False(_repo.IsCached(contractAddress));

            await _repo.UpsertAsync(contractCreationVO);

            Assert.True(await _repo.ExistsAsync(contractAddress));
            Assert.True(_repo.IsCached(contractAddress));


            var storedContract = await _repo.FindByAddressAsync(contractAddress);

            Assert.NotNull(storedContract);
            Assert.Equal(contractAddress, storedContract.Address);
            Assert.Equal(code, storedContract.Code);
            Assert.Equal(transaction.From, storedContract.Creator);
            Assert.Equal(transaction.TransactionHash, storedContract.TransactionHash);
        }
예제 #28
0
        public async Task ProcessTransactionAsync(Transaction transaction, TransactionReceipt transactionReceipt, HexBigInteger blockTimestamp)
        {
            var     transactionHash = transaction.TransactionHash;
            var     hasStackTrace   = false;
            JObject stackTrace      = null;
            var     error           = string.Empty;
            var     hasError        = false;

            if (EnabledVmProcessing)
            {
                try
                {
                    stackTrace = await GetTransactionVmStack(transactionHash).ConfigureAwait(false);
                }
                catch
                {
                    if (transaction.Gas == transactionReceipt.GasUsed)
                    {
                        hasError = true;
                    }
                }

                if (stackTrace != null)
                {
                    error         = VmStackErrorChecker.GetError(stackTrace);
                    hasError      = !string.IsNullOrEmpty(error);
                    hasStackTrace = true;
                    await _transactionVmStackRepository.UpsertAsync(transactionHash, transaction.To, stackTrace);
                }
            }

            var logs = transactionReceipt.Logs;

            await _transactionRepository.UpsertAsync(transaction,
                                                     transactionReceipt,
                                                     hasError, blockTimestamp, hasStackTrace, error);

            await
            _addressTransactionRepository.UpsertAsync(transaction, transactionReceipt, hasError, blockTimestamp,
                                                      transaction.To, error, hasStackTrace);

            var addressesAdded = new List <string> {
                transaction.To
            };

            for (var i = 0; i < logs.Count; i++)
            {
                var log = logs[i] as JObject;
                if (log != null)
                {
                    var logAddress = log["address"].Value <string>();

                    if (!addressesAdded.Exists(x => x == logAddress))
                    {
                        addressesAdded.Add(logAddress);

                        await
                        _addressTransactionRepository.UpsertAsync(transaction, transactionReceipt, hasError,
                                                                  blockTimestamp,
                                                                  logAddress, error, hasStackTrace);
                    }

                    await _transactionLogRepository.UpsertAsync(transactionHash,
                                                                i, log);
                }
            }
        }
 private static async Task <BlockchainProcessing.BlockStorage.Entities.Transaction> FindOrCreate(Nethereum.RPC.Eth.DTOs.Transaction transaction, BlockchainDbContextBase context)
 {
     return(await context.Transactions
            .FindByBlockNumberAndHashAsync(transaction.BlockNumber, transaction.TransactionHash).ConfigureAwait(false) ??
            new BlockchainProcessing.BlockStorage.Entities.Transaction());
 }
예제 #30
0
        private static Dictionary <string, List <InteropTransfer> > GetInteropTransfers(Nexus nexus, Logger logger,
                                                                                        TransactionReceipt txr, EthAPI api, string[] swapAddresses)
        {
            logger.Debug($"get interop transfers for tx {txr.TransactionHash}");
            var interopTransfers = new Dictionary <string, List <InteropTransfer> >();

            Nethereum.RPC.Eth.DTOs.Transaction tx = null;
            try
            {
                // tx to get the eth transfer if any
                tx = api.GetTransaction(txr.TransactionHash);
            }
            catch (Exception e)
            {
                logger.Error("Getting eth tx failed: " + e.Message);
            }

            Console.WriteLine("txr: " + txr.Status);
            logger.Debug("Transaction status: " + txr.Status.Value);
            // check if tx has failed
            if (txr.Status.Value == 0)
            {
                logger.Error($"tx {txr.TransactionHash} failed");
                return(interopTransfers);
            }

            foreach (var a in swapAddresses)
            {
                Console.WriteLine("swap address: " + a);
            }
            var nodeSwapAddresses = swapAddresses.Select(x => BSCWallet.EncodeAddress(x));
            var interopAddress    = ExtractInteropAddress(tx);

            Console.WriteLine("interop address: " + interopAddress);

            // ERC721 (NFT)
            // TODO currently this code block is mostly copypaste from BEP20 block, later make a single method for both...
            //var erc721_events = txr.DecodeAllEvents<Nethereum.StandardNonFungibleTokenERC721.ContractDefinition.TransferEventDTOBase>();
            //foreach (var evt in erc721_events)
            //{
            //    var asset = EthUtils.FindSymbolFromAsset(nexus, evt.Log.Address);
            //    if (asset == null)
            //    {
            //        logger.Warning($"Asset [{evt.Log.Address}] not supported");
            //        continue;
            //    }

            //    var targetAddress = BSCWallet.EncodeAddress(evt.Event.To);
            //    var sourceAddress = BSCWallet.EncodeAddress(evt.Event.From);
            //    var tokenID = PBigInteger.Parse(evt.Event.TokenId.ToString());

            //    if (nodeSwapAddresses.Contains(targetAddress))
            //    {
            //        if (!interopTransfers.ContainsKey(evt.Log.TransactionHash))
            //        {
            //            interopTransfers.Add(evt.Log.TransactionHash, new List<InteropTransfer>());
            //        }

            //        string tokenURI = FetchTokenURI(evt.Log.Address, evt.Event.TokenId);

            //        interopTransfers[evt.Log.TransactionHash].Add
            //        (
            //            new InteropTransfer
            //            (
            //                BSCWallet.BSCPlatform,
            //                sourceAddress,
            //                DomainSettings.PlatformName,
            //                targetAddress,
            //                interopAddress,
            //                asset,
            //                tokenID,
            //                System.Text.Encoding.UTF8.GetBytes(tokenURI)
            //            )
            //        );
            //    }
            //}

            // BEP20
            var bep20_events = txr.DecodeAllEvents <TransferEventDTO>();

            foreach (var evt in bep20_events)
            {
                var asset = EthUtils.FindSymbolFromAsset(BSCWallet.BSCPlatform, nexus, evt.Log.Address);
                if (asset == null)
                {
                    logger.Warning($"Asset [{evt.Log.Address}] not supported");
                    continue;
                }

                var targetAddress = BSCWallet.EncodeAddress(evt.Event.To);
                var sourceAddress = BSCWallet.EncodeAddress(evt.Event.From);
                var amount        = PBigInteger.Parse(evt.Event.Value.ToString());

                if (nodeSwapAddresses.Contains(targetAddress))
                {
                    if (!interopTransfers.ContainsKey(evt.Log.TransactionHash))
                    {
                        interopTransfers.Add(evt.Log.TransactionHash, new List <InteropTransfer>());
                    }

                    interopTransfers[evt.Log.TransactionHash].Add
                    (
                        new InteropTransfer
                        (
                            BSCWallet.BSCPlatform,
                            sourceAddress,
                            DomainSettings.PlatformName,
                            targetAddress,
                            interopAddress,
                            asset,
                            amount
                        )
                    );
                }
            }

            Console.WriteLine("value: " + tx.Value);
            Console.WriteLine("value: " + tx.Value.Value);
            if (tx.Value != null && tx.Value.Value > 0)
            {
                var targetAddress = BSCWallet.EncodeAddress(tx.To);
                var sourceAddress = BSCWallet.EncodeAddress(tx.From);

                foreach (var a in nodeSwapAddresses)
                {
                    Console.WriteLine("node swap address: " + a);
                }
                Console.WriteLine("target address: " + targetAddress);

                if (nodeSwapAddresses.Contains(targetAddress))
                {
                    var amount = PBigInteger.Parse(tx.Value.ToString());

                    if (!interopTransfers.ContainsKey(tx.TransactionHash))
                    {
                        interopTransfers.Add(tx.TransactionHash, new List <InteropTransfer>());
                    }

                    interopTransfers[tx.TransactionHash].Add
                    (
                        new InteropTransfer
                        (
                            BSCWallet.BSCPlatform,
                            sourceAddress,
                            DomainSettings.PlatformName,
                            targetAddress,
                            interopAddress,
                            "BSC", // TODO use const
                            amount
                        )
                    );
                }
            }


            return(interopTransfers);
        }