Get Started With OpenLaw in Minutes — Build a complete Dapp with the OpenLaw API + Truffle + React.js.

OpenLaw
9 min readMar 12, 2019

--

Introduction

At OpenLaw we want to help your decentralized application (“DApp”) integrate with today’s legal frameworks. A DApp is a software application where the backend code is run on a decentralized and distributed blockchain such as Ethereum, as opposed to a centralized server.

Building on the prior OpenLaw tutorial by Michael Rice, we will demonstrate a full end-to-end tutorial on how create a simple DApp integrated with the OpenLaw JavaScript API and Truffle’s React Box. Building a DApp with OpenLaw requires both the OpenLaw APIClient and OpenLaw Object libraries which come bundled in the OpenLaw NPM package.

While this tutorial covers deploying a smart contract in Truffle using React as the front-end, it is not necessary to use Truffle or React with OpenLaw. These tools are just one way to get from end-to-end to build your DApp and have it powered by OpenLaw. So, if you already have a smart contract deployed and want to skip the section about deploying a contract with Truffle, please feel free to do so.

Prerequisites: Basic knowledge of JavaScript and NPM/Node.js. Working knowledge of React and the Truffle framework is helpful for this particular tutorial, but not necessary to use the OpenLaw API and OpenLaw Object in general.

Already Installed on your computer (to do this tutorial in its entirety, make sure you have all of the below). Node version 8.9.4, NPM version 6.0.0, Truffle version 5.0.3 . For this tutorial, we are using a globally installed version of Truffle. If you haven’t installed Truffle, See the Truffle docs and Truffle NPM package. Also needed are MetaMask in your browser. Rinkeby Ether in your MetaMask account and an Infura.io account to connect your DApp to the Rinkeby testnet.

Skip Ahead:

If you want to skip straight to the code go to the Github here.

If you want to skip the deploying a contract with Truffle section, and go straight to building with the OpenLaw API in your App.js click here.

What we are building: — A DApp to interact with the OpenLaw API

Overview

For this tutorial, we are going to 1) create an OpenLaw template with OpenLaw’s easy to use markdown language, 2) use Truffle’s React Box to deploy a smart contract to accompany our OpenLaw template, 3) and finally use the OpenLaw JavaScript API to build a microsite with React.js to interact with our OpenLaw template.

Setup OpenLaw

Sign-up for OpenLaw account. If you do not already have an OpenLaw account, you can sign up for a free account.

OpenLaw Documentation. We will primarily be referencing the documentation from the OpenLaw APIClient and the OpenLaw Object both of which are packaged with OpenLaw’s NPM module.

Create an OpenLaw Template. Log in to the Openlaw.io instance you are using and create a template, for this demo I will use the title “OpenLaw API Tutorial Sale Agreement”, but you can call your agreement whatever you like. Then cut and paste the code below (For a full explanation of how to build this template, please see OpenLaw’s previous tutorial). The previous tutorial explains how to create a “Bill of Sale” Template, which is a simple blockchain based legal agreement where one party agrees to buy an item at a certain price from another party.

<%
[[Seller Address: EthAddress]]
[[Buyer Address: EthAddress]]
[[Purchased Item]]
[[Purchase Price: Number]]
[[@Purchase Price in Wei = Purchase Price * 1000000000000000000]]
[[Record Contract:EthereumCall(
contract: "0x9570a3C2e9cC4a43D03d06EC9bf36fa5B9bCd0D2";
interface:[{"constant":false,"inputs":[{"name":"_descr","type":"string"},{"name":"_price","type":"uint256"},{"name":"_seller","type":"address"},{"name":"_buyer","type":"address"}],"name":"recordContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}];
network:"Rinkeby";
function:"recordContract";
arguments: Purchased Item, Purchase Price in Wei, Seller Address, Buyer Address)]]
%>
\centered ** BILL OF SALE **Seller at Ethereum address [[Seller Address]] ("Seller") agrees to sell a **[[Purchased Item]]**, and buyer at Ethereum address [[Buyer Address]] ("Buyer") agrees to pay [[Purchase Price]] ether located at the contract address "Insert your contract address".[[Record Contract]]SELLER:[[Seller Signatory Email: Identity | Signature]]________________BUYER:[[Buyer Signatory Email: Identity | Signature]]

Set up with Truffle’s React Box, Add CSS, and Deploy a Smart Contract.

See: the Truffle React Box docs. As noted before, it is not necessary to use Truffle and/or React.js to with the OpenLaw API.

Start a new DApp with Truffle’s React Box from the terminal:

mkdir openlaw-api-tutorial
cd openlaw-api-tutorial
truffle unbox react

In the root directory install the dotenv and truffle-hdwallet NPM packages:

npm install dotenv
npm install truffle-hdwallet-provider@web3-one

From the root directory install the OpenLaw NPM package (at the time of writing this is version 0.1.20) in the client folder:

cd client
npm install openlaw --save

Add a .env and a truffle.js file to your root directory. The root directory should look like this:

Root directory with .env and truffle.js added.

Add the CSS. From the root directory add Semantic-UI and Semantic-UI-React for CSS. You can also use your preferred CSS framework.

cd client 
npm i semantic-ui
npm i semantic-ui-react

Note: if prompted in the terminal, install semantic-ui in default folders.

From the root directory go to your index.html file

cd client/public/index.html

and add the link to the Semantic-UI stylesheet inside <head></head>

<link 
rel="stylesheet" href="//cdn.jsdelivr.net/npm/semanticui@2.4.2/dist/semantic.min.css/>

Deploying the BillOfSale.sol contract with Truffle.

You will need a free Infura.io account for this part of the tutorial. Infura.ioprovides free access to an Ethereum node, which means you do not have to download the entire Ethereum blockchain to start developing. Sign up for free, login, go to the “Dashboard”, create a new project, after you create a new project, use the “Project Id” for your Infura API key.

Infura Dashboard

In the .env file create a MNEMONIC and INFURA_API_KEY variable. It should be your own mnemoic and Infura API Key (Note: do not put quotes around the mnemonic).

inside the .env file in our root directory

In the truffle.js file, cut and paste the following code to connect to the Rinkeby network (For a more in-depth discussion about configuring a network in truffle with Infura, click here):

require('dotenv').config();
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = process.env["MNEMONIC"];
var infuraKey = process.env["INFURA_API_KEY"];
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
// to customize your Truffle configuration!
//https://truffleframework.com/docs/truffle/getting-started/truffle-with-metamask
//add solc optimizer
solc: {
optimizer: {
enabled: true,
runs: 2000
}
},
//default -- contracts_build_directory:"./build/contracts",
// contracts_build_directory:"./client/src/contracts",
networks: {
ganache: {
host: "localhost",
port: 8545,
network_id: "*" // match any network
},
rinkeby: {
//wrap provider in function to avoid crashing
provider: function() {
return new HDWalletProvider(mnemonic, "https://rinkeby.infura.io/v3/" + infuraKey);
},
host: "localhost",
//port: 8545,
network_id: 4, //rinkeby test network
gas: 4000000, // Gas limit used for deploys
gasPrice : 1000000000
}
}
};

In the ./contracts folder delete the default SimpleStorage.sol file and replace with BillOfSale.sol and cut and paste the code in:

pragma solidity ^0.5.0;contract BillOfSale {
address payable public seller;
address public buyer;
string public descr;
uint public price;
bool public confirmed;
//from OpenLaw Template
function recordContract(string memory _descr, uint _price,
address payable _seller, address _buyer
) public {
descr = _descr;
price = _price;
seller = _seller;
buyer = _buyer;
}
function () external payable { }function confirmReceipt() public payable {
require(msg.sender == buyer, "only buyer can confirm");
require(address(this).balance == price, "purchase price must be funded");
address(seller).transfer(address(this).balance);
confirmed = true;
}
}

In the ./migrations folder delete the code inside “2_deploy_contracts.js”related to SimpleStorage and cut and paste this code:

var BillOfSale = artifacts.require("./BillOfSale.sol");module.exports = function(deployer) {
deployer.deploy(BillOfSale);
};

Compile and migrate our BillOfSale contract to the Rinkeby testnet. Go into the terminal and into the root directory of our DApp and run:

rm -r build/

this command will clear the ./build folder, and is good to use whenever the solidity files are changed.

From the root directory, compile and deploy our BillOfSale contract to the Rinkeby testnet:

truffle compile
truffle migrate --reset --network rinkeby

If your migration to Rinkeby was successful it should look like this:

Successful deployment to Rinkeby

Save your contract address (I highlighted mine in blue for example).

Using the OpenLaw JavaScript API

Add the address of your deployed smart contract into your OpenLaw API Tutorial Sale Agreement (highlighted in blue)

Open a second terminal window and from the root directory go to your client folder and run the DApp on http://localhost:3000/ in your browser. (Note:until we change our App.js file error will render in the browser, which we will get to in a moment).

cd client
npm run start

Then go to client/src/App.js . This is where we will be importing our OpenLaw API Client and OpenLaw Object from the NPM module. We will be doing the bulk of our coding in App.js.

Import the following into App.js:

import React, { Component } from "react";
import BillOfSaleContract from "./contracts/BillOfSale.json";
import getWeb3 from "./utils/getWeb3";
import { Container,Grid, Button, Form} from 'semantic-ui-react';
import { APIClient, Openlaw } from 'openlaw';
import "./App.css";

Note: Issue with Truffle with Create-React-App. (If you open the JavaScript console in your browser, and see that you are unable to import the BillOfSaleContract into App.js, then it may be an issue with Create-React-App part of Truffle’s React Box. This can be fixed by linking or copying the ./contracts folder from the ./build folder into ./src, see the below screenshot. )

Order of Operations for App.js

  1. Configure the OpenLaw API constants and access our OpenLaw instance and current template of OpenLaw Tutorial Sale Agreement.
  2. Set the state variables.
  3. Capture the User’s input from the Form.
  4. Build the OpenLaw object parameters
  5. Send the OpenLaw object to the OpenLaw instance and have it appear in the “Draft Management” or “Contract Management” tab.

Below is a description of all the variables and functions we will be using to integrate OpenLaw into our App.js file. The App.js code in its entirety is after these tables.

Constant variables
State variables
App.js Function Table

Finally, here is the App.js code:

Navigate to your OpenLaw Instance, login, and go to the “Draft Management” link in the menu. Now you should see the draft you submitted to OpenLaw.

Conclusion

To learn more about OpenLaw, check out our site and documentation for an overview and detailed reference guide and. Additionally, be sure to check outOpenLaw Elements which allows you to dynamically render React form components from your OpenLaw template as opposed to wiring up each field individually. You can also find us at hello@openlaw.io or tune in in our community Slack channel. Follow our Medium and Twitter for further announcements, tutorials, and helpful tips over the upcoming weeks and months

OpenLaw Tutorial Reference Links

--

--

OpenLaw

A commercial operating system for blockchains. By @awrigh01 and @bmalaus; a @ConsenSys spoke. https://openlaw.io/