How to Retrieve OLGA’s Image From the Blockchain

An eternal token of love, OLGA’s image is stored on the most permanent medium known to man – the Bitcoin blockchain.

Here I will explain how the image is encoded, present a script which retrieves the image from the blockchain, and how to upscale the image.

The Blockchain Image

This exact image is saved on the blockchain:

The file is a miniature png file. A very small size was required to have it fit inside a bitcoin transaction.

Upscaled Version

Apply color grading and cubic resizing and – voila – the image looks more like the original drawing:

The algorithm is called Mantiuk Tone Mapping. I’ll explain the process at the end of this article. But first let’s retrieve the original file.

Base64 Encoding

The image is stored on the blockchain as a base64 string with the recognizable data:image/png;base64 prefix.

I predicted that if someone ever were to discover this string, they would easily be able to regenerate the image. Indeed, this is exactly what happened when OLGA was ‘unearthed’ in 2021.

Bitcoin Transaction

The base64 string is included in a transaction with ID 627ae48d6b4cffb2ea734be1016dedef4cee3f8ffefaea5602dd58c696de6b74.

You can look it up in any Bitcoin explorer: BlockCypher – Blockchain.com – Blockstream

The transaction has multiple outputs. Here’s the first of them:

The hex codes in blue and yellow contain some of the data. However, it took a full 165 such outputs to to fit the entire image. All of these are concatenated into one long hex string.

RC4 Stream Cipher

The string is RC4 encoded. It must be decoded with the input coin as the key. The input can be seen on Blockstream’s explorer:

Hex To String

The last step is to convert the hex string into a text string. Now you’ll find that it begins with CNTRPRTY and several more characters before data:image/png;base64, followed by the image data.

CNTRPRTY is the prefix which indicates the data is Counterparty encoded. This is a standard for encoding token data on Bitcoin. For this article this is irrelevant since I only want to show that OLGA’s image can be retrieved directly from Bitcoin. However, it’s worth mentioning that anyone running a Bitcoin node with the Counterparty extension can open the database and view OLGA’s code there.

String To Image

As mentioned before, this string can be opened with HTML. Include it in an img tag.

Save the below code as olga.html and open it in a browser:

<!DOCTYPE html>
<html>
  <head><title>OLGA</title></head>
  <body>
    <div style="text-align: center;">
      <h1>OLGA</h1>
      <img width="178" height="130" src="data:image/png;base64,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">
    </div>
  </body>
</html> 

Raw Transaction To Image

The below code generates OLGA’s image from the raw Bitcoin transaction. It gathers the data from Blockcypher’s API, decodes, converts to text, extracts the image data and finally displays the image.

Note that no libraries are needed. Only some RC4 helper functions are required. The code will stop working if Blockcypher goes down, but the same data can be collected from any Bitcoin node. All of them keep an exact copy. That’s the entire point of Bitcoin – and Bitcoin NFTs!

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>OLGA</title>
    <script>

      let tx = '627ae48d6b4cffb2ea734be1016dedef4cee3f8ffefaea5602dd58c696de6b74'

      async function get(tx) {
        let url = 'https://api.blockcypher.com/v1/btc/main/txs/' + tx + '?instart=0&outstart=0&limit=200';
        let obj = await (await fetch(url)).json();
        return obj;
      }
      let json;
      setTimeout(() => { get_json(tx); }, 1402);
      
      function get_json(tx) {
        (async () => {
          json = await get(tx)
          decode(json);
        })()
      }

      function decode(json) {
        //GET INPUT ID AND OUTPUT SCRIPTS
        json = JSON.parse(JSON.stringify(json));
        let utxo = json['inputs'][0]['prev_hash'];
        let script = [];
        for (const x of json['outputs']) {
          if (x['script_type'] == 'pay-to-multi-pubkey-hash') {
            script.push(x['script']);
          }
        }

        //HEX DATA FROM BITCOIN OUTPUTS
        let hex_data = '';
        for (let i = 0; i < script.length; i++) {
          let raw = script[i].substring(6, 68) + script[i].substring(74, 136);
          raw = xcp_rc4(utxo, raw);
          let len = raw.substring(0, 2);
          len = parseInt(len, 16);
          raw = raw.substring(2, 2+(len*2));
          raw = raw.substring(16);      
          hex_data += raw;
        }

        //HEX TO ASCII STRING
        let raw_ascii = hex2a(hex_data);

        //IMAGE DATA FROM ASCII STRING
        let img_data = raw_ascii.substring(raw_ascii.indexOf('data:image/'));
        img_data = img_data.slice(0,-1);

        //OUTPUT HTML
        let img_tag = '<img src="' + img_data + '">';
        let img_tag_double = '<img width="178" height="130" src="' + img_data + '">';
        let html = '<h1>OLGA</h1>';
        html += '<p><br><b>ORIGINAL</b><br>(89x65)<br>' + img_tag + '</p>';
        html += '<p><br><b>DOUBLE</b><br>(178x130)<br>' + img_tag_double + '</p>';
        document.getElementById('content').innerHTML = html;
      }

      //HELPER FUNCTIONS
      function hex2a(hexx) {
        var hex = hexx.toString();//force conversion
        var str = '';
        for (var i = 0; i < hex.length; i += 2)
          str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
        return str;
      }

      function xcp_rc4(key, datachunk) {
        return bin2hex(rc4(hex2bin(key), hex2bin(datachunk)));
      }

      function hex2bin(hex) {
        var bytes = [];
        var str;
        for (var i = 0; i < hex.length - 1; i += 2) {
          var ch = parseInt(hex.substr(i, 2), 16);
          bytes.push(ch);
        }
        str = String.fromCharCode.apply(String, bytes);
        return str;
      };

      function bin2hex(s) {
        // http://kevin.vanzonneveld.net
        var i, l, o = "",
            n;
        s += "";
        for (i = 0, l = s.length; i < l; i++) {
          n = s.charCodeAt(i).toString(16);
          o += n.length < 2 ? "0" + n : n;
        }
        return o;
      }; 

      function rc4(key, str) {
        //https://gist.github.com/farhadi/2185197
        var s = [], j = 0, x, res = '';
        for (var i = 0; i < 256; i++) {
          s[i] = i;
        }
        for (i = 0; i < 256; i++) {
          j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
          x = s[i];
          s[i] = s[j];
          s[j] = x;
        }
        i = 0;
        j = 0;
        for (var y = 0; y < str.length; y++) {
          i = (i + 1) % 256;
          j = (j + s[i]) % 256;
          x = s[i];
          s[i] = s[j];
          s[j] = x;
          res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
        }
        return res;
      }
    </script>

  </head>
  <body>
    <div id="content" style="text-align: center;">
      <h2>Loading Blockcypher API..</h2>
    </div>
  </body>
</html>

Upscaling with GIMP

The blokchain image was overexposed on purpose. The intent was to make a near-invisible engraving that would pop out when looking from an angle. On a modern screen this may not hold true anymore, but that’s how I presented it to Olga on our old LCD monitor.

Anyway, for showcasing OLGA it may be desired to apply a filter and increase the resolution.

Thankfully, this is easy with GIMP;

  1. Image → Crop to Content
    The blockchain image had the last few characters cut off due to a wallet bug. Therefore the bottom line is shown as transparent pixels. This command simply removes that line.
  2. Image → Tone Mapping → Mantiuk 2006…
    Leave the default settings and click OK.
  3. Image → Scale Image
    Set Width and Height to 300% and Interpolation to Cubic.

That’s all!

It’s on my TODO to do this programmatically with the gimpfu library.

Categories: Uncategorized