/// <summary> /// Detects a given address format without validating it. /// </summary> /// <param name="str">The address to be detected</param> /// <param name="format">Detected format</param> /// <returns>True when detection is successful, false otherwise.</returns> public static bool TryDetectFormat(string str, out CashFormat format) { if (!string.IsNullOrEmpty(str)) { // According to Bitcoin Cash documentation, the prefix separator always exists. So, we use it as our primary guess factor. // Reference: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md var separatorIndex = str.IndexOf(':'); if (separatorIndex >= 0) { if (!Base32.ContainsInvalidCharacter(str, separatorIndex + 1)) { format = CashFormat.Cashaddr; return(true); } } else { if (!Base58Encoder.ContainsInvalidCharacter(str)) { format = CashFormat.Legacy; return(true); } } } format = default; return(false); }
private static byte[] ParseAddressHash(CashFormat format, string str, Network expectedNetwork) { switch (format) { case CashFormat.Legacy: var data = Encoders.Base58Check.DecodeData(str); var versionBytes = expectedNetwork.GetVersionBytes(Base58Type.PUBKEY_ADDRESS, false); if (versionBytes != null && data.StartWith(versionBytes)) { if (data.Length == versionBytes.Length + 20) { return(data.Skip(versionBytes.Length).ToArray()); } } break; case CashFormat.Cashaddr: var cashaddr = CashAddr.Decode(str); if (cashaddr.Prefix == expectedNetwork.Prefix) { return(cashaddr.Hash); } break; default: throw new ArgumentOutOfRangeException(); } throw new FormatException(); }
public static BchAddrData Create(CashFormat format, CashNetwork network, CashType type, byte[] hash) { return(new BchAddrData { Format = format, Network = network, Type = type, Hash = hash, }); }
/// <summary> /// returns the Version byte for base58 formats /// </summary> /// <param name="format"></param> /// <param name="network"></param> /// <param name="type"></param> /// <returns></returns> private static byte GetVersionByte(CashFormat format, CashNetwork network, CashType type) { switch (format) { case CashFormat.Legacy: if (network == CashNetwork.Mainnet && type == CashType.P2PKH) { return(0); } else if (network == CashNetwork.Mainnet && type == CashType.P2SH) { return(5); } break; case CashFormat.Bitpay: if (network == CashNetwork.Mainnet && type == CashType.P2PKH) { return(28); } else if (network == CashNetwork.Mainnet && type == CashType.P2SH) { return(40); } break; } if (network == CashNetwork.Testnet && type == CashType.P2PKH) { return(111); } else if (network == CashNetwork.Testnet && type == CashType.P2SH) { return(196); } else if (network == CashNetwork.RegTest && type == CashType.P2PKH) { return(111); } else if (network == CashNetwork.RegTest && type == CashType.P2SH) { return(196); } throw new Validation.ValidationError("Invalid parameters"); }