Introducing NEAR Document Cloud — A Decentralization Approach to Manage Documents

The Web3 way of managing documents

The robust and trustless solution to sign, manage store, and modify documents.

Everything is powered by the next-generation layer-one blockchain NEAR platform.

Blockchain Choice Justification

NEAR is not the most popular blockchain at the time of writing but it has a very good foundation to be chosen for a decentralized application that is at least theoretically a mass consumer-focused app.

It needs to be cheap and fast, it should be scalable and allow users to easily enter it without having any prior setup and it also should not impact the environment. Compared to Ethereum, NEAR has it and make it beneficial for such use case.

The Problem Description

We all sign or at least acknowledge documents or agreements with various parties. These can be banks, real estate agents, and landlords. The same is true for companies that do endeavors formalized by means of agreements with consumers and other businesses

A single agreement that bounds two parties can have several revisions issued and thus management (ie storing, issuing, issuing) of this all is signing complex.

There are more and more such solutions to reduce the friction of document management but at the time of writing, none of these is based on web3. That is why NEAR Document Cloud is yet another solution to this problem but this time there is decentralization involved.

User Interface

The UI layer is currently at the wireframing stage. Generally, my personal opinion is that any UI is infinitely better than no UI even for means of communication among technical guys. It automatically makes everyone on the same page and clearly understands the idea.

Let’s discuss the NEAR document cloud’s most important frameworks and treat it as the best explanation of the whole project’s purpose

Listing agreements

Here we show all either issued by or issued for the agreements logged-in user. This is a kind of a welcome page where the user can immediately see any actions to be performed ie sign a newly issued agreement before some due date.

Listing of all documents

On the list we also can see a clear agreements between agreements issued by me and those issued for me (where I am supposed to sign)

Issuing new agreement

Visualization of adding a new agreement process with a very simple form

Any user can add an agreement. Adding agreement requires input at least ipfs link to the initial document version and intended signer. All remaining details are a matter of potential extension and decision on where to store these (on-chain vs off-chain).

Signing agreements

Users can sign the agreement only if it has been issued with explicit indication he/she is the intended signer. Trying to sign an agreement that has not been issued for acting user will throw (reject tx).

An agreement with a credit card operator that is not yet signed

In the image above we can see the Agreement with the credit cart operator not signed because it has been updated – the issuer has added revision two and to formally be in force this agreement needs to be signed again. This can be easily achieved by clicking the sign with the wallet button and acknowledging the tx.

Adding new revision

User can only add revision for those agreements he/she has issued. Trying to add a revision to an agreement issued by someone else will result in transaction rejection.

Adding new revisions could potentially be achieved on a separate screen and require just entering ipfs link to a new document. All other details of the agreement like previous links, signing history, or other details should be read-only at this stage.

Adding a new revision sets the whole agreement in isSigned : false the state, no matter if it has already been signed or not. Conditions have changed and the agreement can not be automatically in force/signed without the signer explicitly signing it again.

See it in action

The Code

contract contract

Agreement class should have:

  • issuer for storing the issuer wallet address
  • isSigned for tracking the agreement’s latest revision signed state
  • versions for keeping track of all versions of the agreement

Additionally, it has two methods one when the agreement is signed and one when a new revision is added.

Let’s break it down and discuss the code in chunks.

constructor(public uri: string, public signer: string) {
this.issuer = Context.sender;
this.isSigned = false;
this.versions = new PersistentVector<string>(`${uri}-v`);
this.uri = uri;

In the constructor, we see that each agreement has its signer set to method callee, it is initially not signed, it has added the first version to its versions collection (by means of PersistenVector), and its uri is initial URI, event if the current URI will change later on.

addAgreementVersion(version: string): void {
    assert(Context.sender == this.issuer, "Only issuer can update                       
this.isSigned = false;

addAgreementVersion just ensures that the callee is the initial issuer and resets isSigned flag to false (as after adding a new revision the whole agreement should be signed again since apparently, the conditions have changed) and adds the new version to theversioncollection

signAgreement(): void{
assert(Context.sender == this.signer, "You're not allowed to sign this");
this.isSigned = true;

signAgreement ensures the callee is the one indicated as the signer and if so it changes the flag isSigned to true.

The agreement contract usage

Those functions here simulate a kind of a factory class making sure there is a register with all agreements and call functions of each class to present how things work down at the class level.

Originally Posted at

Introducing NEAR Document Cloud — A Decentralization Approach to Manage Documents was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.

Leave a Comment