I have been looking for EOS demux implementation using PostgreSQL but found none. So I thought of writing this short tutorial explaining how we can implement EOS demux using PostgreSQL. Those who don’t know about EOS Demux please have a look at the article explaining the same in a very intuitive way. https://github.com/EOSIO/demux-js.
A short explanation of EOS Demux: Demux architecture allows application developers to use traditional Mongo or Postgres SQL databases in a way that means the data stored in them is still verifiable by the blockchain. This enables the best of both worlds: the flexibility and speed of traditional databases, coupled with the trust and immutable properties of a blockchain. The overall flow of an application looks as follows:
To use PostgreSQL as a data store we need to use massive.js. So go ahead and install massive.js using the following command
> npm i massive --save
are required to make blog entry verifiable and secure. Following is the contract.
#include <eosiolib/eosio.hpp> #include <eosiolib/multi_index.hpp> #include <eosiolib/types.hpp> #include <eosiolib/print.hpp> #include <eosiolib/system.h> //using namespace eosio; class blog_contract : public eosio::contract{ public: blog_contract(account_name self) : eosio::contract(self), bloges(self, self){} /// @abi action void create(account_name author, uint64_t id, std::string email, const std::string& data){ require_auth(author); blogs.emplace(author, [&](auto& new_blog) { new_blog.id = id; new_blog.author = author; }); } //.. destroy, show and update actions .. private : /// @abi table blog i64 struct blog{ uint64_t id; uint64_t author; uint64_t primary_key() const { return id; } EOSLIB_SERIALIZE(blog,(id)(author)); }; typedef eosio::multi_index<N(blog), blog> blog_table; blog_table blogs; }; EOSIO_ABI( blog_contract, (create)(destroy)(show)(update) )
const massive = require('massive'); let db; massive({ host: host, port: port, database: database, user: user, password: password }).then(instance => { db = instance; return Promise.resolve(db); }).catch(e => { console.log(e) console.log('error while getting massive instance') });
function createBlog(db, payload, blockInfo, context){ db.blog_data.insert({ id : payload.data.id, author : payload.data.author, data : payload.data.data, //Storing blog data email : payload.data.email }).then(new_blog => { console.log('blog created') }).catch(err => { console.log('error while inserting data') }) } //Register blockchain Actions to which this update will be called. const updaters = [{ actionType: "blogger.p::create", updater: createProfile} ] module.exports = updaters
function logUpdate(state, payload, blockInfo, context) { console.info(“blog created\n") } const effects = [ { actionType: "blogger.p::create", effect: logUpdate, } ] module.exports = effects
const { readers: { eos: { NodeosActionReader } }, handlers :{ postgres : { MassiveActionHandler } }, watchers: { BaseActionWatcher } } = require('demux-js') const actionHandler = new MassiveActionHandler( updaters, effects, db ) const actionReader = new NodeosActionReader( httpEndpoint, 0, // Start at most recent blocks ) const actionWatcher = new BaseActionWatcher( actionReader, actionHandler, 500, ) actionWatcher.watch()
CREATE TABLE _index_state ( id serial PRIMARY KEY, block_number integer NOT NULL, block_hash text NOT NULL, is_replay boolean NOT NULL );