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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }