Bitcoin Forum
December 14, 2024, 06:03:01 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 [2] 3 4 »  All
  Print  
Author Topic: NBitcoin : Almost full bitcoin implementation in .NET  (Read 30756 times)
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 05, 2014, 04:47:42 PM
 #21

Thanks for the tip, highly appreciate !! yes I develop in C# professionnally. Did NBitcoin so entrepreneurs can build business upon Bitcoin more easily.
You can use xUnit test runner in visual studio via extension gallery in vs or with http://visualstudiogallery.msdn.microsoft.com/463c5987-f82b-46c8-a97e-b1cde42b9099
Then it works as MSTest, and you can run/debug them directly in VS.

Yes, I am a proponent of Test Driven Development.
I ported the tests of Bitcoin Core or other bitcoin libraries before making its implementation.
The reason is that I wanted a class model similar to Bitcoin Core, this make porting easier and learning curve smooth.

I'm using xUnit just because it was easier to run in a build environment in the past than mstest, and I never looked back.

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
July 05, 2014, 04:59:59 PM
 #22

Quote
Thanks for the tip, highly appreciate !!

No problem.  It is a very solid library.  I hope you continue to develop it.

Quote
You can use xUnit test runner in visual studio via extension gallery in vs or with http://visualstudiogallery.msdn.microsoft.com/463c5987-f82b-46c8-a97e-b1cde42b9099

Yeah I grabbed the runner and it works fine in VS 2013.  

Quote
yes I develop in C# professionally. ... Yes, I am a proponent of Test Driven Development.
I had a feeling.  Glad to see another C# developer involved in Bitcoin.  We are a rare breed but I think a solid .Net library will be essential as Bitcoin moves more into the mainstream.  

Quote
I'm using xUnit just because it was easier to run in a build environment in the past than mstest, and I never looked back.
I hear you.  The only times in recent history that I used mstest was when I was working for a company which required it (because they had been using it for years).  I have always used NUnit but have been meaning to learn about XUnit.  This will give me a good excuse.
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 05, 2014, 05:13:47 PM
 #23

I will continue to maintain it. I intend to build my own project on top of it, also I am currently working with some bitcoin startup, and the community is very supportive, that get me a great incentive. Smiley

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
July 06, 2014, 04:52:09 PM
 #24

Glad to hear it.  I have a question on the difference between ExtKey and Bitcoin ExtKey (and likewise ExtPubKey and BitcoinExtPubKey).  If the BitcoinX class simply a wrapper around a generic ExtKey which contains the Bitcoin specific (i.e. BIP32) features?

I find myself needing to swap between them excessively.  That usually means I am missing something obvious.  My first thought is that you would be able to derive extended keys directly from the BitcoinExtKey class but those methods (Derive & Neuter are not implemented).  My assumption is that you are using these classes differently than I assumed they would be used.

Is there a reason that BitcoinExtKey and BitcoinExtPubKey do not implement derive and neuter or is it just that it hasn't been completed.  If it is the later I would gladly do a pull but I want to make sure I am not missing something obvious before I go down that road.
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 06, 2014, 06:00:51 PM
Last edit: July 06, 2014, 07:27:31 PM by Nicolas Dorier
 #25

BitcoinExtKey and BitcoinExtPubKey inherit from Base58Data as all base58Data it contains also information about the Network you are using (Main, TestNet or Reg).
ExtKey on the other hand, only contains the key information.

You can get the ExtKey from BitcoinExtKey by using the property BitcoinExtKey.Key.
However, to do the reverse, ExtKey need information about which Network to use to generate your base58 string.

So here is how your do to go back and forth :

Quote
String keyStr = "xprv9s21ZrQH143K4XUJvv1fQcoDGhLdtQUsfqX7zX4p5XvMtbh8bQxjjMRSTdeVakjmMtg52no13wj g16eSgKA32i1WRxSNYpDaRkF2GkG2NZc";
BitcoinExtKey base58key = new BitcoinExtKey(keyStr, Network.Main); //Would throw FormatException if the base58 is for Network.TestNet
ExtKey key = base58key.Key;
ExtPubKey pubkey = key.Neuter();

//Or, if you want NBitcoin to deduce the network from the base58 directly, this does exactly the same thing

base58key = Network.CreateFromBase58Data<BitcoinExtKey>(keyStr);
key = base58key.Key;
pubkey = key.Neuter();

//Now, if you want to transform back in BitcoinExtKey

base58key = new BitcoinExtKey(key, Network.Main);  //Or Network.Main.CreateBitcoinExtKey(key)
string base58Str = base58key.ToString(); //base58Str == key

//If you want the PubKey in base58 :
var base58PubKey = new BitcoinExtPubKey(pubkey, Network.Main);  //Or Network.Main.CreateBitcoinExtPubKey(key)
base58Str = base58PubKey.ToString(); //xpub661MyMwAqRbcH1Yn2wYfmkjwpjB8HsCj34SinuURdsTLmQ2H8xGzH9jvJxMYRRKchqEYF3xEB1sXsnQTRKU8oNYDChLuYPgyBneJvdzhc1J
//BitcoinExtPubKey.PubKey to get back the ExtPubKey

So to respond to your question, the reason why there is both BitcoinExtKey and ExtKey is because BitcoinExtKey represents a base58 data, which contains more information that simply the ExtKey. (that has no Network information attached to ExtKey, just the strict cryptographic data)
This works the same for all base58Data. (Key vs BitcoinSecret for example)

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
July 07, 2014, 08:53:48 PM
 #26

Yeah I got it working like that but I found it easier to modify BitcoinExtKey and BitcoinExtPubKey to have the Neuter and Derive methods to avoid excess swapping between types.  Also I think it would be more clear if the "Key" property in BitcoinExtKey (and "PubKey" in BitcoinExtPubKey) were named ExtKey and ExtPubKey as they do refer to the Extended Key and ExtPubKey.    Otherwise the accessor for the actual Key or PubKey becomes bitcoinExtKey.Key.Key and bitcoinExtPubKey.PubKey.PubKey.

Code:
            var masterPubKey = new BitcoinExtPubKey(masterPubKeyString, Network.Main);
            var masterServerWalletPubChain = masterPubKey.Derive(0);

...
       private BitcoinScriptAddress GenerateDepositAddresses(BitcoinExtPubKey parentExtPubKey, uint index)
        {
            BitcoinExtPubKey serverDepositPubChain1 = parentExtPubKey.Derive(1001);
            BitcoinExtPubKey serverDepositPubChain2 = parentExtPubKey.Derive(1002);
            BitcoinExtPubKey serverDepositPubChain3 = parentExtPubKey.Derive(1003);
           
            BitcoinExtPubKey extendedDepositPubKey1 = serverDepositPubChain1.Derive(index);
            BitcoinExtPubKey extendedDepositPubKey2 = serverDepositPubChain2.Derive(index);
            BitcoinExtPubKey extendedDepositPubKey3 = serverDepositPubChain3.Derive(index);

            var template = new PayToMultiSigTemplate();
            Script scriptPubKey = template.GenerateScriptPubKey(2, new[] { extendedDepositPubKey1.ExtPubKey.PubKey, extendedDepositPubKey2.ExtPubKey.PubKey, extendedDepositPubKey3.ExtPubKey.PubKey });
            return scriptPubKey.GetAddress(Network.Main);


DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
July 07, 2014, 09:31:13 PM
 #27

On an unrelated issue.  There are some unspendable but still valid outputs in the UTXO which the library does not seem to handle properly.  The constructor for the Script class should probably check for cases where there is a OP_PUSHDATA1, OP_PUSHDATA2, or OP_PUSHDATA4 and insufficient bytes to complete the push. A good test case is TxID  ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767 as it is a complete mess.

For example index 4 has a PkScript (in hex) of 0x4d.  Just an OP_PUSHDATA2 with no data following.  This code runs infinitely

Code:
            var script = new Script(new Byte[]{0x4d}); // raw bytes from ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767:4
   string asm = scrip.ToString();

Yeah it would have been nice if since the genesis blocks invalid pushes produced invalid txns and thus this txn would never have made it into a block.  I haven't had a chance to take a close look but I believe the issue is in Op.ReadData().

Quote
      internal static byte[] ReadData(Op op, Stream stream, bool ignoreWrongPush = false)
      {
         var opcode = op.Code;
         uint len = 0;
         BitcoinStream bitStream = new BitcoinStream(stream, false);
         if(opcode == 0)
            return new byte[0];

         if((byte)OpcodeType.OP_1 <= (byte)opcode && (byte)opcode <= (byte)OpcodeType.OP_16)
         {
            return new byte[] { (byte)(opcode - OpcodeType.OP_1 + 1) };
         }

         if(opcode == OpcodeType.OP_1NEGATE)
         {
            return new byte[] { 0x81 };
         }

         if(0x01 <= (byte)opcode && (byte)opcode <= 0x4b)
            len = (uint)opcode;
         else if(opcode == OpcodeType.OP_PUSHDATA1) //fails to return if there is <1 bytes after opcode
            len = bitStream.ReadWrite((byte)0);
         else if(opcode == OpcodeType.OP_PUSHDATA2) //fails to return if there is <2 bytes after opcode
            len = bitStream.ReadWrite((ushort)0);
         else if(opcode == OpcodeType.OP_PUSHDATA4) //fails to return if there is <4 bytes after opcode
            len = bitStream.ReadWrite((uint)0);
         else
            throw new FormatException("Invalid opcode for pushing data : " + opcode);

         byte[] data = new byte[len];
         var readen = stream.Read(data, 0, data.Length);
         if(readen != data.Length && !ignoreWrongPush)
            throw new FormatException("Not enough bytes pushed with " + opcode.ToString() + " expected " + len + " but got " + readen);
         else if(readen != data.Length)
         {
            op.IncompleteData = true;
            Array.Resize(ref data, readen);
         }
         return data;
      }
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 08, 2014, 11:44:34 AM
 #28

You are correct, I will fix this bug tonight, you'll just have to Update-Package NBitcoin

I accept invalid script as parameters, because the coinbase script is arbritrary data.
Trying to .ToString an invalid script can't return something sensible, but at least, I will add a Script.IsValid on the Script class, and make .ToString() terminate correctly.


Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 08, 2014, 05:57:37 PM
 #29

Here you go. (Also on github, so you can just merge with your clone)
Quote
Update-Package NBitcoin
http://docs.nuget.org/docs/start-here/using-the-package-manager-console

The new version is 1.4.0.9
I fixed the bug where invalid script can get you into infinite loop. (Did not renamed the Key and PubKey properties though, I will surely do it later on)

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1079


Gerald Davis


View Profile
July 10, 2014, 01:17:43 AM
 #30

Nice taking a look at it now.
TYDIRocks
Full Member
***
Offline Offline

Activity: 213
Merit: 100


View Profile
July 10, 2014, 05:50:38 AM
 #31

Great work, I'm surprised I haven't seen more replies here, as I remember reading this thread a few months ago.

Once I start getting my lazy ass motivated on furthering my programming knowledge I'll definitely be using your library. I've always wanted to make my own Bitcoin client, no matter how basic it is.


Import new address/private keys with ease: https://bitcointalk.org/index.php?topic=101161
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 12, 2014, 04:54:07 PM
 #32

Great work, I'm surprised I haven't seen more replies here, as I remember reading this thread a few months ago.

Once I start getting my lazy ass motivated on furthering my programming knowledge I'll definitely be using your library. I've always wanted to make my own Bitcoin client, no matter how basic it is.



Spread the word Wink

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
ThePok
Full Member
***
Offline Offline

Activity: 131
Merit: 100


View Profile
July 15, 2014, 11:51:09 AM
 #33

Oh i love it!

And so i donated Smiley

Finaly something that just works after hitting f5 Cheesy
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 15, 2014, 05:15:24 PM
 #34

Oh i love it!

And so i donated Smiley

Finaly something that just works after hitting f5 Cheesy

You forgot Install-Package NBitcoin ... except if you cloned the repo where it compiles directly with F5 :p
I never managed to compile the Bitcoin Core source code by the way... Wink
Thanks a lot for the tip !

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 15, 2014, 08:27:15 PM
 #35

Pushed new small version update, some helper methods ToString(Network) or static Parse methods to get and parse wif format instead of having to pass by Base58Data classes. (For ExtKey, ExtPubKey, and Key)
DeathAndTaxes, I renamed BitcoinExtKey.Key to ExtKey and same for the BitcoinPubExtKey.

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
ThePok
Full Member
***
Offline Offline

Activity: 131
Merit: 100


View Profile
July 16, 2014, 09:39:49 AM
 #36

Are you planning on including a actual Client to show off this nice BitcoinLib?
Nicolas Dorier (OP)
Hero Member
*****
Offline Offline

Activity: 714
Merit: 662


View Profile
July 16, 2014, 06:08:48 PM
 #37

Actually, I'm a little busy to create an indexer.
So that will probably be a blockchain.info or blockexplorer.com backed by Microsoft Azure. (which is pure awesomeness)
I will release it entirely open source.

Then my second project will be a WPF client app to track Colored Coins emission and trading.

If you intend to create a client with NBitcoin, I'll be glad to help you if any problem.

Bitcoin address 15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe
mcaizgk2
Member
**
Offline Offline

Activity: 66
Merit: 10


View Profile
July 16, 2014, 08:46:11 PM
 #38

Are you planning on including a actual Client to show off this nice BitcoinLib?

@ThePok I'm not sure whether your refer to BitcoinLib, but there's another thread for it: https://bitcointalk.org/index.php?topic=456322
TYDIRocks
Full Member
***
Offline Offline

Activity: 213
Merit: 100


View Profile
July 17, 2014, 04:32:57 AM
 #39

Are you planning on including a actual Client to show off this nice BitcoinLib?

I have begun making a simple client using this library and will surely make it open source once it is completed more.

However, you can figure a lot out by playing with the library and checking out all the tests.

Import new address/private keys with ease: https://bitcointalk.org/index.php?topic=101161
Zombie123
Legendary
*
Offline Offline

Activity: 868
Merit: 1000


View Profile
July 21, 2014, 09:48:44 PM
 #40

Great Work I am reading the code now!!
Pages: « 1 [2] 3 4 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!