Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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());
        }
Пример #4
0
        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());
        }