internal static TransactionData ToTransactionData(this SQLiteWalletRepository repo, HDTransactionData transactionData, IEnumerable <HDPayment> payments) { TransactionData txData = new TransactionData() { Amount = new Money(transactionData.Value, MoneyUnit.BTC), BlockHash = (transactionData.OutputBlockHash == null) ? null : uint256.Parse(transactionData.OutputBlockHash), BlockHeight = transactionData.OutputBlockHeight, CreationTime = DateTimeOffset.FromUnixTimeSeconds(transactionData.OutputTxTime), Id = uint256.Parse(transactionData.OutputTxId), Index = transactionData.OutputIndex, // These two are always updated and used in tandem so we update them from a single source value. IsCoinBase = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex == 0, IsCoinStake = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex != 0, // IsPropagated // Not used currently. ScriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.RedeemScript)), SpendingDetails = (transactionData.SpendTxId == null) ? null : new SpendingDetails() { BlockHeight = transactionData.SpendBlockHeight, // BlockIndex // Not used currently. CreationTime = DateTimeOffset.FromUnixTimeSeconds((long)transactionData.SpendTxTime), IsCoinStake = transactionData.SpendTxIsCoinBase == 1, TransactionId = uint256.Parse(transactionData.SpendTxId), Payments = payments.Select(p => new PaymentDetails() { Amount = new Money((decimal)p.SpendValue, MoneyUnit.BTC), DestinationScriptPubKey = new Script(Encoders.Hex.DecodeData(p.SpendScriptPubKey)), OutputIndex = p.SpendIndex }).ToList() } }; if (txData.SpendingDetails == null || repo.ScriptAddressReader == null) { return(txData); } try { IEnumerable <PaymentDetails> allDetails = txData.SpendingDetails.Payments; var lookup = allDetails.Select(d => d.DestinationScriptPubKey).Distinct().ToDictionary(d => d, d => (string)null); foreach (Script script in lookup.Keys.ToList()) { lookup[script] = repo.ScriptAddressReader.GetAddressFromScriptPubKey(repo.Network, script); } foreach (PaymentDetails paymentDetails in allDetails) { paymentDetails.DestinationAddress = lookup[paymentDetails.DestinationScriptPubKey]; } } catch (Exception err) { throw; } return(txData); }
internal static TransactionData ToTransactionData(this SQLiteWalletRepository repo, HDTransactionData transactionData, TransactionCollection transactionCollection) { // We need to examine the entire scriptPubKey of the transaction output in question in order to determine if it is a coldstaking output. var scriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.RedeemScript)); bool isColdStaking = scriptPubKey.IsScriptType(ScriptType.ColdStaking); // TODO: Need to make a central determination of whether a UTXO is Segwit or not (i.e. it pays to a P2WPKH scriptPubKey) var res = new TransactionData() { Amount = new Money(transactionData.Value), BlockHash = (transactionData.OutputBlockHash == null) ? null : uint256.Parse(transactionData.OutputBlockHash), BlockHeight = transactionData.OutputBlockHeight, CreationTime = DateTimeOffset.FromUnixTimeSeconds(transactionData.OutputTxTime), Id = uint256.Parse(transactionData.OutputTxId), Index = transactionData.OutputIndex, // These two are always updated and used in tandem so we update them from a single source value. IsCoinBase = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex == 0, IsCoinStake = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex != 0, IsColdCoinStake = isColdStaking, // IsPropagated // Not used currently. ScriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.RedeemScript)), AddressScriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.ScriptPubKey)), SpendingDetails = (transactionData.SpendTxId == null) ? null : new SpendingDetails() { BlockHeight = transactionData.SpendBlockHeight, BlockHash = string.IsNullOrEmpty(transactionData.SpendBlockHash) ? null : uint256.Parse(transactionData.SpendBlockHash), // BlockIndex // Not used currently. CreationTime = DateTimeOffset.FromUnixTimeSeconds((long)transactionData.SpendTxTime), IsCoinStake = transactionData.SpendTxIsCoinBase == 1, TransactionId = uint256.Parse(transactionData.SpendTxId) }, TransactionCollection = transactionCollection }; if (res.SpendingDetails != null) { res.SpendingDetails.TransactionData = res; } return(res); }
internal static TransactionData ToTransactionData(this SQLiteWalletRepository repo, HDTransactionData transactionData, TransactionCollection transactionCollection) { // We need to examine the entire scriptPubKey of the transaction output in question in order to determine if it is a coldstaking output. var scriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.RedeemScript)); // Making the actual cold staking script template available here for checking will be quite messy, so just bring in the relevant check. byte[] bytes = scriptPubKey.ToBytes(true); bool isColdStaking = ((bytes.Length == 51) && (bytes[0] == (byte)0x76) && // OP_DUP (bytes[1] == (byte)0xa9) && // OP_HASH160 (bytes[2] == (byte)0x7b) && // OP_ROT (bytes[3] == (byte)0x63) && // OP_IF (bytes[4] == (byte)0xb9) && // OP_CHECKCOLDSTAKEVERIFY (bytes[5] == 0x14) && (bytes[26] == (byte)0x67) && // OP_ELSE (bytes[27] == 0x14) && (bytes[48] == (byte)0x68) && // OP_ENDIF (bytes[49] == (byte)0x88) && // OP_EQUALVERIFY (bytes[50] == (byte)0xac)); // OP_CHECKSIG // TODO: Need to make a central determination of whether a UTXO is Segwit or not (i.e. it pays to a P2WPKH scriptPubKey) var res = new TransactionData() { Amount = new Money(transactionData.Value), BlockHash = (transactionData.OutputBlockHash == null) ? null : uint256.Parse(transactionData.OutputBlockHash), BlockHeight = transactionData.OutputBlockHeight, CreationTime = DateTimeOffset.FromUnixTimeSeconds(transactionData.OutputTxTime), Id = uint256.Parse(transactionData.OutputTxId), Index = transactionData.OutputIndex, // These two are always updated and used in tandem so we update them from a single source value. IsCoinBase = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex == 0, IsCoinStake = transactionData.OutputTxIsCoinBase == 1 && transactionData.OutputIndex != 0, IsColdCoinStake = isColdStaking, // IsPropagated // Not used currently. ScriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.RedeemScript)), AddressScriptPubKey = new Script(Encoders.Hex.DecodeData(transactionData.ScriptPubKey)), SpendingDetails = (transactionData.SpendTxId == null) ? null : new SpendingDetails() { BlockHeight = transactionData.SpendBlockHeight, BlockHash = string.IsNullOrEmpty(transactionData.SpendBlockHash) ? null : uint256.Parse(transactionData.SpendBlockHash), // BlockIndex // Not used currently. CreationTime = DateTimeOffset.FromUnixTimeSeconds((long)transactionData.SpendTxTime), IsCoinStake = transactionData.SpendTxIsCoinBase == 1, TransactionId = uint256.Parse(transactionData.SpendTxId) }, TransactionCollection = transactionCollection }; if (res.SpendingDetails != null) { res.SpendingDetails.TransactionData = res; } return(res); }