4

I am a beginner here. A Transaction output has a field for amount and a locking script but no direct field for public address for which the output is meant. When a new transaction is being created, the wallet searches the UTXO set for outputs that is locked to one of the wallet's public addresses.

My question is, how does the wallet, while searching, know that a particular UTXO is locked to its public address?

Does it check each UTXO using a unlocking script to find whether it is locked to its public address?

Or does it maintain a separate database which maps public addresses to UTXOs meant for it, or anything similar for faster lookup?

How does it find this subset of UTXOs which is locked to the public address?

3 Answers 3

6

A Transaction output has a field for amount and a locking script but no direct field for public address for which the output is meant.

This is not quite correct and seems to be the source of the confusion. A "locking script" contains the essential part of an address surrounded by the additional commands necessary to lock (or encumber) the bitcoins in that output to the address. Let's look at an example; first we get an address:

$ bitcoin-cli getnewaddress
397yNmAFc1w6AK1gqkKNxJPb44jnvznm2b

Then let's ask the wallet what it knows about this address:

$ bitcoin-cli validateaddress 397yNmAFc1w6AK1gqkKNxJPb44jnvznm2b
{
  "isvalid": true,
  "address": "397yNmAFc1w6AK1gqkKNxJPb44jnvznm2b",
  "scriptPubKey": "a91451812710fc166bf61033afc0d2a8d7cda7a0fd8c87",
  "isscript": true,
  "iswitness": false
}

Note the scriptPubKey---that's what you're calling the "locking script." Let's see what that script says:

$ bitcoin-cli decodescript a91451812710fc166bf61033afc0d2a8d7cda7a0fd8c87
{
  "asm": "OP_HASH160 51812710fc166bf61033afc0d2a8d7cda7a0fd8c OP_EQUAL",
  "reqSigs": 1,
  "type": "scripthash",
  "addresses": [
    "397yNmAFc1w6AK1gqkKNxJPb44jnvznm2b"
  ]
}

The asm field is the interpreted form of the locking script; OP_HASH160 and OP_EQUAL are two parts of the P2SH-style encumbrance for addresses starting with a 3. The value in the middle 5181...fd8c is the hex form of the essential component of the address (other parts of the address are a version byte and a checksum; these aren't necessary to put in the locking script).

So, in short, the address 397yNmAFc1w6AK1gqkKNxJPb44jnvznm2b is a representation of the same thing as the scriptPubKey a91451812710fc166bf61033afc0d2a8d7cda7a0fd8c87. The scriptPubKey is the data that actually gets placed in the output to indicate that a certain set of bitcoins are controlled by the owner of the corresponding address.

How does it find this subset of UTXOs which is locked to the public address?

A wallet that's part of a full node simply scans every transaction the full node receives to see if any of their outputs pays one of that wallet's scriptPubKeys (addresses). If it does, the wallet saves that UTXO in its own database until it's time to spend it.

Lightweight wallets typically ask full nodes or servers to help them find the outputs. Sometimes this entails scanning blocks basically the same way the full node wallet does with some extra steps (see BIP37), sometimes the server builds a giant database of every address every seen and performs lookup queries on it (see Electrum servers), and sometimes the full node builds a very compact index and sends that to the lightweight client so the client can request blocks that might contain its transactions (see BIP158).

Notably, wallets need to know which UTXO paid you in order to show you your balance, so wallets don't look up UTXOs when spending, they look them up when receiving.

1
  • 1
    Thank you so much. My understanding of the "locking script" was wrong. Thank you again for the help. :) Commented Jun 3, 2018 at 8:15
1

A Transaction output has a field for amount and a locking script but no direct field for public address for which the output is meant.

A form of the address is included in the script.

The kind of script you're referring to is pay-to-public-key-hash (P2PKH). Your locking condition (output script) requires the payee to supply a signature matching a public key identified by its hash value.

OP_DUP OP_HASH160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIGNATURE

The unlocking condition in the input script supplies the public key and the signature.

<signature> <pubkey>

The unlocking condition is executed first, then the locking condition, yielding this validation script:

<signature> <pubkey> OP_DUP OP_HASH_160 <pubkeyhash> OP_EQUALVERIFY OP_CHECKSIGNATURE

My question is, how does the wallet, while searching, know that a particular UTXO is locked to its public address?

The wallet knows the public key it wants to search for. From the public key, it can generate <pubkeyhash>. Using the hash, it can query a set of outputs looking for P2PKH locks matching the public key hash.

0

The UTXO's script contains either a public key (in P2PK outputs, not really used anymore) or a HASH_160 of the public key or redeem script. Segwit outputs similarly contain a hash of the witness script (although this is a SHA256, not HASH_160).

Your wallet knows which redeem scripts and keys it contain, and is able to calculate the relevant hashes. It then simply checks new blocks to see if any output matches one for your wallet. It does not need to attempt to unlock any outputs.

Since the wallet scans blocks as they come in (and the chain the first time it is created), it is able to maintain a local UTXO set. This means that you need not search the entire chain every time you wish to make a tx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.