public int GetAmount(IEnumerable <UnspentTxOut> unspentTxOuts) { UnspentTxOut correspondingUnspentTxOut = GetCorrespondingUnspentTxOut(unspentTxOuts); if (correspondingUnspentTxOut == null) { throw new Exception("tried to get amount of a spent or inexisting tx out"); } return(correspondingUnspentTxOut.amount); }
/// <summary> /// Adds a new transaction to the database. /// </summary> /// <param name="tx">The transaction to add.</param> /// <param name="blockIndex">Index of the block containing the given transaction.</param> /// <param name="positionIndex">Index of the transaction in the block.</param> /// <param name="needSave">If true, the database will be saved immediately.</param> /// <returns>Index object for the given transaction.</returns> /// <remarks> /// In scenarios when there are multiple calls to this method, /// passing false to <paramref name="needSave"/> and then calling /// <see cref="Save"/> in the end would be a more efficient approach. /// </remarks> public TransactionIndex AddTransaction(Transaction tx, int blockIndex, int positionIndex, bool needSave = true) { if (_transactions.ContainsKey(tx.Id) || _transactionIndices.ContainsKey(tx.Id)) { throw new InvalidOperationException("Duplicate transaction ID"); } var txIndex = new TransactionIndex { Id = tx.Id, BlockIndex = blockIndex, PositionIndex = positionIndex, }; _transactionIndices.Add(tx.Id, txIndex); _transactions.Add(tx.Id, tx); for (int i = 0, c = tx.Inputs.Count; i < c; ++i) { var txIn = tx.Inputs[i]; spendTxOut(txIn.TxId, txIn.TxOutIndex); } for (int i = 0, c = tx.Outputs.Count; i < c; ++i) { var txOut = tx.Outputs[i]; var utxo = new UnspentTxOut { TxId = tx.Id, TxOutIndex = i, Address = txOut.Address, }; _unspentTxOuts.Add(utxo); } for (int i = 0, c = _pendingTransactions.Count; i < c; ++i) { var ptx = _pendingTransactions[i]; if (ptx.Tx.Id == tx.Id) { _pendingTransactions.RemoveAt(i); break; } } if (needSave) { Save(); } return(txIndex); }
public bool IsValid(string txId, IEnumerable <UnspentTxOut> unspentTxOuts) { UnspentTxOut referencedUnspentTxOut = unspentTxOuts.FirstOrDefault(uto => uto.txId == txOutTxId & uto.txOutIndex == txOutIndex); if (referencedUnspentTxOut == null) { Debug.LogError("Referenced TxOut not found : " + ToString()); return(false); } string address = referencedUnspentTxOut.address; return(Cryptography.VerifySignature(signature, txId, address)); }
/// <summary> /// Removes the given transaction from the database. /// </summary> /// <param name="tx">The transaction to remove.</param> /// <param name="needSave">If true, the database will be saved immediately.</param> /// <returns>True if the transaction exists and can be removed.</returns> /// <remarks> /// In scenarios when there are multiple calls to this method, /// passing false to <paramref name="needSave"/> and then calling /// <see cref="Save"/> in the end would be a more efficient approach. /// </remarks> public bool RemoveTransaction(Transaction tx, bool needSave = true) { if (_transactionIndices.ContainsKey(tx.Id) is false) { return(false); } _transactionIndices.Remove(tx.Id); _transactions.Remove(tx.Id); // Return the TxO's that this Tx has consumed for (int i = 0, c = tx.Inputs.Count; i < c; ++i) { var txIn = tx.Inputs[i]; var refTx = GetTransaction(txIn.TxId); if (refTx == null) { continue; } var refTxOut = refTx.Outputs[txIn.TxOutIndex]; var utxo = new UnspentTxOut { TxId = refTx.Id, TxOutIndex = txIn.TxOutIndex, Address = refTxOut.Address, }; _unspentTxOuts.Add(utxo); } // Remove the TxO's that this Tx has produced for (int i = 0, c = _unspentTxOuts.Count; i < c; ++i) { var utxo = _unspentTxOuts[i]; if (utxo.TxId == tx.Id) { _unspentTxOuts.RemoveAt(i); --i; --c; } } if (needSave) { Save(); } return(true); }
public string ComputeSignature(string txId, CspParameters privateKeyCointainer, IEnumerable <UnspentTxOut> unspentTxOuts) { UnspentTxOut referencedUnspentTxOut = GetCorrespondingUnspentTxOut(unspentTxOuts); if (referencedUnspentTxOut == null) { Debug.LogError("could not find referenced txOut for txIn"); return(null); } string referencedAddress = referencedUnspentTxOut.address; if (Cryptography.GetPublicKey(privateKeyCointainer) != referencedAddress) { Debug.LogError("trying to sign an input with private key that doesn't match the address of txIn's unspent txOut"); return(null); } return(Cryptography.SignHashWithPrivateKey(privateKeyCointainer, txId)); }