Ejemplo n.º 1
0
        public IEnumerable <Transaction> GetTransactionHistory(string address)
        {
            if (!ValidationUtils.IsValidAddress(address))
            {
                throw new ArgumentException("Invalid transaction address");
            }

            var transactionsByAddress = this.GetAllTransactions()
                                        .Where(
                t => t.From == address || t.To == address)
                                        .OrderBy(s => DateTime.Parse(s.DateCreated))
                                        .ToList();

            return(transactionsByAddress);
        }
Ejemplo n.º 2
0
        public void Test_IsValidAddress_When_Not_Valid()
        {
            var validAddress = "x3293572dbe6ebc60de4a20ed0e21446cae66b17";

            Assert.False(ValidationUtils.IsValidAddress(validAddress));
        }
Ejemplo n.º 3
0
        public Transaction AddNewTransaction(Transaction tranData)
        {
            // Validate the transaction & add it to the pending transactions
            if (!ValidationUtils.IsValidAddress(tranData.From))
            {
                throw new ArgumentException("Invalid sender address:" + tranData.From);
            }

            if (!ValidationUtils.IsValidAddress(tranData.To))
            {
                throw new ArgumentException("Invalid recipient address:" + tranData.To);
            }

            if (!ValidationUtils.IsValidPublicKey(tranData.SenderPubKey))
            {
                throw new ArgumentException("Invalid public key:" + tranData.SenderPubKey);
            }

            var senderAddr = CryptoUtils.GetAddressFromPublicKey(tranData.SenderPubKey);

            if (senderAddr != tranData.From)
            {
                throw new ArgumentException("The public key should match the sender address:" + tranData.SenderPubKey);
            }

            if (!ValidationUtils.IsValidTransferValue(tranData.Value))
            {
                throw new ArgumentException("Invalid transfer value: " + tranData.Value);
            }

            if (!ValidationUtils.IsValidFee(tranData.Fee))
            {
                throw new ArgumentException("Invalid transaction fee: " + tranData.Fee);
            }

            if (!ValidationUtils.IsValidDate(tranData.DateCreated))
            {
                throw new ArgumentException("Invalid date: " + tranData.DateCreated);
            }

            if (!ValidationUtils.IsValidSignatureFormat(CryptoUtils.SignatureByHex(tranData.SenderSignature)))
            {
                throw new ArgumentException("Invalid or missing signature. Expected signature format: BigInteger[2] " + tranData.SenderSignature);
            }


            var tran = new Transaction(
                tranData.From,
                tranData.To,
                tranData.Value,
                tranData.Fee,
                tranData.DateCreated,
                tranData.Data,
                tranData.SenderPubKey,
                null, // the transactionDataHash is auto-calculated
                tranData.SenderSignature

                );

            //tran.IsSignatureValid = tranData.IsSignatureValid;

            // Check for duplicated transactions (to avoid "replay attack")
            var tranDataHex = CryptoUtils.BytesToHex(tran.TransactionDataHash);

            if (this.FindTransactionByDataHash(tranDataHex) != null)
            {
                throw new ArgumentException("Duplicated transaction: " + tranDataHex);
            }


            if (!CryptoUtils.VerifySignature(CryptoUtils.SignatureByHex(tran.SenderSignature), tran.TransactionDataHash))
            {
                throw new ArgumentException("Invalid signature: " + tranData.SenderSignature);
            }


            var balances = this.GetAccountBalance(tran.From);

            if (balances.ConfirmedBalance < tran.Fee)
            {
                throw new ArgumentException("Unsufficient sender balance at address:  " + tran.From);
            }

            //if (this.PendingTransactions.Any(s => CryptoUtils.BytesToHex(s.TransactionDataHash) == CryptoUtils.BytesToHex(tran.TransactionDataHash)))
            //    throw new ArgumentException("Trying to add duplicate transaction:  " + CryptoUtils.BytesToHex(tran.TransactionDataHash));

            this.PendingTransactions.Add(tran);
            Console.WriteLine("Added pending transaction: " + JsonConvert.SerializeObject(tran));

            return(tran);
        }
Ejemplo n.º 4
0
        public AccountBalance GetAccountBalance(string address)
        {
            if (!ValidationUtils.IsValidAddress(address))
            {
                throw new ArgumentException("Invalid account address");
            }

            var transactions = this.GetTransactionHistory(address);
            var balance      = new AccountBalance();

            foreach (var tran in transactions)
            {
                var confirmsCount = 0;

                if (tran.MinedInBlockIndex.HasValue)
                {
                    confirmsCount = this.Blocks.Count - tran.MinedInBlockIndex.Value + 1;
                }



                if (tran.From == address)
                {
                    // Funds spent -> subtract value and fee
                    balance.PendingBalance -= tran.Fee;
                    if (confirmsCount == 0 || tran.TransferSuccessful)
                    {
                        balance.PendingBalance -= tran.Value;
                    }

                    if (confirmsCount >= 1)
                    {
                        balance.ConfirmedBalance -= tran.Fee;
                        if (tran.TransferSuccessful)
                        {
                            balance.ConfirmedBalance -= tran.Value;
                        }
                    }

                    if (confirmsCount >= Config.SafeConfirmCount)
                    {
                        balance.SafeBalance -= tran.Fee;
                        if (tran.TransferSuccessful)
                        {
                            balance.SafeBalance -= tran.Value;
                        }
                    }
                }

                if (tran.To == address)
                {
                    // Funds received --> add value and fee
                    if (confirmsCount == 0 || tran.TransferSuccessful)
                    {
                        balance.PendingBalance += tran.Value;
                    }
                    if (confirmsCount >= 1 && tran.TransferSuccessful)
                    {
                        balance.ConfirmedBalance += tran.Value;
                    }
                    if (confirmsCount >= Config.SafeConfirmCount && tran.TransferSuccessful)
                    {
                        balance.SafeBalance += tran.Value;
                    }
                }
            }

            return(balance);
        }