# ScriptPubKey

You might not know that as far as the Blockchain is concerned, there is no such thing as a Bitcoin Address. Internally, the Bitcoin protocol identifies the recipient of Bitcoin by a **ScriptPubKey**.

![](https://236133742-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvu-TV4ulp8gU1t%2F-LL8tOzX5dLCrxijS6s9%2F-LL8tRZjnzhpyuIocDEX%2FScriptPubKey.png?generation=1535616870796467\&alt=media)\
A **ScriptPubKey** may look like this:\
`OP_DUP OP_HASH160 14836dbe7f38c5ac3d49e8d790af808a4ee9edcf OP_EQUALVERIFY OP_CHECKSIG`

It is a short script that explains what conditions must be met to claim ownership of bitcoins. We will go into the types of operations in a **ScriptPubKey** as we move through the lessons of this book.

We are able to generate the ScriptPubKey from the Bitcoin Address. This is a step that all bitcoin clients do to translate the “human friendly” Bitcoin Address to the Blockchain readable address.

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

```csharp
var publicKeyHash = new KeyId("14836dbe7f38c5ac3d49e8d790af808a4ee9edcf");

var testNetAddress = publicKeyHash.GetAddress(Network.TestNet);
var mainNetAddress = publicKeyHash.GetAddress(Network.Main);

Console.WriteLine(mainNetAddress.ScriptPubKey); // OP_DUP OP_HASH160 14836dbe7f38c5ac3d49e8d790af808a4ee9edcf OP_EQUALVERIFY OP_CHECKSIG
Console.WriteLine(testNetAddress.ScriptPubKey); // OP_DUP OP_HASH160 14836dbe7f38c5ac3d49e8d790af808a4ee9edcf OP_EQUALVERIFY OP_CHECKSIG
```

Notice the **ScriptPubKey** for testnet and mainnet address is the same?\
Notice the **ScriptPubKey** contains the hash of the public key?\
We will not go into the details yet, but note that the **ScriptPubKey** appears to have nothing to do with the Bitcoin Address, but it does show the hash of the public key.

Bitcoin Addresses are composed of a version byte which identifies the network where to use the address and the hash of a public key. So we can go backwards and generate a bitcoin address from the **ScriptPubKey** and the network identifier.

```csharp
var paymentScript = publicKeyHash.ScriptPubKey;
var sameMainNetAddress = paymentScript.GetDestinationAddress(Network.Main);
Console.WriteLine(mainNetAddress == sameMainNetAddress); // True
```

It is also possible to retrieve the hash from the **ScriptPubKey** and generate a Bitcoin Address from it:

```csharp
var samePublicKeyHash = (KeyId) paymentScript.GetDestination();
Console.WriteLine(publicKeyHash == samePublicKeyHash); // True
var sameMainNetAddress2 = new BitcoinPubKeyAddress(samePublicKeyHash, Network.Main);
Console.WriteLine(mainNetAddress == sameMainNetAddress2); // True
```

> **Note:** A ScriptPubKey does not necessarily contain the hashed public key(s) permitted to spend the bitcoin.

So now you understand the relationship between a Private Key, a Public Key, a Public Key Hash, a Bitcoin Address and a ScriptPubKey.

In the remainder of this book, we will exclusively use **ScriptPubKey**. A Bitcoin Address is only a user interface concept.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://programmingblockchain.gitbook.io/programmingblockchain/bitcoin_transfer/payment_script.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
