// Visible for testing. internal static IList <IPEndPoint> ParseUserList(IEnumerable <string> userNames) { var addresses = new List <IPEndPoint>(); foreach (var user in userNames) { // All BitCoin peers start their nicknames with a 'u' character. if (!user.StartsWith("u")) { continue; } // After "u" is stripped from the beginning array contains unsigned chars of: // 4 byte IP address, 2 byte port, 4 byte hash check (ipv4) byte[] addressBytes; try { // Strip off the "u" before decoding. Note that it's possible for anyone to join these IRC channels and // so simply beginning with "u" does not imply this is a valid BitCoin encoded address. // // decodeChecked removes the checksum from the returned bytes. addressBytes = Base58.DecodeChecked(user.Substring(1)); } catch (AddressFormatException) { _log.WarnFormat("IRC nick does not parse as base58: {0}", user); continue; } // TODO: Handle IPv6 if one day the official client uses it. It may be that IRC discovery never does. if (addressBytes.Length != 6) { continue; } var ipBytes = new[] { addressBytes[0], addressBytes[1], addressBytes[2], addressBytes[3] }; var port = Utils.ReadUint16Be(addressBytes, 4); var ip = new IPAddress(ipBytes); var address = new IPEndPoint(ip, port); addresses.Add(address); } return(addresses); }