Skip to content
Decentralized notary using Squarelink.
JavaScript CSS HTML
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Hosted Demo Milestone Description

Press Me


SquareSign was a project built at ETHBoston @Harvard University solo, in 36-hours. In general, it's a rough waiver-signing/notarization platform that builds upon my past experiences (working with the OpenSign Ethereum smart contract libraries).

SquareSign is written completely in React, with no back-end services, or even, state management. Choosing to have some fun—not using Redux—the project uses a header master-component hiearchy.

Squarelink was used for web3 support + connecting to the Ethereum blockchain because: (1) they were the awesome sponsors, and (2) I wanted the application to be as simple as possible to use for non-blockchain-folk. Thus, you can just pop in and email/password and let SquareSign handle the rest.

Landing page

Document upload flow

Running SquareSign

If you want to spin up SquareSign, it's as simple as can be.

  1. Run git clone
  2. Change directory via cd squaresign/
  3. Run yarn
  4. Run yarn build
  5. Run yarn start


Squaresign relies heavily on React, IPFS, and my favourite modal plugin React-Responsive-Modal. Once documents are uploaded, they are hashed and stored directly upon IPFS (and hashed via the smart contract so that signatories can be tracked).

Contract architecture:

pragma solidity ^0.4.17;

contract Squaresign{
    struct Document {
        uint timestamp;
        bytes ipfs_hash;
        address[] signatures;
    mapping(address => bytes[]) public users; //maps addresses to agreement id
    mapping(bytes32 => Document) public documents; //maps keccak256(agreement_id) hashes to documents

    function addDocument(bytes id, bytes ipfs) public {
        users[msg.sender].push(ipfs); //Add document to users's "signed" list
        address[] memory sender = new address[](1);
        sender[0] = msg.sender;
        documents[keccak256(id)] = Document(block.timestamp, ipfs, sender);

    function signDocument(bytes id) public {
    function getSignatures(bytes id) public view returns (address[]) {
        return documents[keccak256(id)].signatures;


Squaresign is licensed under the MIT license.

You can’t perform that action at this time.