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)); }
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); }
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)); }
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); }