Docxpresso Blockchain Integration

The primary goal for integrating blockchain anchoring in Docxpresso is to offer our users the possibility to certify integrity, time stamping and existence of any document generated within Docxpresso.

The anchoring of document data to the blockchain consists of multiple steps.

First of all Docxpresso creates a unique “digital signature” of the document we want to anchor to the blockchain. This is technically achived by creating a cryptographically safe string of 64 chars (SHA-256 HEX format) that is, by all practical means, uniquely associated with the document.

Then this unique document hash is again packed in a criptographically secure manner with many other hashes in order to create what is technically known as a Merkle root that is finally anchored to the Bitcoin blockchain.

As a result of all this process Docxpresso stores in its databases:

  • The hash associated with the corresponding Docxpresso document.
  • The time stamp certifying the moment in which the anchoring process took place.
  • The chainpoint/blockchain receipt.
  • The receipt reference.

Blockchain integration in Docxpresso

This chainpoint/blockchain receipt allows anyone, at any later time, to check if that particular document has been modified after the registered timestamp.

But how that can be done?

The easy way

Just go to and:

  1. Copy and paste the receipt in the “Proof” textbox.
  2. Upload the file you want to test against that receipt.
  3. Hit the “Verify proof” button.

If everything is OK the following message will show up:

valid receipt

If on the contrary the uploaded file does not correspond to the inserted receipt you will get an error message (the exact message may vary from case to case):

valid receipt

The hard way

It may well happen that you wish to personally check the validity of the receipt because the proof of the integrity has special interest or you are not confident in third parties like Docxpresso or Tierion.

This process consists of various steps and although we will spare the most technical details we will give references where the interested user will be able to dig up all required facts:

  • Generate a SHA-256 hash of the document to be verified against the corresponding receipt.
  • Check that the computed hash corresponds to the targetHash value included in the receipt.
  • Get the sourceId hash of the receipt and check that that transaction exists in any blockchain block explorer like by introducing its value in the provided search box (more technically skillful users may also use their APIs).
  • Check that the associated transaction has an OP_RETURN value equal to the Merkle root included in the receipt. Beware that in the web interface the OP_RETURN value may be displayed with a diffrent name but you will be able to identify it because it should equal your merkleRoot variable displayed at the receipt (also depending of the web interface you may be obliged to expand the results to get all transaction details).

If everything works out up to this point we can make sure that the transaction described in the receipt has been anchored to the (Bitcoin) blockchain. But what was anchored to the blockchain was the Merkle root and not the hash or digital signature of the document itself so we still need some extra work.

Chainpoint is an open standard so the unique procedure to obtain the Merkle root out of the original document hash and the chainpoint receipt is publicly available and you can find the details here: But fortunately the procedure is simple enough to be summarized in a few lines if you do not mind to omit the details.

In order to get the final Merkle root associated with the original document hash one has to run iteratively over all proof hashes included in the receipt as follows:

  • Start with the original hash and left or right concatenate it with the first proof hash depending if it is a left or right proof as indicated in the receipt.
  • Hash again the concatenated result with the SHA-256 algorithm.
  • Use the resulting hash to left or right concatenate it with the second proof and compute again the SHA-256 of the result.
  • So long so forth until you run over all the proof ítems in the receipt.

If the final hash coincides with the included Merkle root everything is OK, otherwise the receipt is false or, most probably, you implemented the procedure wrongly, as it happened to me first time I tried 🙂