public static Script GetScriptPubKey(this string bech32Address) { if (bech32Address == null) { throw new ArgumentNullException(nameof(bech32Address)); } if (bech32Address.Length == C.PubKeyHashAddressLength && bech32Address.StartsWith(PubKeyAddressPrefix)) { var hash160 = PubKeyAddressEncoder.Decode(bech32Address, out var witnessVersion); KeyHelper.CheckBytes(hash160, 20); if (witnessVersion != 0) { InvalidAddress(bech32Address); } return(new Script(OpcodeType.OP_0, Op.GetPushOp(hash160))); } if (bech32Address.Length == C.ScriptAddressLength && bech32Address.StartsWith(ScriptAddressPrefix)) { var hash256 = PubKeyAddressEncoder.Decode(bech32Address, out var witnessVersion); KeyHelper.CheckBytes(hash256, 32); if (witnessVersion != 0) { InvalidAddress(bech32Address); } return(new Script(OpcodeType.OP_0, Op.GetPushOp(hash256))); } throw InvalidAddress(bech32Address); }
public void ValidAddress() { foreach (string[] address in VALID_ADDRESS) { byte witVer; byte[] witProg; Bech32Encoder encoder = bech32; try { witProg = bech32.Decode(address[0], out witVer); encoder = bech32; } catch { witProg = tbech32.Decode(address[0], out witVer); encoder = tbech32; } byte[] scriptPubkey = Scriptpubkey(witVer, witProg); string hex = string.Join("", scriptPubkey.Select(x => x.ToString("x2"))); Assert.Equal(hex, address[1]); string addr = encoder.Encode(witVer, witProg); Assert.Equal(address[0].ToLowerInvariant(), addr); } }
public void CanDetectError() { Bech32Encoder bech = Encoders.Bech32("bc"); byte wit; var ex = Assert.Throws <Bech32FormatException>(() => bech.Decode("bc1zw508e6qejxtdg4y5r3zarvaryvg6kdaj", out wit)); Assert.Single(ex.ErrorIndexes); Assert.Equal(8, ex.ErrorIndexes[0]); ex = Assert.Throws <Bech32FormatException>(() => bech.Decode("bc1zw508e6qeextdg4y5r3zarvaryvg6kdaj", out wit)); Assert.Equal(2, ex.ErrorIndexes.Length); Assert.Equal(8, ex.ErrorIndexes[0]); Assert.Equal(12, ex.ErrorIndexes[1]); }
public BitcoinWitPubKeyAddress(string bech32, Network expectedNetwork) : base(Validate(bech32, expectedNetwork), expectedNetwork) { Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true); byte witVersion; byte[] decoded = encoder.Decode(bech32, out witVersion); this._Hash = new WitKeyId(decoded); }
public BitcoinWitScriptAddress(string bech32, Network expectedNetwork = null) : base(Validate(bech32, expectedNetwork), expectedNetwork) { Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true); byte witVersion; byte[] decoded = encoder.Decode(bech32, out witVersion); this._Hash = new WitScriptId(decoded); }
private static string GetBase58(PubKey blindingKey, BitcoinAddress address) { if (address == null) { throw new ArgumentNullException(nameof(address)); } if (blindingKey == null) { throw new ArgumentNullException(nameof(blindingKey)); } if (address is BitcoinBlindedAddress ba) { address = ba.UnblindedAddress; } if (!(address is IBase58Data)) { byte witVer; byte[] witProg; var blech32Encoder = address.Network.GetBech32Encoder(Bech32Type.BLINDED_ADDRESS, true); Bech32Encoder bech32Encoder = null; switch (address) { case BitcoinWitPubKeyAddress _: bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, true); break; case BitcoinWitScriptAddress _: bech32Encoder = address.Network.GetBech32Encoder(Bech32Type.WITNESS_SCRIPT_ADDRESS, true); break; default: throw new ArgumentException($"no bech32 encoder for {address.GetType()} found"); } witProg = bech32Encoder.Decode(address.ToString(), out witVer); return(blech32Encoder.Encode(witVer, blindingKey.ToBytes().Concat(witProg))); } else { var network = address.Network; var keyId = address.ScriptPubKey.GetDestination(); if (keyId == null) { throw new ArgumentException("The passed address can't be reduced to a hash"); } var bytes = address.Network.GetVersionBytes(Base58Type.BLINDED_ADDRESS, true).Concat( network.GetVersionBytes(((IBase58Data)address).Type, true), blindingKey.ToBytes(), keyId.ToBytes()); return(NBitcoin.DataEncoders.Encoders.Base58Check.EncodeData(bytes)); } }
public void ValidAddress() { foreach (var address in VALID_ADDRESS) { Bech32Encoder encoder = Bech32Encoder.ExtractEncoderFromString(address[0]); var witProg = encoder.Decode(address[0], out var witVer); var scriptPubkey = Scriptpubkey(witVer, witProg); var hex = string.Join("", scriptPubkey.Select(x => x.ToString("x2"))); Assert.Equal(hex, address[1]); var addr = encoder.Encode(witVer, witProg); Assert.Equal(address[0].ToLowerInvariant(), addr); } }
public static T ToNetwork <T>(this T obj, Network network) where T : IBitcoinString { if (network == null) { throw new ArgumentNullException("network"); } if (obj == null) { throw new ArgumentNullException("obj"); } if (obj.Network == network) { return(obj); } if (obj is IBase58Data) { var b58 = (IBase58Data)obj; if (b58.Type != Base58Type.COLORED_ADDRESS) { byte[] version = network.GetVersionBytes(b58.Type, true); byte[] inner = Encoders.Base58Check.DecodeData(b58.ToString()).Skip(version.Length).ToArray(); string newBase58 = Encoders.Base58Check.EncodeData(version.Concat(inner).ToArray()); return(Network.Parse <T>(newBase58, network)); } else { string colored = BitcoinColoredAddress.GetWrappedBase58(obj.ToString(), obj.Network); BitcoinAddress address = Network.Parse <BitcoinAddress>(colored, obj.Network).ToNetwork(network); return((T)(object)address.ToColoredAddress()); } } else if (obj is IBech32Data) { var b32 = (IBech32Data)obj; Bech32Encoder encoder = b32.Network.GetBech32Encoder(b32.Type, true); byte wit; byte[] data = encoder.Decode(b32.ToString(), out wit); encoder = network.GetBech32Encoder(b32.Type, true); string str = encoder.Encode(wit, data); return((T)(object)Network.Parse <T>(str, network)); } else { throw new NotSupportedException(); } }
public static bool IsValid(string bech32, Network expectedNetwork, out Exception exception) { exception = null; if (bech32 == null) { exception = new ArgumentNullException("bech32"); return(false); } Bech32Encoder encoder = expectedNetwork.GetBech32Encoder(Bech32Type.WITNESS_PUBKEY_ADDRESS, false); if (encoder == null) { return(false); } try { byte witVersion; byte[] data = encoder.Decode(bech32, out witVersion); if (data.Length == 20 && witVersion == 0) { return(true); } } catch (Bech32FormatException bech32FormatException) { exception = bech32FormatException; return(false); } catch (FormatException) { exception = new FormatException("Invalid BitcoinWitPubKeyAddress"); return(false); } exception = new FormatException("Invalid BitcoinWitScriptAddress"); return(false); }