Managing Ethereum Smart Contract Events with Drizzle

Cruz Molina
Truffle Suite
Published in
4 min readJun 12, 2019

Co-authored by Amal Sudama & Cruz Molina

As dapps grow in complexity, coordination between dapps and off-chain services becomes crucial. Enter Drizzle, a tool designed for smooth synchronization between a smart contract state and user interface.

Using just a tiny bit of code, Drizzle opens up a powerful mechanism to enable such coordination. Imagine your dapp needs to send a message whenever a contract event is generated. In this tutorial, we’ll go over how to use Drizzle to manage smart contract events.

The finished dapp!

Complete example available at the following repo.

Prerequisites: You should be familiar with Truffle, Drizzle, MetaMask, React and Redux. If you need an introduction please consult the following resources:

  1. Truffle Quickstart
  2. Getting Started with Drizzle and React
  3. How to use MetaMask
  4. Tutorial: Intro to React
  5. Redux Basic Tutorial
  6. Redux Saga
  7. Redux Middleware

Unbox Drizzle

We will use truffle unbox to bootstrap a project and then wire up a contract event to a display component.

// In the project directory...
$ truffle unbox drizzle

In a separate terminal window, start a local blockchain using truffle develop.

// Separate terminal window...
$ truffle develop

In the Truffle Develop console, we will compile and migrate our smart contracts.

$ compile... compiler output ...$ migrate... migration output ...

Now that our test chain is up and our smart contracts have been deployed, let’s add a notification to the UI.

Listen for Contract Events

We want to listen for the SimpleStorage contract's StorageSet event and show a notification once it fires.

We’ll use react-toastify to alert the user whenever a SimpleStorage contract event is emitted.

The front end code is located under the app folder. Lets add the notification library react-toastify to simulate an external interaction.

// Back in the project directory terminal window...
$ cd app
$ npm install react-toastify

For the sake of simplicity, we will write our code in one file.

$ mkdir ./src/middleware
$ touch ./src/middleware/index.js

Import EventActions and generateStore from Drizzle as well as toast from react-toastify, and drizzleOptions.

// ./app/middleware/index.js
import { generateStore, EventActions } from 'drizzle'
import drizzleOptions from '../drizzleOptions'
import { toast } from 'react-toastify'

The action EventActions.EVENT_FIRED is emitted whenever a contract event is detected in a block. We will invoke toast.success()to display a notification when EventActions.EVENT_FIRED is emitted.

const contractEventNotifier = store => next => action => {
if (action.type === EventActions.EVENT_FIRED) {
const contract = action.name
const contractEvent = action.event.event
const message = action.event.returnValues._message
const display = `${contract}(${contractEvent}): ${message}`

toast.success(display, { position: toast.POSITION.TOP_RIGHT })
}
return next(action)
}

Next we have to register this middleware with Drizzle. generateStore will return a Redux store you can use anywhere you can use a store. We will export it to DrizzleProvider.

const appMiddlewares = [ contractEventNotifier ]

export default generateStore({
drizzleOptions,
appMiddlewares,
disableReduxDevTools: false // enable ReduxDevTools!
})

Connect the Store

Pass the store as a prop to DrizzleProvider.

// App.js
...
import store from './middleware'
...
<DrizzleProvider store={store} options={drizzleOptions}>
...

Hook up the Display

Modify MyComponent.js to import ReactToastify.css and configure ToastContainer.

...
import { ToastContainer } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
...

export default ({ accounts }) => (
<div className="App">
<ToastContainer />
...
</div>

A Quick Test

  • Things often go south during development so it’s good practice to have a checklist to review.
  1. MetaMask should NOT be connected to the Mainnet! Do not run this if you’re connected to the Mainnet!
  2. Instead, configure MetaMask to connect toLocalhost 8545.
  3. If you have Privacy Mode enabled in MetaMask, make sure to give MetaMask permission to connect.
  4. Copy an account Private Key displayed in truffle develop and import it into MetaMask via Import Account. This imports an account to MetaMask preloaded with ETH funds.
  • Start the app.
$ npm run start
  • Change SimpleStorage’s Stored Value
  • You’ll be rewarded with a toast notification when the transaction is completed.
A successful Toast!

The dapp is now a consumer of Drizzle’s EVENT_FIRED action item and can coordinate with off-chain services!

For a deeper dive into Drizzle, join us for TruffleCon 2019 August 2–4 at Microsoft’s campus in Redmond, WA! Get Tickets

Originally published at https://www.trufflesuite.com.

--

--