Managing Ethereum Smart Contract Events with Drizzle
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.
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:
- Truffle Quickstart
- Getting Started with Drizzle and React
- How to use MetaMask
- Tutorial: Intro to React
- Redux Basic Tutorial
- Redux Saga
- 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.
- MetaMask should NOT be connected to the Mainnet! Do not run this if you’re connected to the Mainnet!
- Instead, configure MetaMask to connect to
Localhost 8545
. - If you have Privacy Mode enabled in MetaMask, make sure to give MetaMask permission to connect.
- Copy an account
Private Key
displayed intruffle 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.
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.