Example #1
0
            public OutPoint(Blake256Hash hash, uint index, byte tree)
            {
                if (hash == null)
                {
                    throw new ArgumentNullException(nameof(hash));
                }

                Hash  = hash;
                Index = index;
                Tree  = tree;
            }
Example #2
0
 public BlockIdentity(Blake256Hash hash, int height)
 {
     Hash   = hash;
     Height = height;
 }
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));
        }