public void NetworksAreValid() { foreach (Network network in NetworkRegistration.GetNetworks()) { Assert.NotNull(network); } }
public static T Parse <T>(string str, Network expectedNetwork) where T : IBitcoinString { if (str == null) { throw new ArgumentNullException("str"); } IEnumerable <Network> networks = expectedNetwork == null?NetworkRegistration.GetNetworks() : new[] { expectedNetwork }; bool maybeb58 = true; for (int i = 0; i < str.Length; i++) { if (!Base58Encoder.pszBase58Chars.Contains(str[i])) { maybeb58 = false; break; } } if (maybeb58) { try { Encoders.Base58Check.DecodeData(str); } catch (FormatException) { maybeb58 = false; } if (maybeb58) { foreach (IBase58Data candidate in GetCandidates(networks, str)) { bool rightNetwork = expectedNetwork == null || (candidate.Network == expectedNetwork); bool rightType = candidate is T; if (rightNetwork && rightType) { return((T)(object)candidate); } } throw new FormatException("Invalid base58 string"); } } foreach (Network network in networks) { int i = -1; foreach (Bech32Encoder encoder in network.Bech32Encoders) { i++; if (encoder == null) { continue; } var type = (Bech32Type)i; try { byte witVersion; byte[] bytes = encoder.Decode(str, out witVersion); object candidate = null; if (witVersion == 0 && bytes.Length == 20 && type == Bech32Type.WITNESS_PUBKEY_ADDRESS) { candidate = new BitcoinWitPubKeyAddress(str, network); } if (witVersion == 0 && bytes.Length == 32 && type == Bech32Type.WITNESS_SCRIPT_ADDRESS) { candidate = new BitcoinWitScriptAddress(str, network); } if (candidate is T) { return((T)candidate); } } catch (Bech32FormatException) { throw; } catch (FormatException) { continue; } } } throw new FormatException("Invalid string"); }
//https://en.bitcoin.it/wiki/List_of_address_prefixes public void CanDetectBase58NetworkAndType() { var tests = new[] { new { Base58 = "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", ExpectedType = typeof(BitcoinWitScriptAddress), Network = this.networkMain }, new { Base58 = "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", ExpectedType = typeof(BitcoinWitScriptAddress), Network = this.networkTestNet }, new { Base58 = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", ExpectedType = typeof(BitcoinWitPubKeyAddress), Network = this.networkMain }, new { Base58 = "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", ExpectedType = typeof(BitcoinWitPubKeyAddress), Network = this.networkTestNet }, new { Base58 = "bWqaKUZETiECYgmJNbNZUoanBxnAzoVjCNx", ExpectedType = typeof(BitcoinColoredAddress), Network = this.networkTestNet }, new { Base58 = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem", ExpectedType = typeof(BitcoinPubKeyAddress), Network = this.networkMain }, new { Base58 = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem", ExpectedType = typeof(BitcoinPubKeyAddress), Network = this.networkMain }, new { Base58 = "3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX", ExpectedType = typeof(BitcoinScriptAddress), Network = this.networkMain }, new { Base58 = "mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn", ExpectedType = typeof(BitcoinPubKeyAddress), Network = this.networkTestNet }, new { Base58 = "5Hwgr3u458GLafKBgxtssHSPqJnYoGrSzgQsPwLFhLNYskDPyyA", ExpectedType = typeof(BitcoinSecret), Network = this.networkMain }, new { Base58 = "92Pg46rUhgTT7romnV7iGW6W1gbGdeezqdbJCzShkCsYNzyyNcc", ExpectedType = typeof(BitcoinSecret), Network = this.networkTestNet }, new { Base58 = "3qdi7TXgRo1qR", ExpectedType = (Type)null, Network = (Network)null }, new { Base58 = "6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7", ExpectedType = typeof(BitcoinEncryptedSecretNoEC), Network = (Network)null }, new { Base58 = "6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX", ExpectedType = typeof(BitcoinEncryptedSecretEC), Network = (Network)null }, new { Base58 = "passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm", ExpectedType = typeof(BitcoinPassphraseCode), Network = (Network)null }, new { Base58 = "cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD", ExpectedType = typeof(BitcoinConfirmationCode), Network = (Network)null }, new { Base58 = "xprv9s21ZrQH143K3Gx1VAAD1ueDmwoPQUApekxWYSJ1f4W4m1nUPpRGdV5sTVhixZJT5cP2NqtEMZ2mrwHdW5RWpohCwspWidCpcLALvioXDyz", ExpectedType = typeof(BitcoinExtKey), Network = this.networkMain }, new { Base58 = "xpub661MyMwAqRbcEhHavVcryjNF2uA5woK6JCNRNJB8Z3dxPU8VNBd9E8GP7fusw2bhgYe7BXt6izr5iUaYo483919jjdtfEpG8j97djnEgJqo", ExpectedType = typeof(BitcoinExtPubKey), Network = this.networkMain }, new { Base58 = "akB4NBW9UuCmHuepksob6yfZs6naHtRCPNy", ExpectedType = typeof(BitcoinColoredAddress), Network = this.networkMain } }; foreach (var test in tests) { if (test.ExpectedType == null) { Assert.Throws <FormatException>(() => Network.Parse(test.Base58, null)); } else { IBitcoinString result = Network.Parse(test.Base58, null); Assert.True(test.ExpectedType == result.GetType()); if (test.Network != null) { if (test.Network.Name.ToLowerInvariant().Contains("test")) { Assert.Contains(result.Network, new[] { KnownNetworks.RegTest, KnownNetworks.TestNet }); } else { Assert.Equal(test.Network, result.Network); } } Network.Parse(test.Base58, test.Network); if (test.Network == null) { continue; } foreach (Network network in NetworkRegistration.GetNetworks()) { if (test.Network.Name.ToLowerInvariant().Contains("test")) { Assert.Contains(result.Network, new[] { KnownNetworks.RegTest, KnownNetworks.TestNet }); break; } else { if (network == test.Network) { break; } } Assert.Throws <FormatException>(() => Network.Parse(test.Base58, network)); } } } }