# Building an OpenZeppelin dapp with Solidity Hot Loader

**URL:** <https://forum.openzeppelin.com/t/building-an-openzeppelin-dapp-with-solidity-hot-loader/1843>\
**Category:** Guides and Tutorials\
**Created:** [December 18, 2019, 5:45am UTC](https://forum.openzeppelin.com/t/building-an-openzeppelin-dapp-with-solidity-hot-loader/1843 "2019-12-18T05:45:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [December 18, 2019, 5:45am UTC](https://forum.openzeppelin.com/t/building-an-openzeppelin-dapp-with-solidity-hot-loader/1843/1 "2019-12-18T05:45:54Z")

</div>

[UPDATE] ⚠ This tutorial uses _OpenZeppelin Network.js_ which is deprecated. We are no longer actively developing new features nor addressing issues.

## Introduction

The [Solidity Hot Loader](https://github.com/OpenZeppelin/solidity-loader) brings the web developer experience to Solidity to help you develop your smart contracts and dapps faster.

In this tutorial, we will use Solidity Hot Loader, to build a simple dapp.  
We will create a Counter dapp, which displays the value of a Counter that can be increased. We will update the code in the smart contract to show the power of the Solidity Hot Loader.

The Solidity Hot Loader watches your smart contract `.sol` files you’re using. Once there’s a change, it compiles them, updates the local blockchain using the [OpenZeppelin SDK](https://openzeppelin.com/sdk/), and refreshes your app in the browser while preserving your blockchain state. Compare this against the existing Solidity development cycle.

The Solidity Hot Loader development cycle:

1. Make a change to your smart contract `.sol` file and save it
2. Wait a bit
3. Done

The existing (slow) Solidity development cycle:

1. Make a change to your smart contract `.sol` file and save it
2. Compile your contract
3. Deploy your contract
4. Restore the state
5. Restart dapp to get new contract

## Video

If you enjoy video 📹 , watch @ylv-io’s Devcon presentation: **Devcon Delightful Developer Experience With Solidity Hot Loader**.

[![](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/b/b8f0cacfe4209d16bc54d51890d1468ebc252130.jpeg "Devcon 5 Igor Yalovoy") ](https://www.youtube.com/watch?v=KU6_r3sJ2E4)

## Setting up the environment

We will use the `create-react-app` package to bootstrap a React application.

First we need a local blockchain to develop on.  
We use `ganache-cli` , so go ahead and install (if you haven’t already) and then run a local blockchain using `ganache-cli`

```auto
$ npm install -g ganache-cli
$ ganache-cli --deterministic

```

Next we need a project directory to develop our project in. In a separate terminal create the project directory and create `package.json` with `npm init`.

```auto
mkdir myproject && cd myproject
npm init -y

```

We use the OpenZeppelin CLI for compiling and deploying our contract, so go ahead and install _OpenZeppelin CLI_

```auto
npm install @openzeppelin/cli

```

Next, initialize the project with OpenZeppelin. This will create directories and config for our project.

```auto
$ npx openzeppelin init
? Welcome to the OpenZeppelin SDK! Choose a name for your project myproject
? Initial project version 1.0.0
Project initialized. Write a new contract in the contracts folder and run 'openzeppelin create' to deploy it.

```

## Counter contract

Our Counter smart contract consists of an integer `value` and a function to increase it by one.

In the `contracts` directory save `Counter.sol` with the following contents:

```auto
pragma solidity ^0.6.0;

contract Counter {
    uint256 public value;

    function increase() public {
        value = value + 1;
    }
}

```

Next we deploy the Counter contract to our local blockchain.

Run `npx oz deploy` and use the interactive commands to deploy the Counter contract to the development network.  
Choose kind: upgradeable.  
There is no function that we need to call to `initialize`.

```auto
$ npx oz deploy
✓ Compiled contracts with solc 0.6.12 (commit.27d51765)
? Choose the kind of deployment upgradeable
? Pick a network development
? Pick a contract to deploy Counter
✓ Added contract Counter
✓ Contract Counter deployed
All implementations have been deployed
? Call a function to initialize the instance after creating it? No
✓ Setting everything up to create contract instances
✓ Instance created at 0xCfEB869F69431e42cdB54A4F4f105C19C080A601
To upgrade this instance run 'oz upgrade'
0xCfEB869F69431e42cdB54A4F4f105C19C080A601

```

## Creating the dapp

We will create our dapp using the `create-react-app` package, which bootstraps a simple client-side application using React.

```auto
npx create-react-app client

```

## Setup Solidity Hot Loader

Now that the directories for our dapp have been created, we can install Solidity Hot Loader.  
In the `client` directory install _Solidity Hot Loader_

```auto
npm install @openzeppelin/solidity-loader

```

The Solidity Hot Loader uses `json-loader` so we should go ahead and install that too.

```auto
npm install json-loader

```

Next up, we configure Solidity Hot Loader and set it to enabled.  
To stop the Solidity Hot Loader automagically updating our contracts, set disabled to true.

In the `client` directory create a `config` directory. In the `config` directory create a `webpack.js` file with the following code, notice that we are starting with the Solidity Hot Loader enabled (`disabled: false`):

```auto
// client/config/webpack.js
const solidityLoaderOptions = {
  network: 'development',
  // you can stop loader from automatic compile/push/upgrade
  // action by setting disabled flag to true, but it will still
  // serve .json files from file system
  disabled: false,
};

module.exports = {
  solidityLoader: {
    test: /\.sol$/,
    use: [
      { loader: 'json-loader' },
      {
        loader: '@openzeppelin/solidity-loader',
        options: solidityLoaderOptions,
      },
    ],
  },
  solidityLoaderOptions,
};

```

We now add in the Solidity Hot Loader to webpack.

In the `client` directory create a `config-overrides.js` file with the following code:

```auto
// client/config-overrides.js
const { solidityLoader } = require('./config/webpack');

module.exports = function override(config, env) {
  //do stuff with the webpack config...

  // allow importing from outside of app/src folder, ModuleScopePlugin prevents this.
  const scope = config.resolve.plugins.findIndex(o => o.constructor.name === 'ModuleScopePlugin');
  if (scope > -1) {
    config.resolve.plugins.splice(scope, 1);
  }

  // add solidity loader support
  // have to insert before last loader, because CRA user 'file-loader' as default one
  config.module.rules.splice(config.module.rules - 2, 0, solidityLoader);

  return config;
};

```

We use `react-app-rewired` to override `create-react-app` webpack configs to add in the Solidity Hot Loader without ejecting.

In the `client` directory, install `react-app-rewired`

```auto
$ npm i react-app-rewired

```

To use `react-app-rewired`, we now need to change the `package.json` scripts.

In `package.json` in the `client` directory, update the scripts to use `react-app-rewired` so that they looks as follows:

```auto
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },

```

## Add the dapp code

We will use [OpenZeppelin Network.js](https://github.com/OpenZeppelin/openzeppelin-network.js) to access the Web3 provider. **OpenZeppelin Network.js** is an easy to use and reliable library that provides one line access to the web3 API. It can be used in both React and in (vanilla) JavaScript. It also supports the Gas Station Network.

First we change to the `client` directory

```auto
cd client

```

Then, install _OpenZeppelin Network.js_  
⚠ This project is deprecated. We are no longer actively developing new features nor addressing issues.

```auto
npm install @openzeppelin/network 

```

Our dapp will display a Counter that we can increase the value of, consisting of displaying the value and a button to increase the counter.

In the code below, first we import `useWeb3Injected` from the React implementation of **OpenZeppelin Network.js** (`@openzeppelin/network/react`). We then get a `web3Context` using `useWeb3Injected`.  
The dapp loads the Counter json artifact.  
The display of the Counter is handled in a component.  
To start, on the `client/src/App.js` file, replace the placeholder code in `App.js` in our react project with the following code:

```auto
// client/src/App.js
import React, { useState } from 'react';
import './App.css';

import { useWeb3Network } from '@openzeppelin/network/react';
import Counter from './components/Counter.js';

function App() {
  const web3Context = useWeb3Network('http://127.0.0.1:8545');
  
  // load Counter json artifact
  let counterJSON = undefined;
  try {
    // see https://github.com/OpenZeppelin/solidity-loader
    counterJSON = require('../../contracts/Counter.sol');
  } catch (e) {
    console.log(e);
  }

  // load Counter instance
  const [counterInstance, setCounterInstance] = useState(undefined);
  let deployedNetwork = undefined;
  if (!counterInstance && web3Context && counterJSON && counterJSON.networks && web3Context.networkId) {
    deployedNetwork = counterJSON.networks[web3Context.networkId.toString()];
    if (deployedNetwork) {
      setCounterInstance(new web3Context.lib.eth.Contract(counterJSON.abi, deployedNetwork.address));
    }
  }

  return (
    <div className="App">
      <div>
        <h1>OpenZeppelin Solidity Hot Loader</h1>
        <div>
          <Counter {...web3Context} JSON={counterJSON} instance={counterInstance} deployedNetwork={deployedNetwork} />
        </div>
      </div>
    </div>
  );
}

export default App;

```

### Add a Counter component to the dapp

The Counter component displays the current value of the counter and has a button to increase the value of the counter.

In the `client/src` directory create a `components` directory. In the `components` directory create a `Counter.js` file with the following code:

```auto
// client/src/components/Counter.js
import React, { useState, useEffect, useCallback } from 'react';

export default function Counter(props) {
  const { instance, accounts, lib } = props;
  const { _address } = instance || {};

  const [count, setCount] = useState(0);

  const getCount = useCallback(async () => {
    if (instance) {
      // Get the value from the contract to prove it worked.
      const response = await instance.methods.value().call();
      // Update state with the result.
      setCount(response);
    }
  }, [instance]);

  useEffect(() => {
    getCount();
  }, [getCount, instance]);

  const [sending, setSending] = useState(false);

  const increase = async number => {
    try {
      if (!sending) {
        setSending(true);

        await instance.methods.increase().send({ from: accounts[0] });

        getCount();

        setSending(false);
      }
    } catch (e) {
      setSending(false);
      console.log(e);
    }
  };

  return (
    <div>
      <h3>Counter Instance</h3>
      {lib && instance && (
        <React.Fragment>
          <div>
            <div>Instance address: {_address}</div>
          </div>
          <div>
            <div>Counter Value: {count}</div>
          </div>
            <React.Fragment>
              <div>
                <h4>Counter Actions</h4>
              </div>
              <div>
                <button onClick={() => increase()} size="small">
                  {sending ? <span>Sending ...</span> : <span> Increase Counter</span>}
                </button>
              </div>
            </React.Fragment>
        </React.Fragment>
      )}
    </div>
  );
}

```

## Run the dapp

We can now fire up our application running `npm start` from within the `client` directory.

```auto
$ npm start

```

Our dapp that we created will display in the browser `https://localhost:3000`

 ![OpenZeppelin Solidity Hot Loader](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/6/6ed3ee0e8ebb75b4e3efd9416ada0b115f4a5c94.png)

With our dapp loaded in the browser, we can increase the value of the counter.

### Solidity Hot Loader in action

We can now make changes to our contract and this will be reflected in the dapp using the Solidity Hot Loader.

In `Counter.sol` change the value that the counter is increased by from 1 to 3.

```auto
  function increase() public {
    value = value + 3;
  }

```

Save the change in `Counter.sol` and Solidity Hot Loader will compile the contract, upgrade it and refresh the dapp.

Press the `Increase Counter` button and once the transaction in confirmed the counter will have increased by 3.

* * *

Let’s take a moment and go over the Solidity Hot Loader development cycle again:

1. Make a change to your smart contract `.sol` file and save it
2. Wait a bit
3. Done

We didn’t have to manually do any of the following:

- Compile your contract
- Deploy your contract
- Restore the state
- Restart dapp to get new contract

This is a big improvement to the developer experience, and allows us to develop faster using the Solidity Hot Loader.

* * *

We can keep developing our smart contract and Solidity Hot Loader will update our dapp.

Please note, that Solidity Hot Loader under the covers uses OpenZeppelin Upgrades, so is limited to contracts that can be upgradeable, e.g. no constructors: [https://docs.openzeppelin.com/upgrades/2.8/writing-upgradeable](https://docs.openzeppelin.com/upgrades/2.8/writing-upgradeable)

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [June 15, 2020, 8:57am UTC](https://forum.openzeppelin.com/t/building-an-openzeppelin-dapp-with-solidity-hot-loader/1843/2 "2020-06-15T08:57:54Z")

</div>

Split this topic on June 15, 2020, 8:57am UTC

A post was split to a new topic: [Solidity Hot Loader with Vue](https://forum.openzeppelin.com/t/solidity-hot-loader-with-vue/3104)

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [August 20, 2020, 9:02am UTC](https://forum.openzeppelin.com/t/building-an-openzeppelin-dapp-with-solidity-hot-loader/1843/3 "2020-08-20T09:02:16Z")

</div>

Split this topic on August 20, 2020, 9:02am UTC

A post was split to a new topic: [The create command is deprecated: Building an OpenZeppelin dapp with Solidity Hot Loader](https://forum.openzeppelin.com/t/the-create-command-is-deprecated-building-an-openzeppelin-dapp-with-solidity-hot-loader/3598)
