コード例 #1
0
        /// <summary>
        /// Deserialize the transaction hex string.
        /// </summary>
        /// <param name="tx">Transaction hex string</param>
        /// <returns>Bitcoin Transaction</returns>
        public static BitcoinTransaction DecodeRawTx(string tx)
        {
            BitcoinTransaction btx = new BitcoinTransaction();
            int index = 0;

            // 1) 4 byte - version
            string version = tx.Substring(index, 8);

            btx.Version = (UInt32)NumberConversions.HexToUInt(version);
            index      += 8;

            // 2) ? byte - tx_in count (CompactSize uint)
            btx.TxInCount = NumberConversions.ReadCompactSize(tx, ref index);

            bool isSigned = true;
            bool isRbf    = false;

            // Initialize the array
            btx.TxInList = new TxIn[btx.TxInCount];
            for (UInt64 i = 0; i < btx.TxInCount; i++)
            {
                TxIn temp = new TxIn();
                // 3) 32 byte - TX hash (reverse)
                temp.TxId = tx.Substring(index, 64);
                temp.TxId = ReverseTx(temp.TxId);
                index    += 64;

                // 4) 4 byte - output Index
                string outIndex = tx.Substring(index, 8);
                temp.OutIndex = (UInt32)NumberConversions.HexToUInt(outIndex);
                index        += 8;

                // 5) ? byte - scriptSig length (CompactSize uint) (Maximum value is 10,000 bytes)
                string scriptSigLength = tx.Substring(index, 2);
                temp.ScriptSigLength = (int)NumberConversions.ReadCompactSize(tx, ref index);

                // 6) ? byte - scriptSig or a placeholder for unsigned (can be empty too)
                temp.ScriptSig = tx.Substring(index, temp.ScriptSigLength * 2);
                index         += temp.ScriptSigLength * 2;

                //7) 4 byte - sequence - max is 0xffffffff - can change for RBF transactions
                string sequence = tx.Substring(index, 8);
                temp.Sequence = (UInt32)NumberConversions.HexToUInt(sequence);
                index        += 8;

                btx.TxInList[i] = temp;

                // Check to see if all the inputs are signed
                if (temp.ScriptSigLength <= 25)
                {
                    isSigned = false;
                }

                // Check for opt-in Replace By Fee
                if (temp.Sequence != UInt32.MaxValue)
                {
                    isRbf = true;
                }
            }
            // Set transaction sign and RBF status.
            btx.Status = (isSigned) ? BitcoinTransaction.TxStatus.Signed : BitcoinTransaction.TxStatus.Unsigned;
            btx.IsRbf  = isRbf;

            //8) ? byte - tx_out count (compactSize uint)
            btx.TxOutCount = NumberConversions.ReadCompactSize(tx, ref index);

            // Initialize the array
            btx.TxOutList = new TxOut[btx.TxOutCount];
            for (UInt64 i = 0; i < btx.TxOutCount; i++)
            {
                TxOut temp = new TxOut();

                //9) 8 byte - amout to transfer
                string amount = tx.Substring(index, 16);
                temp.Amount = NumberConversions.HexToUInt(amount);
                index      += 16;

                //10) ? byte - pk_script length (compactSize uint)
                string pkScriptLength = tx.Substring(index, 2);
                temp.PkScriptLength = (Int32)NumberConversions.HexToUInt(pkScriptLength);
                index += 2;

                //11) ? byte - pk_script
                temp.PkScript = tx.Substring(index, temp.PkScriptLength * 2);
                index        += temp.PkScriptLength * 2;

                btx.TxOutList[i] = temp;
            }

            //12) 4 byte - lock time
            string lockTime = tx.Substring(index, 8);

            btx.LockTime = (UInt32)NumberConversions.HexToUInt(lockTime);
            index       += 8;

            // If the transaction is signed, then it has a TxId
            if (isSigned)
            {
                btx.TxId = BitcoinConversions.GetTxId(tx);
            }

            return(btx);
        }