# Bitcoin address

You know that your **Bitcoin Address** is what you share to the world to get paid.\
![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tQFihZpLIOmMtMYB%2FBitcoinAddress.png?generation=1535616888643986\&alt=media)\
You probably know that your wallet software uses a **private key** to spend the money you received on this address.\
![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tQFkdzs_BfMnCCqo%2FPrivateKey.png?generation=1535616887575580\&alt=media)

The keys are not stored on the network and they can be generated without access to the Internet.

This is how you generate a private key with NBitcoin:

```csharp
Key privateKey = new Key(); // generate a random private key
```

From the private key, we use a one-way cryptographic function, to generate a **public key**.

![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tQFmbU9np8a-GCEu%2FPrivKeyPubKey.png?generation=1535616879222437\&alt=media)

```csharp
PubKey publicKey = privateKey.PubKey;
Console.WriteLine(publicKey); // 0251036303164f6c458e9f7abecb4e55e5ce9ec2b2f1d06d633c9653a07976560c
```

There are two Bitcoin **networks**:

* **TestNet** is a Bitcoin network for development purposes. Bitcoins on this network worth nothing. &#x20;
* **MainNet** is the Bitcoin network everybody uses. &#x20;

> **Note:** You can acquire testnet coins quickly by using **faucets**, just google "get testnet bitcoins".

You can easily get your **bitcoin address** from your public key and the **network** on which this address should be used.

![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tQFoJSnvTSF8Rpuy%2FPubKeyToAddr.png?generation=1535616887376960\&alt=media)

```csharp
Console.WriteLine(publicKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main)); // 1PUYsjwfNmX64wS368ZR5FMouTtUmvtmTY
Console.WriteLine(publicKey.GetAddress(ScriptPubKeyType.Legacy, Network.TestNet)); // n3zWAo2eBnxLr3ueohXnuAa8mTVBhxmPhq
```

**To be precise, a bitcoin address is made up of a version byte (which is different on both networks) and your public key’s hash bytes. Both of these bytes are concatenated and then encoded into a Base58Check:**

![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tQFqeyXqY0L-5Xsd%2FPubKeyHashToBitcoinAddress.png?generation=1535616857978536\&alt=media)

```csharp
var publicKeyHash = publicKey.Hash;
Console.WriteLine(publicKeyHash); // f6889b21b5540353a29ed18c45ea0031280c42cf
var mainNetAddress = publicKeyHash.GetAddress(Network.Main);
var testNetAddress = publicKeyHash.GetAddress(Network.TestNet);
```

> **Fact:** A public key hash is generated by using a SHA256 hash on the public key, then a RIPEMD160 hash on the result, using Big Endian notation. The function could look like this: RIPEMD160(SHA256(pubkey))

The Base58Check encoding has some neat features, such as checksums to prevent typos and a lack of ambiguous characters such as '0' and 'O'.\
The Base58Check encoding also provides a consistent way to determine the network of a given address; preventing a wallet from sending MainNet coins to a TestNet address.

```csharp
Console.WriteLine(mainNetAddress); // 1PUYsjwfNmX64wS368ZR5FMouTtUmvtmTY
Console.WriteLine(testNetAddress); // n3zWAo2eBnxLr3ueohXnuAa8mTVBhxmPhq
```

> **Tip:** Practicing Bitcoin Programming on MainNet makes mistakes more memorable.
