public IWithdrawal ExtractWithdrawalFromTransaction(Transaction transaction, uint256 blockHash, int blockHeight) { if (transaction.Outputs.Count(this.IsTargetAddressCandidate) != 1) { return(null); } if (!this.IsOnlyFromMultisig(transaction)) { return(null); } if (!this.opReturnDataReader.TryGetTransactionId(transaction, out string depositId)) { return(null); } this.logger.LogDebug( "Processing received transaction with source deposit id: {0}. Transaction hash: {1}.", depositId, transaction.GetHash()); TxOut targetAddressOutput = transaction.Outputs.Single(this.IsTargetAddressCandidate); var withdrawal = new Withdrawal( uint256.Parse(depositId), transaction.GetHash(), targetAddressOutput.Value, targetAddressOutput.ScriptPubKey.GetDestinationAddress(this.network).ToString(), blockHeight, blockHash); return(withdrawal); }
public IWithdrawal ExtractWithdrawalFromTransaction(Transaction transaction, uint256 blockHash, int blockHeight) { // Coinbase can't contain withdrawals. if (transaction.IsCoinBase) { return(null); } if (!this.IsOnlyFromMultisig(transaction)) { return(null); } if (!this.opReturnDataReader.TryGetTransactionId(transaction, out string depositId)) { return(null); } // This is not a withdrawal transaction. if (transaction.Outputs.Count < ExpectedNumberOfOutputsNoChange) { return(null); } Money withdrawalAmount = null; string targetAddress = null; // Cross chain transfers either have 2 or 3 outputs. if (transaction.Outputs.Count == ExpectedNumberOfOutputsNoChange || transaction.Outputs.Count == ExpectedNumberOfOutputsChange) { TxOut targetAddressOutput = transaction.Outputs.SingleOrDefault(this.IsTargetAddressCandidate); if (targetAddressOutput == null) { return(null); } withdrawalAmount = targetAddressOutput.Value; targetAddress = targetAddressOutput.ScriptPubKey.GetDestinationAddress(this.network).ToString(); } else { // Reward distribution transactions will have more than 3 outputs. IEnumerable <TxOut> txOuts = transaction.Outputs.Where(output => output.ScriptPubKey != this.multisigAddress.ScriptPubKey && !output.ScriptPubKey.IsUnspendable); if (!txOuts.Any()) { return(null); } withdrawalAmount = txOuts.Sum(t => t.Value); targetAddress = this.network.CirrusRewardDummyAddress; } var withdrawal = new Withdrawal(uint256.Parse(depositId), transaction.GetHash(), withdrawalAmount, targetAddress, blockHeight, blockHash); return(withdrawal); }
public IWithdrawal ExtractWithdrawalFromTransaction(Transaction transaction, uint256 blockHash, int blockHeight) { // Coinbase can't contain withdrawals. if (transaction.IsCoinBase) { return(null); } // Withdrawal has a specific structure. if (transaction.Outputs.Count != ExpectedNumberOfOutputsNoChange && transaction.Outputs.Count != ExpectedNumberOfOutputsChange) { return(null); } if (!this.IsOnlyFromMultisig(transaction)) { return(null); } if (!this.opReturnDataReader.TryGetTransactionId(transaction, out string depositId)) { return(null); } TxOut targetAddressOutput = transaction.Outputs.SingleOrDefault(this.IsTargetAddressCandidate); if (targetAddressOutput == null) { return(null); } var withdrawal = new Withdrawal( uint256.Parse(depositId), transaction.GetHash(), targetAddressOutput.Value, targetAddressOutput.ScriptPubKey.GetDestinationAddress(this.network).ToString(), blockHeight, blockHash); return(withdrawal); }