示例#1
0
        public void SerializeTo(byte[] destination, int offset = 0)
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            var cursor = new ByteCursor(destination, offset);

            cursor.WriteInt32(Version);
            cursor.WriteCompact((ulong)Inputs.Length);
            foreach (var input in Inputs)
            {
                cursor.Write(input.PreviousOutpoint.Hash);
                cursor.WriteUInt32(input.PreviousOutpoint.Index);
                cursor.WriteVarBytes(input.SignatureScript);
                cursor.WriteUInt32(input.Sequence);
            }
            cursor.WriteCompact((ulong)Outputs.Length);
            foreach (var output in Outputs)
            {
                cursor.WriteInt64(output.Amount);
                cursor.WriteVarBytes(output.PkScript);
            }
            cursor.WriteUInt32(LockTime);
        }
示例#2
0
        void ByteCursor.IWriter.WriteToCursor(ByteCursor cursor)
        {
            if (cursor == null)
            {
                throw new ArgumentNullException(nameof(cursor));
            }

            _buffer.WriteToCursor(cursor);
        }
示例#3
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));
        }
示例#4
0
 public void WriteToCursor(ByteCursor cursor)
 {
     unsafe
     {
         fixed(byte *p = _data)
         {
             cursor.WriteFixedBytes(p, Length);
         }
     }
 }
示例#5
0
 public EncodingException(Type resultType, ByteCursor cursor, Exception innerException)
     : base(string.Format(messageFormat, resultType), innerException)
 {
     ResultType = resultType;
     Cursor     = cursor;
 }
示例#6
0
 public EncodingException(Type resultType, ByteCursor cursor, string reason)
     : base(string.Format(messageReasonFormat, resultType, reason))
 {
     ResultType = resultType;
     Cursor     = cursor;
 }
示例#7
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);
        }
示例#8
0
        public void SerializeTo(byte[] destination, int offset = 0)
        {
            var cursor = new ByteCursor(destination, offset);

            cursor.WriteInt32(Version);
            cursor.WriteCompact((ulong)Inputs.Length);
            foreach (var input in Inputs)
            {
                cursor.Write(input.PreviousOutpoint.Hash);
                cursor.WriteUInt32(input.PreviousOutpoint.Index);
                cursor.WriteVarBytes(input.SignatureScript);
                cursor.WriteUInt32(input.Sequence);
            }
            cursor.WriteCompact((ulong)Outputs.Length);
            foreach (var output in Outputs)
            {
                cursor.WriteInt64(output.Amount);
                cursor.WriteVarBytes(output.PkScript);
            }
            cursor.WriteUInt32(LockTime);
        }
示例#9
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));
        }
示例#10
0
        public void SerializeTo(byte[] destination, int offset = 0)
        {
            if (destination == null)
                throw new ArgumentNullException(nameof(destination));

            var cursor = new ByteCursor(destination, offset);

            cursor.WriteInt32(Version);

            // Serialize prefix
            cursor.WriteCompact((ulong)Inputs.Length);
            foreach (var input in Inputs)
            {
                cursor.Write(input.PreviousOutpoint.Hash);
                cursor.WriteUInt32(input.PreviousOutpoint.Index);
                cursor.WriteByte(input.PreviousOutpoint.Tree);
                cursor.WriteUInt32(input.Sequence);
            }
            cursor.WriteCompact((ulong)Outputs.Length);
            foreach (var output in Outputs)
            {
                cursor.WriteInt64(output.Amount);
                cursor.WriteUInt16(output.Version);
                cursor.WriteVarBytes(output.PkScript);
            }
            cursor.WriteUInt32(LockTime);
            cursor.WriteUInt32(Expiry);

            // Serialize witness
            cursor.WriteCompact((ulong)Inputs.Length);
            foreach (var input in Inputs)
            {
                cursor.WriteInt64(input.InputAmount);
                cursor.WriteUInt32(input.BlockHeight);
                cursor.WriteUInt32(input.BlockIndex);
                cursor.WriteVarBytes(input.SignatureScript);
            }
        }
示例#11
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);
        }
示例#12
0
 public EncodingException(Type resultType, ByteCursor cursor, Exception innerException)
     : base(string.Format(messageFormat, resultType), innerException)
 {
     ResultType = resultType;
     Cursor = cursor;
 }
示例#13
0
 public EncodingException(Type resultType, ByteCursor cursor, string reason)
     : base(string.Format(messageReasonFormat, resultType, reason))
 {
     ResultType = resultType;
     Cursor = cursor;
 }