Awesome - cheers for that. I have already noted down the issue with returning a compressed key everytime, it's on my mental todo list. Nunit is awesome, my personal preference of a testing framework, what mocking framework do you usually use? I'm quite a fan of Telerik's JustMock.
Moq is really the only framework I have used although they are similar enough I don't see that being much of an issue.
Yeah, my extensions class is a complete mess at the moment. What's your opinion on extension for strings like HexToBigInteger, HexToBytes and for byte[] ToBigIntegerUnsigned etc? I wasn't sure if those are better kept as static methods or extension methods.
The extensions from "true" types/classes is straightforward. byte[] -> BigInteger, ulong ->VarInt, etc. The extensions from "psuedo classes" gets a little messier. Right now "hex" is just a string so having extension methods off of the string class which aren't applicable for non hex strings starts to feel a little kludgy. On the other hand I am not a fan of the static class with utility methods unless there is no other choice. I am wondering if a lightweight class for HexString would be a better design choice.
Maybe something like this?
HexString privHex = new HexString("E9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA33262");
var aBigInt = privHex.ToBigInteger();
...
Console.WriteLine("Private Key (hex) {0}", privHex.ToString());
Not 100% sure still going back and forth on that one.
Also, your point about adding in a keypair class. I wasn't too sure about this, I know that the likes of Bitcoinj use this approach. But I was considering maybe separating things out a bit more, having classes like:
PrivateKey - then PrivateKey would have a property called PublicKey
PublicKey - then PublicKey will have a property called PubKeyHash
PubKeyHash - which is essentially the bitcoin address which can be representing with different encoding methods.
Well Address is the versioned and checksummed PubKeyHash. Still that may work. if a KeyPair class was used I do think it should be lightweight mainly facilitating conversion between the related objects. I don't like bitcoinj approach on this as it makes the KeyPair (ECKey I believe) class very heavy and there isn't a clear separation of the objects.
I haven't put much thought into the Address class. But I was thinking about maybe making the Address class abstract and having classes like PubKeyHashAddress and ScriptHashAddress inheriting from Address.
That may work. The relationships between Bitcoin objects is complex and it makes having clear inheritance "interesting". To throw a monkey wrench into your structure above keep in mind that WIFPrivateKey, and Addressees are both implementations of the Base58Check structure (version +checksum added to a payload encoded in base58).