tutorial: extract file from blockchain

example case

We have uploaded the file hello.txt and this is the resulting Pigi Upload API Response:


Bitcoin transactions in a nutshell

A bitcon transaction contains INPUTS and OUTPUTS. See https://learnmeabitcoin.com/technical/transaction-data for more detail. The file that we just uploaded is stored the first OUTPUT

get a raw transaction by TXID

It's possible to fetch the raw transaction from any txid by calling public APIs.

Popular API's for Bitcoin SV are:

inspecting the decoded transaction

To increase our understanding of the transaction that we just created. Let's inspect its JSON-decoded form. A bitcoin transaction is often serialized in hexadecimal format. This hexadecimal format can be parsed and represented as a JSON object. Blockchair's API will return the JSON represenation of the transaction in the data.<txid>.decoded_raw_transaction field.


inspecting the first Output

Take a closer look at decoded_raw_transaction.vout[0].scriptPubKey.asm. This is a Bitcoin Script and it contains an assembly language that is executed by miners in order to verify that a specific output can be spent. In this case, the output is unspendable and simply contains data. Let's dissect this script:

  1. 0
  3. 6d696e74426c7565
  4. 000003ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab34000000060e2a315f97660897d9d3c25d0f7fd851a8a161b49ed7b8d0bba2a1c24a6204a7de4ff107d5f18a56a357d6dd4473ce598211f7a3c4b396c7660b697b5252c2c708cb294d3aca7cfca554cc3edbb9ba5b1e7c2dbf2a7b27c57966898788cb2bb373ba594939a586a36bce566c7756df3e4

extracting the file (pseudocode)

Now that we understand how a Pigi binary blob is stored within a transaction, lets parse the Pigi binary blob and decrypt its contents.

  1. Read the first byte (version)
  2. Read the second byte (algorithm)
  3. Read the next 32 bytes (file id)
  4. Read the next 4 bytes (length)
  5. Read the next 16 bytes (IV)
  6. Read the next encryptedSize bytes (encryptedData)

part 1: parsing

part 2: decrypting AES-256-CBC

The upload reponse returned a secret key inside the identifiers.raw.secret field. In our case: WmH5w6eCzNrYSAc80Hgtd2GZq8qwAtt6PS3Lct6yzzA0

This is a base62-encoded representation of a 32 byte secret key. To convert the base62 key to binary, use any base62 library and use the following alphabet:



Now that the key is in binary form. We can decrypt encryptedData as follows:


part 3: decompressing

The decrypted data is an LZMA compressed binary blob. We must now decompress it


part 4: decoding CBOR

The decompressed data contains a CBOR encoded array. We must use CBOR to decode this decompressed data. After we have CBOR decoded the decompressed data, we have access to the filename, file type and file contents.


full Javascript example with code annotations



Updated 16 Mar 2022
Did this page help you?