Cryptonomic NYC Hackathon part 2

The idea

It was the first time I’d ever taken part in a hackathon. I hadn’t been to any of these events before because I was very skeptical about them. I thought: how can we make anything useful in only two days? Well, it turns out that small, but handy tools can be created, even without sacrificing code quality. The key is to choose the right project; not too big or too complicated so you can complete it within a weekend. In our case, it was a Micheline Michelson translator that I’m going to tell you more about in this article.

The hackathon

Our hackathon took place on the first weekend of August (03-04.08). Cryptonomic is a startup which provides tools and smart contracts for decentralized and consortium applications. We had to use the Cryptonomic technology stack, tools such as ConceilJS (https://github.com/Cryptonomic/ConseilJS) during the hackathon. We decided to create a Google-like translator between Michelson and Micheline; two formats of source files used in Tezos software development. 

What are Tezos and Michelson?

According to the Tezos website:

“Tezos is a new decentralized blockchain that governs itself by establishing a true digital commonwealth.”

“Tezos addresses key barriers facing blockchain adoption to date: smart contract safety, long-term upgradability, and open participation”

Michelson is a domain-specific language that we use to write smart contracts on the Tezos blockchain. Unlike Solidity or Viper which must be compiled to EVM (Ethereum Virtual Machine) byte code to be executed on EVM, Michelson code itself gets to run in the Tezos VM.

Micheline vs. Michelson

First of all, Michelson is the specification and Micheline is the concrete language syntax of Michelson encoded in JSON. Before deployment to Tezos VM, Michelson is transformed into Micheline. 

For example, here is the same program in Michelson and Micheline representation:

Micheline

parameter int;
storage int;
code {CAR;                      # Get the parameter
      PUSH int 1;               # We're adding 1, so we need to put 1 on the stack
      ADD;                      # Add the two numbers
      NIL operation;            # We put an empty list of operations on the stack
      PAIR}

Michelson

[
    {
      "prim": "parameter",
      "args": [
        {
          "prim": "int"
        }
      ]
    },
    {
      "prim": "storage",
      "args": [
        {
          "prim": "int"
        }
      ]
    },
    {
      "prim": "code",
      "args": [
        [
          {
            "prim": "CAR"
          },
          {
            "prim": "PUSH",
            "args": [
              {
                "prim": "int"
              },
              {
                "int": "1"
              }
            ]
          },
          {
            "prim": "ADD"
          },
          {
            "prim": "NIL",
            "args": [
              {
                "prim": "operation"
              }
            ]
          },
          {
            "prim": "PAIR"
          }
        ]
      ]
    }
]

As you can see, there is a clear correspondence between Michelson and Micheline representation. Despite this, many people still find it challenging to understand the difference between Michelson and Micheline. That’s why our team decided to create this translator. Above all, we hope it is going to help other developers to learn smart contracts development in Tezos.

The Technology stack

To create our Micheline Michelson translator, we agreed to use Scala and Akka http for the backend side. At the frontend side, we used React, Redux, and Typescript.

The Coding

A conversion between the two formats is already a part of Cryptonomic tools. So, we needed to extract it from the base source code. After that, we decided to create a separate module for conversion which, we could then import into other projects, so as not to duplicate code.

A Micheline to Michelson translation has already been implemented in Scala using Circe, so it was quite easy to integrate it into our Scala-based project. However, the Michelson to Micheline conversion code is JavaScript. We tried to come up with our own Scala parser for Michelson. Unfortunately, it was too time-consuming, and we finally decided to use a parser from ConceilJS. We also chose Node.js for running the JavaScript code.

Michelin Michelson Translator

The Solution

In short, our solution consists of one frontend and two backend modules. 

Frontend module:

https://github.com/ScalaConsultants/Tezos-Micheline-Michelson-Translator-Frontend

Translation module:

https://github.com/ScalaConsultants/Tezos-FullStack-Console-Translation-Module

Console backend:

https://github.com/ScalaConsultants/Tezos-FullStack-Console

(There’s more detailed information about the modules in the Readme files, so there’s no point in duplicating the text)

Also, our team selected Heroku as the deployment platform.

Final application

You can try out our solution here: http://smart-contracts-micheline-michelson-translator-for-tezos.scalac.io/

On the left side, you paste the Micheline code and click translate to see the result. That simple!

The experience

In conclusion, it turns out that over only two days, it’s possible to create a small yet beneficial application. It was also an excellent opportunity to learn about some Tezos development tools. 

The Micheline Michelson translator was one of two projects that by Scalac. Check out the Frontend data visualization app that the other team made. 

Async/await is a brand new way of handling asynchronous calls in JavaScript. If you don’t know how it works, in this article I will be providing some examples to help you get started. Read more

Introduction

One of hardest parts in developing and maintaining React/Redux application is handling asynchronous actions: timeouts, requests/response handling, interaction with third-party stores, different callbacks and so on without сomplicating logic into actions-creators and reducers.

In this post, I’m going a real project to show you how to move all side-effects ( and not only ) away from action-creators. All of this in a way that makes them as clean as possible with Redux-Saga. Read more

JWT Authentication in a React-Redux app

Are you currently working on JWT authentication in React and Redux App? Don’t you know how to handle it? In this article we will cover a sign in process step by step.

These days, authentication is very important and commonly used aspect in modern web. It is for identifying users and to provide access rights for specific content. When logging, users either enter their usernames and passwords or use 3rd party providers for authentication purposes. In this entry I’ll present how to handle that process from the front-end side with an example using JSON Web Token.

JSON Web Token (JWT) is an open standard that defines a compact and self-contained way to transmit information securely between parties using a JSON object. More about JWT

Tools that we’ll use: react, redux, redux-form, react-router, redux-thunk, axios.

Prelude

After receiving user login data (e.g.: email and password), the server checks if data is valid. If it is, server returns a specific json response containing the token to allow user identification.
JSON Web Tokens consist of three parts, which are:

  • Header – The header usually consists of: the type of the token (JWT) and the hashing algorithm such as HMAC SHA256 or RSA.
  • Payload – contains the claims like RESERVED, PUBLIC and PRIVATE. RESERVED – are predefined claims which are not mandatory but recommended, like iss (issuer), exp (expiration time), sub (subject), aud (audience). PUBLIC – can be defined at will by those using JWTs. PRIVATE – are the custom claims, dedicated for sharing information. The payload is then Base64Url encoded to form the second part of the JSON Web Token.
  • Signature – consists of the encoded header, the encoded payload, a secret and the algorithm specified in the header.

When the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. Header content should looks like the following: “Authorization: Bearer <token>”.

The server’s protected routes will check for a valid JWT in the Authorization header, and if it’s valid, the user will be allowed to access protected resources. For security reasons, after logout, the server should pass the token to the blacklist to revoke them.

If the server receives the request without the token, it should send the response of 401 code – unauthorized. In other cases, e.g. failed validation, the server returns 400 code – bad request.

Thanks to HTTP codes and messages, client side application can recognize failed and successful requests and serve responses like tokens or errors.

To begin authorization process, the application has to send request to specific server URL that provides authentication. For example: http://www.sample-website.com/signin

In our case the request must contains two parameters in its body: email and password.

After a successful sign-in, the server returns a specific user token which should be stored in browser memory, for example in the localStorage or sessionStorage, in order to authenticate the user session.

Alert: This post won’t cover the basics of react and redux. If you want learn more about state management in react/redux apps I recommend you to read: Managing React state with Redux.

Configuration:

To start with our application, first let’s begin by initializing React, Redux, and React Router.

Root index.js looks like this:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import Navbar from './components/universal/navbar';
import Homepage from './components/homepage';
import Signin from './components/auth/signin';
import Signup from './components/auth/signup';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware()(createStore);
const store = createStoreWithMiddleware(reducers);

ReactDOM.render(
  <Provider store={store}>
    <Router>
      <div>
        <Navbar />
        <Route exact path="/" component={Homepage} />
        <Route path="/signin" component={Signin} />
        <Route path="/secret" component={SecretPage} />
      </div>
    </Router>
  </Provider>,
  document.querySelector('#root')
);

The code shows a typical initialization of react for our web application: reduxis used to help managing state, react-redux delivers the provider to establish a connection between the state and our application, and, lastly, react-router-dom, to help defining dynamic routing.

Provider requires passing store to be able to use connect() calls. We define createStoreWithMiddleware to be able to use middleware in the future and to pass main reducer file which will allow to propagation of state through the whole application scope.

There also was added react-router-dom, which allows to define dynamic routing inside web application. Components that were added to router as routes are: Homepage, Signin and the SecretPage (which ultimately is going to be available only for signed in users).

Sign In component:

It’s time to prepare component of Sign In form. For this purpose we’ll use the handy redux-form package, which allows to manage form state in Redux. Below you can find a very basic implementation of redux-form. The submit function takes values passed into form (email and password) and displays them in the console on click event (for testing purposes).

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class Signin extends Component {
  submit = (values) => {
    console.log(values);
  }

  render() {
    const { handleSubmit } = this.props;
    return (
      <div className="form">
        <div className="container">
          <h2>Sign In</h2>
          <form onSubmit={ handleSubmit(this.submit) }>
            <Field name="email"
                  component="input"
                  type="text"
                  placeholder="Email" 
            />
            <Field name="password" 
                  component="input"
                  type="password" 
                  placeholder="Password" 
            />
            <button type="submit" className="blue">Sign In</button>
          </form>
        </div>
      </div>
    );
  }
}

export default reduxForm({
  form: 'signin'
})(Signin);

To make the form component communicate with the store, it has to be wrapped with reduxForm(). ReduxForm will provide the props for the state and the function to handle the submission process. Also, provided by ReduxForm, thecomponent, helps connecting each input to the store. Redux store has to know how to handle actions coming from the form components. So make it possible we need to pass the formReducer to the store.

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
form: formReducer
});

export default rootReducer;

Authentication:

It’s the high time to start working on authentication. So now, we are going to:

  • make a connection with the server,
  • pass email and password into the request body,
  • receive token and save inside browser’s memory – localStorage,
  • redirect user to specific route – Secret,
  • handle errors.

To make all of those things possible, we are going to use Action Creators.

Actions are payloads of information that send data from the application to store. Action Creators are exactly what the name suggests, they are functions that create actions. They always return an object with type and payload – type being the action name, and payload the data they carry. In fact we are going to make a few additional steps, listed above. That’s why we need to use a middleware like redux-thunk, which allows to write asynchronous code.

“The Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.”

Installation of redux-thunk is very simple. First we need to install its package, import it in our root index.js and add its instance to applyMiddleware.

import reduxThunk from 'redux-thunk';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);

After redux-thunk is added, we can go forward and create our Action Creator:

import axios from 'axios';

export const AUTHENTICATED = 'authenticated_user';
export const UNAUTHENTICATED = 'unauthenticated_user';
export const AUTHENTICATION_ERROR = 'authentication_error';

const URL = 'http://www.sample-website.com';

export function signInAction({ email, password }, history) {
  return async (dispatch) => {
    try {
      const res = await axios.post(`${URL}/signin`, { email, password });

      dispatch({ type: AUTHENTICATED });
      localStorage.setItem('user', res.data.token);
      history.push('/secret');
    } catch(error) {
      dispatch({
        type: AUTHENTICATION_ERROR,
        payload: 'Invalid email or password'
      });
    }
  };
}

We have added to our application the HTTP client Axios, it allows for an easy way to send asynchronous HTTP requests to REST endpoints. Axios supports the Promise API, allows to cancel or intercept request, response and automatically transforms data to JSON. Thanks to this, our communication with the server will be much faster and easier. We also set some types that we will need to dispatch to the reducer.

Next we create an Action Creator called signInAction where we pass in: email, password and history from the Signin component. Email and password are required in the request body for authentication purposes and the history object will help us to redirect user if the sign in process passes successful. Then, we define async/await function with the dispatch method. In the try block, we define const res with axios method POST with server URL and values from Signin component (email/password).

We also added await operator before post method to execute other functions only if the request was done successfully, but, if not, the error is handled in the catch() block. Dispatches an actions of type AUTHENTICATED saves token in localStorage. Then, history.push() redirects the user to the specific route URL.

If user is authenticated, state should returns true or false. In case of an error, state also should contain error message. So, we need to create auth_reducer.js file that handles different cases based on dispatched action types.

import { AUTHENTICATED, UNAUTHENTICATED, AUTHENTICATION_ERROR } from '../actions';

export default function(state={}, action) {
  switch(action.type) {
    case AUTHENTICATED:
      return { ...state, authenticated: true };
    case UNAUTHENTICATED:
      return { ...state, authenticated: false };
    case AUTHENTICATION_ERROR:
      return { ...state, error: action.payload };
  }
  return state;
}

Depending on specific case AUTHENTICATED, UNAUTHENTICATED or AUTHENTICATION_ERROR, the reducer returns a new state with the appropriate boolean value or error message.

Now we have to pass our new auth reducer to the main reducer file as follows:

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
import authReducer from './auth_reducer';

const rootReducer = combineReducers({
  form: formReducer,
  auth: authReducer
});

export default rootReducer;

On this step we have to back to Sign In component and make some changes.

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { signInAction } from '../../actions';
import { connect } from 'react-redux';

class Signin extends Component {
  submit = (values) => {
    this.props.signInAction(values, this.props.history);
  }

  errorMessage() {
    if (this.props.errorMessage) {
      return (
        <div className="info-red">
          {this.props.errorMessage}
        </div>
      );
    }
  }

  render() {
    const { handleSubmit } = this.props;
    return (
      <div className="form">
        <div className="container">
          <h2>Sign In</h2>
          <form onSubmit={ handleSubmit(this.submit) }>
            <Field name="email"
                   component="input"
                   type="text"
                   placeholder="Email" 
            />
            <Field name="password" 
                   component="input"
                   type="password"
                   placeholder="Password" 
            />
            <button type="submit" className="blue">Sign In</button>
          </form>
          {this.errorMessage()}
        </div>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { errorMessage: state.auth.error };
}


const reduxFormSignin = reduxForm({
  form: 'signin'
})(Signin);

export default connect(mapStateToProps, {signInAction})(reduxFormSignin);

We have to import signInAction action that we prepared earlier and also connect() method from react-redux. This method will connect our reduxFormSignin and Signin component with actions creators. And now our Actions Creators (signInAction()) are available as a props in our component.

We also have to define mapStateToProps function which takes application state and pass it into component as a props. In our case, we need state.auth.error and use it as this.props.errorMessage, which returns an error in case of authentication failure.

We pass our action creator – signInAction to the submit function with the values from the form and with props.history (to be able to redirect user in action). We also defined errorMessageDisplay function that displays errors.

Sign In form should also have a client-side validation. Very fine example you can find in redux-form documentation

Now we can use our authenticated state value, for example to render proper menu items. If user is logged we render Signout and Secret page links, in other case we want Sign In and Sign Up. The code below shows how to achieve that.

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';

class Navbar extends Component {
  navbarLinks() {
    if (this.props.authenticated) {
      return [
        <li key="secret"><Link to="/secret">Secret</Link></li>,
        <li key="signout"><Link to="/signout">Sign out</Link></li>
      ];
    }
    return [
      <li key="signin"><Link to="/signin">Sign in</Link></li>,
      <li key="signup"><Link to="/signup">Sign up</Link></li>
    ];
  }

  render() {
    return (
      <nav className="navbar">
        <div className="container">
          <Link to="/"><span className="brand">Auth-app</span></Link>
          <ul>
            {this.navbarLinks()}
          </ul>
        </div>
      </nav>
    );
  }
}

function mapStateToProps(state) {
  return {
    authenticated: state.auth.authenticated
  };
}

export default connect(mapStateToProps)(Navbar);

Auto user authentication:

If the token is saved in localStorage, our application should automatically change the auth state to authenticated before rendering. But currently there’s no code for that. That’s why when we refresh the page, state of user auth comes back to false. To fix this, we have to add dispatch method with type: AUTHENTICATED if there is a proper token in user browser. In root index.js file, we need to make some fixes as follows:

import { AUTHENTICATED } from './actions';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = createStoreWithMiddleware(reducers);

const user = localStorage.getItem('user');

if(user) {
  store.dispatch({ type: AUTHENTICATED });
}

ReactDOM.render(
  <Provider store={store}>
    <Router>
      <div>
        <Navbar />
        <Route exact path="/" component={Homepage} />
        <Route path="/signin" component={noRequireAuth(Signin)} />
        <Route path="/signup" component={noRequireAuth(Signup)} />
        <Route path="/signout" component={Signout} />
        <Route path="/secret" component={requireAuth(SecretPage)} />
      </div>
    </Router>
  </Provider>,
  document.querySelector('#root')
);

We have to check if there is an ‘user’ token in localStorage. In case there is, we need to dispatch an action of type AUTHENTICATED into reducers. Thanks to this, new state will return value of authenticated: true.

Sign out:

To add Sign out logic, we just have to create a SignOut component which would trigger specific action. Sample action creator for signout may looks like this:

export function signOutAction() {
  localStorage.clear();
  return {
    type: UNAUTHENTICATED
  };
}

Protected routes:

Currently the user, after successful sign in, is redirected into ‘/secret’ route. In fact this route isn’t protected in anyway. Even not authorized person can go there and see the content. This is behaviour that we want to avoid, because of security reasons. That’s why we want to secure our route with Higher-Order Components (HOC). HOC is able to wrap specific component and extend its functionality.

In our case, have to check if the user is authenticated. If the user is not, higher order component redirects to another route for example into Signin. To make it happen we have to create new component, called for example require_auth.js and add specific the logic like:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

export default function (ComposedComponent) {
  class Authentication extends Component {
    componentWillMount() {
      if (!this.props.authenticated) {
        this.props.history.push('/signin');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.props.history.push('/signin');
      }
    }

    PropTypes = {
      router: PropTypes.object,
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}

When the component is mounting or updating (because of changes to props or state) there is an if statement that check if the user is authenticated. If the user is not, HOC will make a redirection into ‘/signin’ URL. In any other case, nothing happens and the user can go into current component.

Similarly, we can also ‘protect’ routes which should not be available for authenticated user, like Sign In, Sign Up etc. The HOC for it has a very similar logic

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

export default function (ComposedComponent) {
  class NotAuthentication extends Component {
    componentWillMount() {
      if (this.props.authenticated) {
        this.props.history.push('/secret');
      }
    }

    componentWillUpdate(nextProps) {
      if (nextProps.authenticated) {
        this.props.history.push('/secret');
      }
    }

    PropTypes = {
      router: PropTypes.object,
    }

    render() {
      return <ComposedComponent {...this.props} />;
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(NotAuthentication);
}

An authenticated user while visiting urls like ‘/signin’ or ‘/signup’ is automatically redirected to specific URL, for example ‘/secret’.

To secure specific routes, we just have to wrap those with our Higher Order Components as below:

import requireAuth from './components/hoc/require_auth';
import noRequireAuth from './components/hoc/no_require_auth';
<Route exact path="/" component={Homepage} />
<Route path="/signin" component={noRequireAuth(Signin)} />
<Route path="/signup" component={noRequireAuth(Signup)} />
<Route path="/signout" component={requireAuth(Signout)} />
<Route path="/secret" component={requireAuth(SecretPage)} />

And that’s it. We have made a react-redux app that uses JWT Authentication process.

I attach some links below to repositories which helped me to implement this authorization and to understand a whole process. I hope that this article will help you understand the unclear parts of the authentication process from a front-end point of view.

Other useful links: