Tutorial • Interactive

React & IOTA - From zero to a transaction

Vision

Send a IOTA transaction without any knowledge about React or IOTA



Contributors

React & IOTA

From zero to a transaction


This tutorial is a guide, which leads you through the basics concepts of React and IOTA's javascript Library. After this tutorial, you will have: 

  1. Basic understanding of React
  2. Basic understanding of the iota.lib.js
  3. Basic understanding of an IOTA transaction.

  4. Basic understanding of Proof of Work

You also get many links, where you can read further information. 

The complete source code is available on GitHub but just look to it, if you struggling with a problem.

https://github.com/huhn511/hello_iota

Setup React

First, we need to set up our project. The fasted way to do it is with facebook’s create-react-app helper: GitHub Repository

$ npx create-react-app hello_iota
$ cd hello_iota
$ npm start


Then open http://localhost:3000/ to see your app.


Create a button

Open the directory with your favorite code editor. I use the open source editor Atom. https://atom.io/

This opens the directory in Atom from your console:  

$ atom .


Go to the app.js file in the /src directory.

Write a new method in the App Component called “send” which first just print a console log in the browser console. 

send() {
console.log("Send!");
}


Now we need to return a button in the React render method on which we can click. Remove the paragraph and add a button with a click handler, which calls the send function. 

<button onClick={this.send}>Send Transaction</button>


And we have a working button! We can find the output in the Browser console.


Watch the code here.


Create a button component

The next step is to outsource the button to its own component. That’s easy and clean up our App.js file.

Create a new directory, called components and a new React component file called SendButton.js in there.

Copy the function in the new file, and render just the button like this:

import React, { Component } from 'react';
class SendButton extends Component {
send() {
console.log("Send!");
}
render() {
return (
<button onClick={this.send}>Send Transaction</button>
);
}
}
export default SendButton;


 In the App.js file we need to include the button on the top:

import SendButton from './components/SendButton'


Then we just need to replace the button with the SendButton component in the render function. 

render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<SendButton />
</div>
);
}


And, back to the browser and see the console log! Our component works works!


Watch the code here.


Setup the IOTA javascript library

Now we want to say hello to IOTA. The best way to do this is with a hello IOTA transaction. Let’s do it!

First, we need to install the iota javascript library with the node package manager (npm). https://github.com/iotaledger/iota.lib.js/

$ npm install iota.lib.js


We import this in our App.js file on the top.

import IOTA from 'iota.lib.js'


Now, we create a constructor and set up the IOTA library with a node in the Devnet. The constructor is a method, that will call shortly before the app component is loaded from React. Keep in mind, that we need to call the super function to give the props through the React app.

constructor(props) {
super(props)
// Drop your code here.
}

 

We create a new iota instance and connect us with a Devnet node in our constructor.

 // Create IOTA instance directly with provider
var iota = new IOTA({
'provider': 'https://nodes.devnet.thetangle.org:443'
});
console.log("iota", iota)


 You should see an output like this in your console. 


To get information about the connected node. We can call the getNodeInfo API method and log the response in our console.

 iota.api.getNodeInfo(function(error, success) {
if (error) {
console.error(error);
} else {
console.log(success); }
});


Et Voila! These are all Information we get from this Devnet IOTA node. 



React states

Back to the button. Now, we want to send a transaction, but first, we need to learn a bit more about React. We need our iota methods in the button component. The parent component (app) can deliver data like objects to its child component (SendButton) via props.

First, we save our IOTA object in the React state in our app constructor. 

this.state = {iota: iota}


Then we parse the iota state to the SendButton component.

<SendButton iota={this.state.iota} />


In our SendButton component, we can fetch these properties in the constructor.

constructor(props){
super(props);
console.log("iota from SendButton Component", this.props.iota);
}


If we access our iota object in our send method, we got a weird error.


This because we are in a different scope, and the scope doesn’t know, which context is mean with “this”.

To solve this, we need to bind the context “this” to our onClick handler.

<button onClick={this.send.bind(this)}>Send Transaction</button>


And it works! 

Click here to see the code.


Send a transaction

To send a transaction with the IOTA protocol we need first to prepare a transaction and then attach it to the tangle. 
We use the iota.js.lib helper function sendTransfers, which is a wrapper function, that prepares our transfers and attach it to the tangle and finally, it broadcasts and stores the transaction locally.

https://github.com/iotaledger/iota.lib.js/#sendtransfer 

Our transaction is just a JSON Object, you can define it like here:

const transaction = {
// Recipient address
address: 'XZRCWIPKMX9BBTEVIFEEHOQWBAYCQLRQOYTIIIR9LDYVTPBRLXOFSWZAOYMQDJDNPRNNRWIXLTWZKMK9YJDEZJYOGZ',
// Value sent to recipient
value: 0,
message: 'HELLO9WORLD9FROM9REACT9AND9IOTA',
tag: 'HELLOWORLD'
}


Please keep in mind, that the message and the tag attributes can only contain a Tryte string (A-Z and 9). So if you want to store real data, you will have to use the convert helper functions toTrytes and fromTrytes
Also good to know is that the message can contain 2187 trytes and the tag 27 tryes. 

More information about the anatomy of a transaction, you find here in the IOTA docs.


Now we want to use our sendTransfer method, but we need to know some things before.

iota.api.sendTransfer(seed, depth, minWeightMagnitude, transfers [, options], callback)


Let's check the parameters: 


seed

We use a random seed. Do not use your original seed here! The easiest and securest way to create a seed is to generate it with your terminal:

Linux

$ cat /dev/urandom |tr -dc A-Z9|head -c${1:-81} 


Mac

$ cat /dev/urandom |LC_ALL=C tr -dc 'A-Z9' | fold -w 81 | head -n 1 


You could also just use this javascript function, to generate each time u use it as a new seed.

https://gist.github.com/SteveFromTheOffice/c8448a09352337386f135a16bbb20d93

let seed = GenerateSeed();


depth

This specifies the number of bundles you will walk back and confirm.


minWeightMagnitude

This is the minimum weight magnitude (MWM) that specifies how mwm proof of work is required. On the testnet, anything less than 9 is not going to be accepted.


transfers

This is an array which contains the value, address, and message of your desired transaction. You can specify multiple transactions to different addresses.


options (optional)

This is an object, where you can define the pinouts and the remainder address. We don't need this, because we just use transactions with zero value.

  1. inputs: Array List of inputs used for funding the transfer
  2. address: String if defined, this address will be used for sending the remainder value (of the inputs) to

callback

This is a function which returns the success and error resulting from the sendTransfers function.


So our send function looks like this:

send( ) {

const seed = 'QME9BQDQWRTQLMTY9VALTRNLDQID9SNLQCVC9NNRTSHDLPDIHVJYHHJMYLAOSNFG9QVZ9GIDCNTM9POPS'
const depth = 4
const minWeightMagnitude = 14
// Transfer array representing two different withdrawal transfer
const transaction =
{
// Recipient address
address: 'XZRCWIPKMX9BBTEVIFEEHOQWBAYCQLRQOYTIIIR9LDYVTPBRLXOFSWZAOYMQDJDNPRNNRWIXLTWZKMK9YJDEZJYOGZ',
// Value sent to recipient
value: 0,
message: 'HELLO9WORLD9FROM9REACT9AND9IOTA',
tag: 'HELLOWORLD'
}
const transfers = [transaction]
this.props.iota.api.sendTransfer(seed, depth, minWeightMagnitude, transfers, (error, success) => {
if (error) {
console.error("sendTransfer: error", error);
} else {
console.log("sendTransfer: success", success);
}
}); }


If we go to our Browser and click the button, we got an error in the console:

The error attachToTangle is not available is a common error on Public IOTA nodes.

This is because this function uses heavy CPU load to compute the Proof of Work for the transaction. If node operators left this open person could abuse the function and slow down the node significantly.

So will we have to publish a transaction without using the attachToTanglecommand of the node. This is achieved by overriding the behavior of the library with a PoW service. There are three to choose from:

ccurl.interface.js - This is for node.js environments and allows for PoW to be done locally.

curl.lib.js - This is for WebGL 2 enabled browsers to compute PoW using the GPU of the user's computer

@iota/curl-remote - This is used to mimic a remote node handling the PoW. In reality, this is a standalone service built to provide Pow-as-a-Service.


We will do the PoW local in our Browser.

If you want to use the public Sandbox just follow this tutorial: 

https://docs.iota.org/introduction/tutorials/first-transaction#attach-to-tangle


Local Proof of Work (PoW)

We will use the curl.lib.js to do the POW local with the Browser.

Because of a bug in the main library, we need to use a fork from Martyn James. 
https://github.com/iotaeco/curl.lib.js

So install the node package:

$ npm install iotaeco/curl.lib.js


Just import the library on the top of App.js.

import CURL from 'curl.lib.js'


Add this try/catch statement after you create the IOTA instance and before you bind it to the state.

// Create IOTA instance directly with provider
var iota = new IOTA({
'provider': 'https://nodes.devnet.thetangle.org:443'
});
// Attach curl to iota instance so that we can perform WebGL proof of work
try { CURL.init(); CURL.overrideAttachToTangle(iota);
} catch (err) {
console.error("Error", err);
}
this.state = {iota: iota}


That's it! You should see something like this in your Browser console: