blockchainrpcbitcoinjson-rpc

Getting a list of keys from block 0


Using a local blockchain, is it is possible to use the bitcoin-core rpc commands to query a block (such as the genesis block) and get a list of all the public keys used in that block? If it is possible, which commands do I need to use?


Solution

  • Not entirely. This is because modern outputs contain addresses (technically scriptPubkeys) which are encoded hashes of a public key, see Types of Transactions. Hashes cannot be reversed (or Bitcoin wouldn't work at all), so in order to reveal the public key, the spender must provide it. You can extract public keys from spent outputs (via the scriptSig), but it is not straightforward. With legacy outputs, however, (as in the genesis block), this is possible without spending because they use a deprecated transaction type (Pay-To-Pubkey).

    There are a few commands to use. First, get the transactions in the block:

    1. getblockhash
    $ bitcoin-cli getblockhash 0
    000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
    

    where 0 is the block index of the genesis block.

    1. getblock
    $ bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f 2
    
    {
      "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
      "confirmations": 600908,
      "strippedsize": 285,
      "size": 285,
      "weight": 1140,
      "height": 0,
      "version": 1,
      "versionHex": "00000001",
      "merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
      "tx": [
        {
          "txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
          "hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
          "version": 1,
          "size": 204,
          "vsize": 204,
          "weight": 816,
          "locktime": 0,
          "vin": [
            {
              "coinbase": "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
              "sequence": 4294967295
            }
          ],
          "vout": [
            {
              "value": 50.00000000,
              "n": 0,
              "scriptPubKey": {
                "asm": "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG",
                "hex": "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac",
                "reqSigs": 1,
                "type": "pubkey",
                "addresses": [
                  "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
                ]
              }
            }
          ],
          "hex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"
        }
      ],
      "time": 1231006505,
      "mediantime": 1231006505,
      "nonce": 2083236893,
      "bits": "1d00ffff",
      "difficulty": 1,
      "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
      "nTx": 1,
      "nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
    }
    

    where the first argument is the block hash, and 2 is the verbosity (i.e. for json object with transaction data). Note that this is not much data for the genesis block, but for more recent blocks, this will be very large and slow.

    1. Extract the public key from the scriptPubkey Lucky for us, the genesis block uses a deprecated transaction type called Pay-to-Pubkey which gives us the public key and is of the form:

    <pubkey> OP_CHECKSIG

    In the first vout the scriptPubkey is 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG

    So the public key is 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f. Note that this is 65 bytes because early Bitcoin versions used uncompressed public keys.