Example #1
0
        public static bool TryParse(string str, out NodeInfo nodeInfo)
        {
            nodeInfo = null;
            var parts = str.Split(new[] { '@' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length < 2)
            {
                return(false);
            }
            var nodeId = parts[0];

            if (!PubKey.Check(Encoders.Hex.DecodeData(nodeId), true))
            {
                return(false);
            }
            var host = String.Join("@", parts.Skip(1).ToArray());

            parts = host.Split(new[] { ':' }, StringSplitOptions.None);
            var maybePort = parts[parts.Length - 1];

            if (ushort.TryParse(maybePort, out ushort port))
            {
                host = string.Join(":", parts.Take(parts.Length - 1).ToArray());
            }
            else
            {
                port = 9735;
            }
            if (string.IsNullOrWhiteSpace(host))
            {
                return(false);
            }
            nodeInfo = new NodeInfo(nodeId, host, port);
            return(true);
        }
 protected override bool FastCheckScriptPubKey(Script scriptPubKey, out bool needMoreCheck)
 {
     needMoreCheck = false;
     return
         (scriptPubKey.Length > 3 &&
          PubKey.Check(scriptPubKey.ToBytes(true), 1, scriptPubKey.Length - 2, false) &&
          scriptPubKey.ToBytes(true)[scriptPubKey.Length - 1] == 0xac);
 }
        /// <summary>
        /// Extract the public key or null from the script
        /// </summary>
        /// <param name="scriptPubKey"></param>
        /// <param name="deepCheck">Whether deep checks are done on public key</param>
        /// <returns>The public key</returns>
        public PubKey ExtractScriptPubKeyParameters(Script scriptPubKey, bool deepCheck)
        {
            PubKey result = ExtractScriptPubKeyParameters(scriptPubKey);

            if (result == null || !deepCheck)
            {
                return(result);
            }
            return(PubKey.Check(result.ToBytes(true), true) ? result : null);
        }
 protected override bool CheckScriptSigCore(Network network, Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
 {
     Op[] ops = scriptSigOps;
     if (ops.Length != 2)
     {
         return(false);
     }
     return(ops[0].PushData != null &&
            ((ops[0].Code == OpcodeType.OP_0) || TransactionSignature.IsValid(network, ops[0].PushData, ScriptVerify.None)) &&
            ops[1].PushData != null && PubKey.Check(ops[1].PushData, false));
 }
        public PayToMultiSigTemplateParameters ExtractScriptPubKeyParameters(Script scriptPubKey)
        {
            bool needMoreCheck;

            if (!FastCheckScriptPubKey(scriptPubKey, out needMoreCheck))
            {
                return(null);
            }
            Op[] ops = scriptPubKey.ToOps().ToArray();
            if (!CheckScriptPubKeyCore(scriptPubKey, ops))
            {
                return(null);
            }

            //already checked in CheckScriptPubKeyCore
            int sigCount    = ops[0].GetInt().Value;
            int keyCount    = ops[ops.Length - 2].GetInt().Value;
            var keys        = new List <PubKey>();
            var invalidKeys = new List <byte[]>();

            for (int i = 1; i < keyCount + 1; i++)
            {
                if (!PubKey.Check(ops[i].PushData, false))
                {
                    invalidKeys.Add(ops[i].PushData);
                }
                else
                {
                    try
                    {
                        keys.Add(new PubKey(ops[i].PushData));
                    }
                    catch (FormatException)
                    {
                        invalidKeys.Add(ops[i].PushData);
                    }
                }
            }

            return(new PayToMultiSigTemplateParameters()
            {
                SignatureCount = sigCount,
                PubKeys = keys.ToArray(),
                InvalidPubKeys = invalidKeys.ToArray()
            });
        }
        public BitcoinBlindedAddress(string base58, Network network)
            : base(base58, network)
        {
            var  prefix  = network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true);
            var  vchData = Encoders.Base58Check.DecodeData(base58);
            var  version = network.GetVersionBytes(Base58Type.PUBKEY_ADDRESS, false);
            bool p2pkh   = true;

            if (version == null || !StartWith(prefix.Length, vchData, version))
            {
                p2pkh   = false;
                version = network.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, false);
                if (version == null || !StartWith(prefix.Length, vchData, version))
                {
                    throw new FormatException("Invalid Bitcoin Blinded Address");
                }
            }

            if (vchData.Length != prefix.Length + version.Length + 33 + 20)
            {
                throw new FormatException("Invalid Bitcoin Blinded Address");
            }
            var blinding = vchData.SafeSubarray(prefix.Length + version.Length, 33);

            if (PubKey.Check(blinding, true))
            {
                _BlindingKey = new PubKey(blinding);

                var hash = vchData.SafeSubarray(prefix.Length + version.Length + 33, 20);
                _UnblindedAddress =
                    p2pkh ? (BitcoinAddress) new BitcoinPubKeyAddress(new KeyId(hash), network)
                                                  : new BitcoinScriptAddress(new ScriptId(hash), network);
            }
            else
            {
                throw new FormatException("Invalid Bitcoin Blinded Address");
            }
        }
Example #7
0
        public async Task <object> Find(string data)
        {
            data = data.Trim();
            var b58 = NoException(() => WhatIsBase58.GetFromBitcoinString(data));

            if (b58 != null)
            {
                if (b58 is WhatIsAddress)
                {
                    var address = (WhatIsAddress)b58;
                    TryFetchRedeemOrPubKey(address);
                }
                return(b58);
            }

            if (data.Length == 0x40)
            {
                try
                {
                    return(await Controller.JsonTransaction(uint256.Parse(data), false));
                }
                catch
                {
                }
            }
            var b = NoException(() => Controller.JsonBlock(BlockFeature.Parse(data), true, false));

            if (b != null)
            {
                return(b);
            }

            if (data.Length == 0x28) //Hash of pubkey or script
            {
                TxDestination dest    = new KeyId(data);
                var           address = new WhatIsAddress(dest.GetAddress(Network));
                if (TryFetchRedeemOrPubKey(address))
                {
                    return(address);
                }

                dest    = new ScriptId(data);
                address = new WhatIsAddress(dest.GetAddress(Network));
                if (TryFetchRedeemOrPubKey(address))
                {
                    return(address);
                }
            }


            var script = NoException(() => GetScriptFromBytes(data));

            if (script != null)
            {
                return(new WhatIsScript(script, Network));
            }
            script = NoException(() => GetScriptFromText(data));
            if (script != null)
            {
                return(new WhatIsScript(script, Network));
            }

            var sig = NoException(() => new TransactionSignature(Encoders.Hex.DecodeData(data)));

            if (sig != null)
            {
                return(new WhatIsTransactionSignature(sig));
            }

            var pubkeyBytes = NoException(() => Encoders.Hex.DecodeData(data));

            if (pubkeyBytes != null && PubKey.Check(pubkeyBytes, true))
            {
                var pubKey = NoException(() => new PubKey(data));
                if (pubKey != null)
                {
                    return(new WhatIsPublicKey(pubKey, Network));
                }
            }

            if (data.Length == 80 * 2)
            {
                var blockHeader = NoException(() =>
                {
                    var h = new BlockHeader();
                    h.ReadWrite(Encoders.Hex.DecodeData(data));
                    return(h);
                });
                if (blockHeader != null)
                {
                    return(new WhatIsBlockHeader(blockHeader));
                }
            }
            return(null);
        }
        public BitcoinBlindedAddress(string base58, Network network)
            : base(base58, network)
        {
            var prefix  = network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true);
            var version = network.GetVersionBytes(Base58Type.PUBKEY_ADDRESS, false);
            var blech32 = network.GetBech32Encoder(Bech32Type.BLINDED_ADDRESS, false);

            if (blech32 != null && NBitcoin.DataEncoders.Encoders.ASCII
                .DecodeData(base58.Substring(0, blech32.HumanReadablePart.Length))
                .SequenceEqual(blech32.HumanReadablePart))
            {
                var    vchData  = blech32.Decode(base58, out var witnessVerion);
                bool   p2pkh    = !(version == null || !StartWith(prefix.Length, vchData, version));
                var    script   = false;
                var    blinding = vchData.SafeSubarray(0, 33);
                byte[] hash;
                if (vchData.Length == 53)
                {
                    hash = vchData.SafeSubarray(version.Length + 32, 20);
                }
                else
                {
                    hash   = vchData.SafeSubarray(version.Length + 32, vchData.Length - version.Length - 32);
                    script = true;
                }
                if (PubKey.Check(blinding, true))
                {
                    _BlindingKey = new PubKey(blinding);
                    if (witnessVerion == 0)
                    {
                        _UnblindedAddress = script?  (BitcoinAddress) new BitcoinWitScriptAddress(new WitScriptId(hash), network):  new BitcoinWitPubKeyAddress(new WitKeyId(hash), network);
                    }
                    else if (witnessVerion > 16 || hash.Length < 2 || hash.Length > 40)
                    {
                        throw new FormatException("Invalid Bitcoin Blinded Address");
                    }
                }
                else
                {
                    throw new FormatException("Invalid Bitcoin Blinded Address");
                }
            }
            else
            {
                var  vchData = NBitcoin.DataEncoders.Encoders.Base58Check.DecodeData(base58);
                bool p2pkh   = true;
                if (version == null || !StartWith(prefix.Length, vchData, version))
                {
                    p2pkh   = false;
                    version = network.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, false);
                    if (version == null || !StartWith(prefix.Length, vchData, version))
                    {
                        throw new FormatException("Invalid Bitcoin Blinded Address");
                    }
                }

                if (vchData.Length != prefix.Length + version.Length + 33 + 20)
                {
                    throw new FormatException("Invalid Bitcoin Blinded Address");
                }
                var blinding = vchData.SafeSubarray(prefix.Length + version.Length, 33);
                if (PubKey.Check(blinding, true))
                {
                    _BlindingKey = new PubKey(blinding);

                    var hash = vchData.SafeSubarray(prefix.Length + version.Length + 33, 20);
                    _UnblindedAddress =
                        p2pkh
                                                        ? (BitcoinAddress) new BitcoinPubKeyAddress(new KeyId(hash), network)
                                                        : new BitcoinScriptAddress(new ScriptId(hash), network);
                }
                else
                {
                    throw new FormatException("Invalid Bitcoin Blinded Address");
                }
            }
        }
        private static Command Connect()
        {
            var c   = new Command("connect", "connect to other lightning node");
            var op1 = new Option(new [] { "--nodeid", "--pubkey" }, "hex-encoded public key of the node we want to connect to")
            {
                Argument = new Argument <string>
                {
                    Arity = ArgumentArity.ExactlyOne
                }
            };

            op1.AddValidator(r =>
            {
                var msg = "Must specify valid pubkey in hex";
                var v   = r.GetValueOrDefault <string>();

                if (String.IsNullOrEmpty(v))
                {
                    return(msg);
                }

                if (!HexEncoder.IsWellFormed(v))
                {
                    return($"Invalid hex for pubkey: {v}");
                }

                var hexEncoder = new HexEncoder();
                var b          = hexEncoder.DecodeData(v);

                if (!PubKey.Check(b, true))
                {
                    return($"Invalid pubkey {v}");
                }
                return(null);
            });
            c.AddOption(op1);

            var op2 = new Option("--host", "ip:port pair of the node")
            {
                Argument = new Argument <string>
                {
                    Arity = ArgumentArity.ExactlyOne
                }
            };

            op2.AddValidator(r =>
            {
                var v = r.GetValueOrDefault <string>();

                if (String.IsNullOrEmpty(v))
                {
                    return("Invalid host");
                }

                if (!NBitcoin.Utils.TryParseEndpoint(v, 80, out var _))
                {
                    return("Invalid host");
                }

                return(null);
            });
            c.AddOption(op2);
            return(c);
        }
 private bool CheckWitScriptCore(Network network, WitScript witScript)
 {
     return(witScript.PushCount == 2 &&
            ((witScript[0].Length == 1 && witScript[0][0] == 0) || (TransactionSignature.IsValid(network, witScript[0], ScriptVerify.None))) &&
            PubKey.Check(witScript[1], false));
 }
Example #11
0
        /// <summary>
        /// Try to interpret the given string in a few ways in order to detect what object it's supposed to represent.
        /// </summary>
        /// <returns>The object represented by the input string. This may be a Bitcoin address, a script, a signature, a public key, etc.</returns>
        public async Task <object> Find(string data)
        {
            data = data.Trim();


            // Is it a Bitcoin address?
            var b58 = NoException(() => WhatIsBase58.GetFromBitcoinString(data));

            if (b58 != null)
            {
                if (b58 is WhatIsAddress address)
                {
                    await TryFetchRedeemOrPubKey(address);  // Shouldn't the return value here be checked?
                }

                return(b58);
            }


            // Is it a transaction ID?
            if (data.Length == 0x40)
            {
                try
                {
                    return(await Controller.JsonTransaction(uint256.Parse(data), false));
                }
                catch
                {
                    // Well, apparently it's not a transaction ID.
                }
            }


            // Is it a block feature?
            var b = NoException(() => Controller.JsonBlock(BlockFeature.Parse(data), true, false));

            if (b != null)
            {
                return(b);
            }


            // Is it the hash of a public key (modeled as KeyId in NBitcoin), or is it the hash of a script ID?
            if (data.Length == 0x28) // Hash of pubkey or script
            {
                TxDestination dest = new KeyId(data);

                var address = new WhatIsAddress(dest.GetAddress(Network));

                if (await TryFetchRedeemOrPubKey(address))
                {
                    return(address);
                }

                dest    = new ScriptId(data);
                address = new WhatIsAddress(dest.GetAddress(Network));

                if (await TryFetchRedeemOrPubKey(address))
                {
                    return(address);
                }
            }


            // Is it a script?
            var script = NoException(() => GetScriptFromBytes(data));

            if (script != null)
            {
                return(new WhatIsScript(script, Network));
            }

            script = NoException(() => GetScriptFromText(data));

            if (script != null)
            {
                return(new WhatIsScript(script, Network));
            }


            // Is it a transaction signature?
            var sig = NoException(() => new TransactionSignature(Encoders.Hex.DecodeData(data)));

            if (sig != null)
            {
                return(new WhatIsTransactionSignature(sig));
            }


            // Is it a hexstring representing the bytes of a public key?
            var pubkeyBytes = NoException(() => Encoders.Hex.DecodeData(data));

            if (pubkeyBytes != null && PubKey.Check(pubkeyBytes, true))
            {
                var pubKey = NoException(() => new PubKey(data));

                if (pubKey != null)
                {
                    return(new WhatIsPublicKey(pubKey, Network));
                }
            }


            // Is it a blockheader?
            if (data.Length == 80 * 2)
            {
                var blockHeader = NoException(() =>
                {
                    var h = ConsensusFactory.CreateBlockHeader();
                    h.ReadWrite(Encoders.Hex.DecodeData(data), ConsensusFactory);
                    return(h);
                });

                if (blockHeader != null)
                {
                    return(new WhatIsBlockHeader(blockHeader));
                }
            }


            // No idea what this is.
            return(null);
        }