<pre><code>////////////////1st offline SERVER//////////////////
//Create Master Private Key with a seed
ExtKey privateKey = new ExtKey("16236c2028fd2018eb7049825e6b4f0191de4dbff003579918de7b7348ff06ac");
//create master public key from this privateKey
ExtPubKey pubKey = privateKey.Neuter();
//save it's wifStr as key to the next server to use and generate all child keys 
string wifStr = pubKey.ToString(Network.Main);
////////////////END//////////////////



////////////////2nd online SERVER//////////////////
ExtPubKey key = ExtPubKey.Parse(wifStr);
//The payment server receive an order, note the server does not need the private key to generate the address
uint orderID = 1001;
BitcoinAddress address = key.Derive(orderID).PubKey.GetAddress(Network.Main);
Console.WriteLine(address);
////////////////END//////////////////


////////////////3rd admin SERVER//////////////////
//Now on the server that have access to the private key, you get the private key from the orderID
ExtKey mPrivateKey = new ExtKey("16236c2028fd2018eb7049825e6b4f0191de4dbff003579918de7b7348ff06ac");
Key key1 = mPrivateKey.Derive(orderID).Key;
BitcoinSecret secret = key1.GetBitcoinSecret(Network.Main);
Console.WriteLine(secret); //Print a nice secret key string
////////////////END//////////////////
</code></pre>

CC BY-SA 3.0
2015-04-03T22:32:40.000Z
the code is right, except new ExtKey(string) does not exist. If you have the private ExtKey, use ExtKey.ToString(Network) / ExtKey.Parse(wif)
Nicolas Dorier
CC BY-SA 3.0
2015-04-03T21:00:28.440Z
2015-04-03T21:00:28.440Z
Haddar Macdasi
<p>when you are doing</p>

<pre><code>BitcoinAddress address1 = **pubKey**.Derive([some client data]).PubKey.GetAddress(Network.Main);
</code></pre>

<p>You are getting the bitcoin address, but not the master public key. (ExtPubKey)
A HD pub key have more information than just the pubkey.</p>

<p>The correct code is</p>

<pre><code>string wifStr = **pubkey**.Derive([some client data]).ToString(Network.Main)
</code></pre>

<p>Then you can reload it</p>

<pre><code>ExtPubKey key = ExtPubKey.Parse(wifStr)
</code></pre>

<p>In fact, the string format of an ExtPubKey have the Network to which it belong, that's why you also have the type "BitcoinExtKey" which represent in object oriented form both : the ExtPubKey AND the Network. If you need it :</p>

<pre><code>BitcoinExtPubKey wif = **pubkey**.GetWif(Network.Main)
</code></pre>

<p>Take a look at <a href="http://blockchainprogramming.azurewebsites.net/" rel="noreferrer">my book</a>, there is other code samples around HD keys.</p>

<p>Concerning the best practices, there is no silver bullet right now. I created an API called RapidBase which permit you to create wallet and add addresses to monitor in this wallet. (You can find it on github)</p>

<p>You can try it if you want, but it is very unstable for now (API wise), so expect things to change in the future. If you are using blockr, I think your best bet is to request each addresses as you are doing.</p>

<p>If you are using bitcoinq RPC, you can add address, but it takes time since bitcoin core will rescan the blockchain for fetching the relevant transactions each time.</p>

<p>I might be wrong, but for now there is no easy to use solution, exception rapidbase I developed, that is not very stable for now.</p>

CC BY-SA 3.0
2015-04-03T16:15:09.543Z
But he's not interested in the chaincode - he doesn't need the extended child key. What he needs is a way to monitor an address.
Nick ODell
CC BY-SA 3.0
2015-04-03T16:18:37.337Z
Well, this is a two part question


"How do I pass the master public key (pubKey) to this code in the online server ?"


This is a response to this one.


I'm editing the response for his second question.
Nicolas Dorier
CC BY-SA 3.0
2015-04-03T16:19:20.310Z
Ah, I see. I didn't see that first question.
Nick ODell
CC BY-SA 3.0
2015-04-03T16:24:23.400Z
didn't see the second one :D
Nicolas Dorier
CC BY-SA 3.0
2015-04-03T21:04:22.610Z
See my answer, I wanted to save the Neuter so I can use it as the master public key from which all childs created. If I save the wifStr and publish it on the online server if some hacker find the wifStr can he create from it the master private key ?
Haddar Macdasi
CC BY-SA 3.0
2015-04-03T22:31:52.890Z
you have a wif version of both : ExtKey and ExtPubKey, if you have the ExtKey and want the ExtPubKey, just do extKey.Neuter().ToString(Network.Main)
Nicolas Dorier
CC BY-SA 4.0
2021-05-03T19:42:19.890Z
@NicolasDorier Your book seems interesting, but the "new version" link is not working, only the "old version" one?
CodeOrElse
CC BY-SA 3.0
2015-04-03T16:09:50.387Z
2015-04-03T16:21:53.720Z
2015-04-03T16:21:53.720Z
Nicolas Dorier
<p>I'm using c# NBitcoin to generate master key at an offline server</p>

<pre><code>ExtKey privateKey = new ExtKey("[My seed]");
ExtPubKey pubKey = privateKey.Neuter();
</code></pre>

<p>I will need to give the online server the master public key, and it can generate as many addresses it needs, my questions are:</p>

<p>How do I pass the master public key (<strong>pubKey</strong>) to this code in the online server ?</p>

<pre><code>BitcoinAddress address1 = **pubKey**.Derive([some client data]).PubKey.GetAddress(Network.Main);
</code></pre>

<p>What is the best practice to listen for a payment received on this new address ? I'm working with web requests to <a href="http://btc.blockr.io/api/v1/address/unconfirmed/[address1]" rel="noreferrer">http://btc.blockr.io/api/v1/address/unconfirmed/[address1]</a><br>
My language is c# server side.</p>

<bip32-hd-wallets><c#><nbitcoin>
How to use NBitcoin for BIP32 wallets
Haddar Macdasi
# How to use NBitcoin for BIP32 wallets

(Asked by: username_0 on 2015-04-03)

I'm using c# NBitcoin to generate master key at an offline server

```
ExtKey privateKey = new ExtKey("[My seed]");
ExtPubKey pubKey = privateKey.Neuter();

```

I will need to give the online server the master public key, and it can generate as many addresses it needs, my questions are:

How do I pass the master public key (**pubKey**) to this code in the online server ?

```
BitcoinAddress address1 = **pubKey**.Derive([some client data]).PubKey.GetAddress(Network.Main);

```

What is the best practice to listen for a payment received on this new address ? I'm working with web requests to <http://btc.blockr.io/api/v1/address/unconfirmed/[address1]>  
My language is c# server side.

**Tags:** bip32-hd-wallets, c#, nbitcoin


---

## 2 answers

### Answer by username_1 on 2015-04-03. Score: 10 | Accepted answer

when you are doing

```
BitcoinAddress address1 = **pubKey**.Derive([some client data]).PubKey.GetAddress(Network.Main);

```

You are getting the bitcoin address, but not the master public key. (ExtPubKey)
A HD pub key have more information than just the pubkey.

The correct code is

```
string wifStr = **pubkey**.Derive([some client data]).ToString(Network.Main)

```

Then you can reload it

```
ExtPubKey key = ExtPubKey.Parse(wifStr)

```

In fact, the string format of an ExtPubKey have the Network to which it belong, that's why you also have the type "BitcoinExtKey" which represent in object oriented form both : the ExtPubKey AND the Network. If you need it :

```
BitcoinExtPubKey wif = **pubkey**.GetWif(Network.Main)

```

Take a look at [my book](http://blockchainprogramming.azurewebsites.net/), there is other code samples around HD keys.

Concerning the best practices, there is no silver bullet right now. I created an API called RapidBase which permit you to create wallet and add addresses to monitor in this wallet. (You can find it on github)

You can try it if you want, but it is very unstable for now (API wise), so expect things to change in the future. If you are using blockr, I think your best bet is to request each addresses as you are doing.

If you are using bitcoinq RPC, you can add address, but it takes time since bitcoin core will rescan the blockchain for fetching the relevant transactions each time.

I might be wrong, but for now there is no easy to use solution, exception rapidbase I developed, that is not very stable for now.

> **Comments:**
> **username_2**: But he's not interested in the chaincode - he doesn't need the extended child key. What he needs is a way to monitor an address.  
> **username_1**: Well, this is a two part question   "How do I pass the master public key (pubKey) to this code in the online server ?"   This is a response to this one.   I'm editing the response for his second question.  
> **username_2**: Ah, I see. I didn't see that first question.  
> **username_1**: didn't see the second one :D  
> **username_0**: See my answer, I wanted to save the Neuter so I can use it as the master public key from which all childs created. If I save the wifStr and publish it on the online server if some hacker find the wifStr can he create from it the master private key ?  
> **username_1**: you have a wif version of both : ExtKey and ExtPubKey, if you have the ExtKey and want the ExtPubKey, just do extKey.Neuter().ToString(Network.Main)  
> **username_3**: @username_1 Your book seems interesting, but the "new version" link is not working, only the "old version" one?  

---

### Answer by username_0 on 2015-04-03. Score: 2

```
////////////////1st offline SERVER//////////////////
//Create Master Private Key with a seed
ExtKey privateKey = new ExtKey("16236c2028fd2018eb7049825e6b4f0191de4dbff003579918de7b7348ff06ac");
//create master public key from this privateKey
ExtPubKey pubKey = privateKey.Neuter();
//save it's wifStr as key to the next server to use and generate all child keys 
string wifStr = pubKey.ToString(Network.Main);
////////////////END//////////////////

////////////////2nd online SERVER//////////////////
ExtPubKey key = ExtPubKey.Parse(wifStr);
//The payment server receive an order, note the server does not need the private key to generate the address
uint orderID = 1001;
BitcoinAddress address = key.Derive(orderID).PubKey.GetAddress(Network.Main);
Console.WriteLine(address);
////////////////END//////////////////

////////////////3rd admin SERVER//////////////////
//Now on the server that have access to the private key, you get the private key from the orderID
ExtKey mPrivateKey = new ExtKey("16236c2028fd2018eb7049825e6b4f0191de4dbff003579918de7b7348ff06ac");
Key key1 = mPrivateKey.Derive(orderID).Key;
BitcoinSecret secret = key1.GetBitcoinSecret(Network.Main);
Console.WriteLine(secret); //Print a nice secret key string
////////////////END//////////////////

```

> **Comments:**
> **username_1**: the code is right, except new ExtKey(string) does not exist. If you have the private ExtKey, use ExtKey.ToString(Network) / ExtKey.Parse(wif)  

---

