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); }
public void Test_IsValidAddress_When_Not_Valid() { var validAddress = "x3293572dbe6ebc60de4a20ed0e21446cae66b17"; Assert.False(ValidationUtils.IsValidAddress(validAddress)); }
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); }
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); }