public async Task <TrustedInput> GetTrustedInputAsync(Transaction transaction, int outputIndex, CancellationToken cancellation = default(CancellationToken)) { if (outputIndex >= transaction.Outputs.Count) { throw new ArgumentOutOfRangeException("outputIndex is bigger than the number of outputs in the transaction", "outputIndex"); } List <byte[]> apdus = new List <byte[]>(); MemoryStream data = new MemoryStream(); // Header BufferUtils.WriteUint32BE(data, outputIndex); BufferUtils.WriteBuffer(data, transaction.Version); VarintUtils.write(data, transaction.Inputs.Count); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x00, (byte)0x00, data.ToArray())); // Each input foreach (var input in transaction.Inputs) { data = new MemoryStream(); BufferUtils.WriteBuffer(data, input.PrevOut); VarintUtils.write(data, input.ScriptSig.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, input.ScriptSig.ToBytes()); apdus.AddRange(CreateApduSplit2(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray(), Utils.ToBytes(input.Sequence, true))); } // Number of outputs data = new MemoryStream(); VarintUtils.write(data, transaction.Outputs.Count); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray())); // Each output foreach (var output in transaction.Outputs) { data = new MemoryStream(); BufferUtils.WriteBuffer(data, Utils.ToBytes((ulong)output.Value.Satoshi, true)); VarintUtils.write(data, output.ScriptPubKey.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, output.ScriptPubKey.ToBytes()); apdus.AddRange(CreateAPDUSplit(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, data.ToArray())); } // Locktime apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, (byte)0x80, (byte)0x00, transaction.LockTime.ToBytes())); byte[] response = await ExchangeApdusAsync(apdus.ToArray(), OK, cancellation).ConfigureAwait(false); return(new TrustedInput(response)); }
private List <byte[]> GetTrustedInputAPDUs(Transaction transaction, int outputIndex) { if (outputIndex >= transaction.Outputs.Count) { throw new ArgumentOutOfRangeException("outputIndex is bigger than the number of outputs in the transaction", "outputIndex"); } var apdus = new List <byte[]>(); var data = new MemoryStream(); // Header BufferUtils.WriteUint32BE(data, outputIndex); BufferUtils.WriteBuffer(data, transaction.Version); VarintUtils.write(data, transaction.Inputs.Count); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x00, 0x00, data.ToArray())); // Each input foreach (var input in transaction.Inputs) { data = new MemoryStream(); BufferUtils.WriteBuffer(data, input.PrevOut); VarintUtils.write(data, input.ScriptSig.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, input.ScriptSig.ToBytes()); apdus.AddRange(CreateApduSplit2(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, data.ToArray(), Utils.ToBytes(input.Sequence, true))); } // Number of outputs data = new MemoryStream(); VarintUtils.write(data, transaction.Outputs.Count); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, data.ToArray())); // Each output foreach (var output in transaction.Outputs) { data = new MemoryStream(); BufferUtils.WriteBuffer(data, Utils.ToBytes((ulong)output.Value.Satoshi, true)); VarintUtils.write(data, output.ScriptPubKey.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, output.ScriptPubKey.ToBytes()); apdus.AddRange(CreateAPDUSplit(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, data.ToArray())); } // Locktime apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_GET_TRUSTED_INPUT, 0x80, 0x00, transaction.LockTime.ToBytes())); return(apdus); }
public byte[][] UntrustedHashTransactionInputStart(bool newTransaction, IndexedTxIn txIn, TrustedInput[] trustedInputs) { List <byte[]> apdus = new List <byte[]>(); trustedInputs = trustedInputs ?? new TrustedInput[0]; // Start building a fake transaction with the passed inputs MemoryStream data = new MemoryStream(); BufferUtils.WriteBuffer(data, txIn.Transaction.Version); VarintUtils.write(data, txIn.Transaction.Inputs.Count); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x00, (newTransaction ? (byte)0x00 : (byte)0x80), data.ToArray())); // Loop for each input long currentIndex = 0; foreach (var input in txIn.Transaction.Inputs) { var trustedInput = trustedInputs.FirstOrDefault(i => i.OutPoint == input.PrevOut); byte[] script = (currentIndex == txIn.Index ? txIn.TxIn.ScriptSig.ToBytes() : new byte[0]); data = new MemoryStream(); if (trustedInput != null) { data.WriteByte(0x01); var b = trustedInput.ToBytes(); // untrusted inputs have constant length data.WriteByte((byte)b.Length); BufferUtils.WriteBuffer(data, b); } else { data.WriteByte(0x00); BufferUtils.WriteBuffer(data, input.PrevOut); } VarintUtils.write(data, script.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x80, (byte)0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, script); BufferUtils.WriteBuffer(data, input.Sequence); apdus.AddRange(CreateAPDUSplit(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x80, (byte)0x00, data.ToArray())); currentIndex++; } return(apdus.ToArray()); }
public byte[][] UntrustedHashTransactionInputStart( InputStartType startType, IndexedTxIn txIn, Dictionary <OutPoint, TrustedInput> trustedInputs, Dictionary <OutPoint, ICoin> coins, bool segwitMode, bool segwitParsedOnce) { List <byte[]> apdus = new List <byte[]>(); trustedInputs = trustedInputs ?? new Dictionary <OutPoint, TrustedInput>(); // Start building a fake transaction with the passed inputs MemoryStream data = new MemoryStream(); BufferUtils.WriteBuffer(data, txIn.Transaction.Version); if (segwitMode && segwitParsedOnce) { VarintUtils.write(data, 1); } else { VarintUtils.write(data, txIn.Transaction.Inputs.Count); } apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x00, (byte)startType, data.ToArray())); // Loop for each input long currentIndex = 0; foreach (var input in txIn.Transaction.Inputs) { if (segwitMode && segwitParsedOnce && currentIndex != txIn.Index) { currentIndex++; continue; } byte[] script = new byte[0]; if (currentIndex == txIn.Index || segwitMode && !segwitParsedOnce) { script = coins[input.PrevOut].GetScriptCode().ToBytes(); } data = new MemoryStream(); if (segwitMode) { data.WriteByte(0x02); BufferUtils.WriteBuffer(data, input.PrevOut); BufferUtils.WriteBuffer(data, Utils.ToBytes((ulong)coins[input.PrevOut].TxOut.Value.Satoshi, true)); } else { var trustedInput = trustedInputs[input.PrevOut]; if (trustedInput != null) { data.WriteByte(0x01); var b = trustedInput.ToBytes(); // untrusted inputs have constant length data.WriteByte((byte)b.Length); BufferUtils.WriteBuffer(data, b); } else { data.WriteByte(0x00); BufferUtils.WriteBuffer(data, input.PrevOut); } } VarintUtils.write(data, script.Length); apdus.Add(CreateAPDU(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x80, (byte)0x00, data.ToArray())); data = new MemoryStream(); BufferUtils.WriteBuffer(data, script); BufferUtils.WriteBuffer(data, input.Sequence); apdus.AddRange(CreateAPDUSplit(LedgerWalletConstants.LedgerWallet_CLA, LedgerWalletConstants.LedgerWallet_INS_HASH_INPUT_START, (byte)0x80, (byte)0x00, data.ToArray())); currentIndex++; } return(apdus.ToArray()); }