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