Example #1
0
        public static Transaction Deserialize(byte[] rawTransaction)
        {
            if (rawTransaction == null)
            {
                throw new ArgumentNullException(nameof(rawTransaction));
            }

            int version;

            Input[]  inputs;
            Output[] outputs;
            uint     lockTime;

            var cursor = new ByteCursor(rawTransaction);

            try
            {
                version = cursor.ReadInt32();
                var inputCount = cursor.ReadCompact();
                if (inputCount > TransactionRules.MaxInputs)
                {
                    var reason = $"Input count {inputCount} exceeds maximum value {TransactionRules.MaxInputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                inputs = new Input[inputCount];
                for (int i = 0; i < (int)inputCount; i++)
                {
                    var previousHash     = new Sha256Hash(cursor.ReadBytes(Sha256Hash.Length));
                    var previousIndex    = cursor.ReadUInt32();
                    var previousOutPoint = new OutPoint(previousHash, previousIndex);
                    var signatureScript  = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    var sequence         = cursor.ReadUInt32();
                    inputs[i] = new Input(previousOutPoint, signatureScript, sequence);
                }
                var outputCount = cursor.ReadCompact();
                if (outputCount > TransactionRules.MaxOutputs)
                {
                    var reason = $"Output count {outputCount} exceeds maximum value {TransactionRules.MaxOutputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                outputs = new Output[outputCount];
                for (int i = 0; i < (int)outputCount; i++)
                {
                    var amount   = (Amount)cursor.ReadInt64();
                    var pkScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    outputs[i] = new Output(amount, pkScript);
                }
                lockTime = cursor.ReadUInt32();
            }
            catch (Exception ex) when(!(ex is EncodingException))
            {
                throw new EncodingException(typeof(Transaction), cursor, ex);
            }

            return(new Transaction(version, inputs, outputs, lockTime));
        }
Example #2
0
        public static Transaction Deserialize(byte[] rawTransaction)
        {
            if (rawTransaction == null)
                throw new ArgumentNullException(nameof(rawTransaction));

            int version;
            Input[] inputs;
            Output[] outputs;
            uint lockTime;

            var cursor = new ByteCursor(rawTransaction);

            try
            {
                version = cursor.ReadInt32();
                var inputCount = cursor.ReadCompact();
                if (inputCount > TransactionRules.MaxInputs)
                {
                    var reason = $"Input count {inputCount} exceeds maximum value {TransactionRules.MaxInputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                inputs = new Input[inputCount];
                for (int i = 0; i < (int)inputCount; i++)
                {
                    var previousHash = new Sha256Hash(cursor.ReadBytes(Sha256Hash.Length));
                    var previousIndex = cursor.ReadUInt32();
                    var previousOutPoint = new OutPoint(previousHash, previousIndex);
                    var signatureScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    var sequence = cursor.ReadUInt32();
                    inputs[i] = new Input(previousOutPoint, signatureScript, sequence);
                }
                var outputCount = cursor.ReadCompact();
                if (outputCount > TransactionRules.MaxOutputs)
                {
                    var reason = $"Output count {outputCount} exceeds maximum value {TransactionRules.MaxOutputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                outputs = new Output[outputCount];
                for (int i = 0; i < (int)outputCount; i++)
                {
                    var amount = (Amount)cursor.ReadInt64();
                    var pkScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    outputs[i] = new Output(amount, pkScript);
                }
                lockTime = cursor.ReadUInt32();
            }
            catch (Exception ex) when (!(ex is EncodingException))
            {
                throw new EncodingException(typeof(Transaction), cursor, ex);
            }

            return new Transaction(version, inputs, outputs, lockTime);
        }
Example #3
0
        public static Transaction Deserialize(byte[] rawTransaction)
        {
            if (rawTransaction == null)
            {
                throw new ArgumentNullException(nameof(rawTransaction));
            }

            int version;

            Input[]  inputs;
            Output[] outputs;
            uint     lockTime;
            uint     expiry;

            var cursor = new ByteCursor(rawTransaction);

            try
            {
                version = cursor.ReadInt32();
                if (version != SupportedVersion)
                {
                    var reason = $"Unsupported transaction version `{version}`";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }

                // Prefix deserialization
                var prefixInputCount = cursor.ReadCompact();
                if (prefixInputCount > TransactionRules.MaxInputs)
                {
                    var reason = $"Input count {prefixInputCount} exceeds maximum value {TransactionRules.MaxInputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                inputs = new Input[prefixInputCount];
                for (int i = 0; i < (int)prefixInputCount; i++)
                {
                    var previousHash     = new Blake256Hash(cursor.ReadBytes(Blake256Hash.Length));
                    var previousIndex    = cursor.ReadUInt32();
                    var previousTree     = cursor.ReadByte();
                    var previousOutPoint = new OutPoint(previousHash, previousIndex, previousTree);
                    var sequence         = cursor.ReadUInt32();
                    inputs[i] = Input.CreateFromPrefix(previousOutPoint, sequence);
                }
                var outputCount = cursor.ReadCompact();
                if (outputCount > TransactionRules.MaxOutputs)
                {
                    var reason = $"Output count {outputCount} exceeds maximum value {TransactionRules.MaxOutputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                outputs = new Output[outputCount];
                for (int i = 0; i < (int)outputCount; i++)
                {
                    var amount        = (Amount)cursor.ReadInt64();
                    var outputVersion = cursor.ReadUInt16();
                    var pkScript      = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    outputs[i] = new Output(amount, outputVersion, pkScript);
                }
                lockTime = cursor.ReadUInt32();
                expiry   = cursor.ReadUInt32();

                // Witness deserialization
                var witnessInputCount = cursor.ReadCompact();
                if (witnessInputCount != prefixInputCount)
                {
                    var reason = $"Input counts in prefix and witness do not match ({prefixInputCount} != {witnessInputCount})";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                for (int i = 0; i < (int)witnessInputCount; i++)
                {
                    var inputAmount     = (Amount)cursor.ReadInt64();
                    var blockHeight     = cursor.ReadUInt32();
                    var blockIndex      = cursor.ReadUInt32();
                    var signatureScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    inputs[i] = Input.AddWitness(inputs[i], inputAmount, blockHeight, blockIndex, signatureScript);
                }
            }
            catch (Exception ex) when(!(ex is EncodingException))
            {
                throw new EncodingException(typeof(Transaction), cursor, ex);
            }

            return(new Transaction(version, inputs, outputs, lockTime, expiry));
        }
Example #4
0
        public static Transaction Deserialize(byte[] rawTransaction)
        {
            if (rawTransaction == null)
                throw new ArgumentNullException(nameof(rawTransaction));

            int version;
            Input[] inputs;
            Output[] outputs;
            uint lockTime;
            uint expiry;

            var cursor = new ByteCursor(rawTransaction);

            try
            {
                version = cursor.ReadInt32();
                if (version != SupportedVersion)
                {
                    var reason = $"Unsupported transaction version `{version}`";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }

                // Prefix deserialization
                var prefixInputCount = cursor.ReadCompact();
                if (prefixInputCount > TransactionRules.MaxInputs)
                {
                    var reason = $"Input count {prefixInputCount} exceeds maximum value {TransactionRules.MaxInputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                inputs = new Input[prefixInputCount];
                for (int i = 0; i < (int)prefixInputCount; i++)
                {
                    var previousHash = new Blake256Hash(cursor.ReadBytes(Blake256Hash.Length));
                    var previousIndex = cursor.ReadUInt32();
                    var previousTree = cursor.ReadByte();
                    var previousOutPoint = new OutPoint(previousHash, previousIndex, previousTree);
                    var sequence = cursor.ReadUInt32();
                    inputs[i] = Input.CreateFromPrefix(previousOutPoint, sequence);
                }
                var outputCount = cursor.ReadCompact();
                if (outputCount > TransactionRules.MaxOutputs)
                {
                    var reason = $"Output count {outputCount} exceeds maximum value {TransactionRules.MaxOutputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                outputs = new Output[outputCount];
                for (int i = 0; i < (int)outputCount; i++)
                {
                    var amount = (Amount)cursor.ReadInt64();
                    var outputVersion = cursor.ReadUInt16();
                    var pkScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    outputs[i] = new Output(amount, outputVersion, pkScript);
                }
                lockTime = cursor.ReadUInt32();
                expiry = cursor.ReadUInt32();

                // Witness deserialization
                var witnessInputCount = cursor.ReadCompact();
                if (witnessInputCount != prefixInputCount)
                {
                    var reason = $"Input counts in prefix and witness do not match ({prefixInputCount} != {witnessInputCount})";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                for (int i = 0; i < (int)witnessInputCount; i++)
                {
                    var inputAmount = (Amount)cursor.ReadInt64();
                    var blockHeight = cursor.ReadUInt32();
                    var blockIndex = cursor.ReadUInt32();
                    var signatureScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    inputs[i] = Input.AddWitness(inputs[i], inputAmount, blockHeight, blockIndex, signatureScript);
                }
            }
            catch (Exception ex) when (!(ex is EncodingException))
            {
                throw new EncodingException(typeof(Transaction), cursor, ex);
            }

            return new Transaction(version, inputs, outputs, lockTime, expiry);
        }