<commit_before>﻿using NBitcoin.DataEncoders;
using System;
using System.Linq;

namespace NBitcoin
{
	/// <summary>
	/// Base58 representation of a script hash
	/// </summary>
	public class BitcoinScriptAddress : BitcoinAddress, IBase58Data
	{
		public BitcoinScriptAddress(string base58, Network expectedNetwork)
			: base(Validate(base58, ref expectedNetwork), expectedNetwork)
		{
			var decoded = (expectedNetwork == null ? Encoders.Base58Check : expectedNetwork.NetworkStringParser.GetBase58CheckEncoder()).DecodeData(base58);
			_Hash = new ScriptId(new uint160(decoded.Skip(expectedNetwork.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, true).Length).ToArray()));
		}

		public BitcoinScriptAddress(string str, ScriptId id, Network expectedNetwork = null)
			: base(str, expectedNetwork)
		{
			if (id == null)
				throw new ArgumentNullException(nameof(id));
			_Hash = id;
		}

		private static string Validate(string base58, ref Network expectedNetwork)
		{
			if (base58 == null)
				throw new ArgumentNullException(nameof(base58));
			var networks = expectedNetwork == null ? Network.GetNetworks() : new[] { expectedNetwork };
			var data = (expectedNetwork == null ? Encoders.Base58Check : expectedNetwork.NetworkStringParser.GetBase58CheckEncoder()).DecodeData(base58);
			foreach (var network in networks)
			{
				var versionBytes = network.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, false);
				if (versionBytes != null && data.StartWith(versionBytes))
				{
					if (data.Length == versionBytes.Length + 20)
					{
						expectedNetwork = network;
						return base58;
					}
				}
			}
			throw new FormatException("Invalid BitcoinScriptAddress");
		}

		public BitcoinScriptAddress(ScriptId scriptId, Network network)
			: base(NotNull(scriptId) ?? Network.CreateBase58(Base58Type.SCRIPT_ADDRESS, scriptId.ToBytes(), network), network)
		{
			_Hash = scriptId;
		}

		private static string NotNull(ScriptId scriptId)
		{
			if (scriptId == null)
				throw new ArgumentNullException(nameof(scriptId));
			return null;
		}

		ScriptId _Hash;
		public ScriptId Hash
		{
			get
			{
				return _Hash;
			}
		}

		public Base58Type Type
		{
			get
			{
				return Base58Type.SCRIPT_ADDRESS;
			}
		}

		protected override Script GeneratePaymentScript()
		{
			return PayToScriptHashTemplate.Instance.GenerateScriptPubKey((ScriptId)Hash);
		}
	}

	/// <summary>
	/// Base58 representation of a bitcoin address
	/// </summary>
	public abstract class BitcoinAddress : IDestination, IBitcoinString
	{
		/// <summary>
		/// Detect whether the input base58 is a pubkey hash or a script hash
		/// </summary>
		/// <param name="str">The string to parse</param>
		/// <param name="expectedNetwork">The expected network to which it belongs</param>
		/// <returns>A BitcoinAddress or BitcoinScriptAddress</returns>
		/// <exception cref="System.FormatException">Invalid format</exception>
		public static BitcoinAddress Create(string str, Network expectedNetwork)
		{
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			return Network.Parse<BitcoinAddress>(str, expectedNetwork);
		}

		/// <summary>
		/// Detect whether the input base58 is a pubkey hash or a script hash
		/// </summary>
		/// <param name="str">The string to parse</param>
		/// <returns>A BitcoinAddress or BitcoinScriptAddress</returns>
		/// <exception cref="System.FormatException">Invalid format</exception>
		[Obsolete("Use BitcoinCreate(string, Network) instead")]
		public static BitcoinAddress Create(string str)
		{
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			return Network.Parse<BitcoinAddress>(str, null);
		}

		internal protected BitcoinAddress(string str, Network network)
		{
			if (network == null)
				throw new ArgumentNullException(nameof(network));
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			_Str = str;
			_Network = network;
		}

		string _Str;

		Script _ScriptPubKey;
		public Script ScriptPubKey
		{
			get
			{
				if (_ScriptPubKey == null)
				{
					_ScriptPubKey = GeneratePaymentScript();
				}
				return _ScriptPubKey;
			}
		}<commit_msg>Fix typo on obsolete call (#738)<commit_after>﻿using NBitcoin.DataEncoders;
using System;
using System.Linq;

namespace NBitcoin
{
	/// <summary>
	/// Base58 representation of a script hash
	/// </summary>
	public class BitcoinScriptAddress : BitcoinAddress, IBase58Data
	{
		public BitcoinScriptAddress(string base58, Network expectedNetwork)
			: base(Validate(base58, ref expectedNetwork), expectedNetwork)
		{
			var decoded = (expectedNetwork == null ? Encoders.Base58Check : expectedNetwork.NetworkStringParser.GetBase58CheckEncoder()).DecodeData(base58);
			_Hash = new ScriptId(new uint160(decoded.Skip(expectedNetwork.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, true).Length).ToArray()));
		}

		public BitcoinScriptAddress(string str, ScriptId id, Network expectedNetwork = null)
			: base(str, expectedNetwork)
		{
			if (id == null)
				throw new ArgumentNullException(nameof(id));
			_Hash = id;
		}

		private static string Validate(string base58, ref Network expectedNetwork)
		{
			if (base58 == null)
				throw new ArgumentNullException(nameof(base58));
			var networks = expectedNetwork == null ? Network.GetNetworks() : new[] { expectedNetwork };
			var data = (expectedNetwork == null ? Encoders.Base58Check : expectedNetwork.NetworkStringParser.GetBase58CheckEncoder()).DecodeData(base58);
			foreach (var network in networks)
			{
				var versionBytes = network.GetVersionBytes(Base58Type.SCRIPT_ADDRESS, false);
				if (versionBytes != null && data.StartWith(versionBytes))
				{
					if (data.Length == versionBytes.Length + 20)
					{
						expectedNetwork = network;
						return base58;
					}
				}
			}
			throw new FormatException("Invalid BitcoinScriptAddress");
		}

		public BitcoinScriptAddress(ScriptId scriptId, Network network)
			: base(NotNull(scriptId) ?? Network.CreateBase58(Base58Type.SCRIPT_ADDRESS, scriptId.ToBytes(), network), network)
		{
			_Hash = scriptId;
		}

		private static string NotNull(ScriptId scriptId)
		{
			if (scriptId == null)
				throw new ArgumentNullException(nameof(scriptId));
			return null;
		}

		ScriptId _Hash;
		public ScriptId Hash
		{
			get
			{
				return _Hash;
			}
		}

		public Base58Type Type
		{
			get
			{
				return Base58Type.SCRIPT_ADDRESS;
			}
		}

		protected override Script GeneratePaymentScript()
		{
			return PayToScriptHashTemplate.Instance.GenerateScriptPubKey((ScriptId)Hash);
		}
	}

	/// <summary>
	/// Base58 representation of a bitcoin address
	/// </summary>
	public abstract class BitcoinAddress : IDestination, IBitcoinString
	{
		/// <summary>
		/// Detect whether the input base58 is a pubkey hash or a script hash
		/// </summary>
		/// <param name="str">The string to parse</param>
		/// <param name="expectedNetwork">The expected network to which it belongs</param>
		/// <returns>A BitcoinAddress or BitcoinScriptAddress</returns>
		/// <exception cref="System.FormatException">Invalid format</exception>
		public static BitcoinAddress Create(string str, Network expectedNetwork)
		{
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			return Network.Parse<BitcoinAddress>(str, expectedNetwork);
		}

		/// <summary>
		/// Detect whether the input base58 is a pubkey hash or a script hash
		/// </summary>
		/// <param name="str">The string to parse</param>
		/// <returns>A BitcoinAddress or BitcoinScriptAddress</returns>
		/// <exception cref="System.FormatException">Invalid format</exception>
		[Obsolete("Use BitcoinAddress.Create(string, Network) instead")]
		public static BitcoinAddress Create(string str)
		{
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			return Network.Parse<BitcoinAddress>(str, null);
		}

		internal protected BitcoinAddress(string str, Network network)
		{
			if (network == null)
				throw new ArgumentNullException(nameof(network));
			if (str == null)
				throw new ArgumentNullException(nameof(str));
			_Str = str;
			_Network = network;
		}

		string _Str;

		Script _ScriptPubKey;
		public Script ScriptPubKey
		{
			get
			{
				if (_ScriptPubKey == null)
				{
					_ScriptPubKey = GeneratePaymentScript();
				}
				return _ScriptPubKey;
			}
		}
{'fraction_non_alphanumeric': 0.10951287320198236, 'fraction_numerical': 0.012691889278375439, 'mean_word_length': 3.9162210338680925, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6783617', 'n_tokens_mistral': 2869, 'n_tokens_neox': 2379, 'n_words': 611}