DEV Community

Robert Chen
Robert Chen

Posted on • Originally published at Medium on

3 1

How To Build Your First Blockchain App on Blockstack

A tutorial to build your first app on the decentralized web

Blockstack is a network for decentralized applications. This platform leverages a serverless architecture, which helps remove critical points of vulnerability. By eliminating these weak points, which have frequently fallen victim to hacks, Blockstack makes user data more secure.

Prerequisites: Knowledge of React.js will be required for this tutorial.

Blockchain tech can be complicated, but getting started doesn’t have to be. Blockstack’s 3rd party sign in/sign up/authentication makes it easy to get started developing apps and publishing it to a decentralized App store like App.co

codecoderevolution

I was able to publish this on App.co in less than a week

After integrating Blockstack, you have the option to either send the unique username that a user creates from Blockstack to your own API and build the user object that way, or use Gaia Storage, Blockstack’s decentralized backend provider. You can also opt to have a combination of both, where private user information like phone numbers and addresses are encrypted and stored in Gaia Storage but public information like comments or posts are stored in a public API.

This blog post is meant to simplify and abstract as much as possible. If you would like deep dive video tutorials, check out Tech Rally on YouTube (this is where I learned about Blockstack).

For now, we’ll cover getting Blockstack Sign In/Sign Out authentication set up. Let’s get started!

1) Install Blockstack Browser

2) Create your Blockstack ID (be sure to save your Secret Recovery Key somewhere safe)
In your terminal:

npm init react-app blockstack-tutorial
cd blockstack-tutorial
npm install --save blockstack@19.0.0-alpha.2
npm install react-app-rewired --save-dev
mkdir src/utils
touch src/utils/constants.js
open src/utils/constants.js
Enter fullscreen mode Exit fullscreen mode

If npm install gives you a problem, try yarn add:

yarn add blockstack@19.0.0-alpha.2
yarn add react-app-rewired --save-dev
Enter fullscreen mode Exit fullscreen mode

4) constants.js:

import { AppConfig } from 'blockstack'
export const appConfig = new AppConfig(['store_write', 'publish_data'])
Enter fullscreen mode Exit fullscreen mode

5) In your terminal:

touch config-overrides.js
open config-overrides.js
Enter fullscreen mode Exit fullscreen mode

6) config-overrides.js:

module.exports = {
webpack: function (config, env) {
return config;
},
jest: function (config) {
return config;
},
// configFunction is the original react-scripts function that creates the
// Webpack Dev Server config based on the settings for proxy/allowedHost.
// react-scripts injects this into your function (so you can use it to
// create the standard config to start from), and needs to receive back a
// function that takes the same arguments as the original react-scripts
// function so that it can be used as a replacement for the original one.
devServer: function (configFunction) {
return function(proxy, allowedHost) {
const config = configFunction(proxy, allowedHost);
// Edit config here - example: set your own certificates.
//
// const fs = require('fs');
// config.https = {
// key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'),
// cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'),
// ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'),
// passphrase: process.env.REACT_HTTPS_PASS
// };
config.headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE",
"Access-Control-Allow-Headers": "Content-Type"
}
return config;
};
}
}

7) In your terminal:

open package.json
Enter fullscreen mode Exit fullscreen mode

8) package.json:

{
"name": "app-name",
"version": "0.1.0",
"private": true,
"dependencies": {
"blockstack": "19.0.0-alpha.2",
"react": "^16.8.6",
"react-app-rewired": "^2.1.3",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-app-rewired eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
view raw package.json hosted with ❤ by GitHub

9) In your terminal:

open src/App.js
Enter fullscreen mode Exit fullscreen mode

10) App.js:

import React, { Component } from "react";
import { appConfig } from "./utils/constants";
import { UserSession } from "blockstack";
class App extends Component {
state = {
userSession: new UserSession({ appConfig })
};
componentDidMount = async () => {
const { userSession } = this.state;
if (!userSession.isUserSignedIn() && userSession.isSignInPending()) {
const userData = await userSession.handlePendingSignIn();
if (!userData.username) {
throw new Error("This app requires a username");
}
window.location = "/";
}
};
handleSignIn = () => {
const { userSession } = this.state;
userSession.redirectToSignIn();
};
handleSignOut = () => {
const { userSession } = this.state;
userSession.signUserOut();
window.location = "/";
};
render() {
const { userSession } = this.state;
return (
<div className="App">
{userSession.isUserSignedIn() ? (
<button className="button" onClick={this.handleSignOut}>
<strong>Sign Out</strong>
</button>
) : (
<button className="button" onClick={this.handleSignIn}>
<strong>Sign In</strong>
</button>
)}
</div>
);
}
}
export default App;
view raw app.js hosted with ❤ by GitHub

11) In your terminal:

open src/index.js
Enter fullscreen mode Exit fullscreen mode

12) index.js:

import React from "react";
import ReactDOM from "react-dom";
import "./App.css";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(<App />, document.getElementById("root"));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
view raw index.js hosted with ❤ by GitHub

13) In your terminal:

open src/App.css
Enter fullscreen mode Exit fullscreen mode

14) App.css:

.App {
display: flex;
text-align: center;
height: 100vh;
}
.button {
max-width: 8em;
max-height: 4em;
font-size: 1em;
margin: auto;
display: inline-block;
padding: 1em;
color: #000;
transition: color 0.3s linear;
border-color: #000;
border-width: 2px;
}
.button:hover {
color: white;
border: 1px solid white;
background-color: black;
}
view raw app.css hosted with ❤ by GitHub

15) In your terminal:

npm start
Enter fullscreen mode Exit fullscreen mode

or

yarn start
Enter fullscreen mode Exit fullscreen mode

That’s it! Simple, but powerful —you are now connected to Blockstack.

In part two of this series, I’ll show you How to Connect Blockstack to your Backend API


Bring your friends and come learn JavaScript in a fun never before seen way! waddlegame.com

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay