A lot of efforts is going into distributed ledger technologies like the blockchain, and while I keep hearing blockchain is the future, there’s a lot of hype, and so far I have not seen that many practical use cases.
But recently I saw Open Source Foundries – a new company announced at Linaro Connect US 2017 – participated in the IOTA blockchain BoF at the OpenIoT Summit 2018 showing a demo publishing sensor data to the IOTA Tangle.
So maybe we have a practical application here… Sadly, there’s no video recording of the IOTA blockchain BoF, so instead let’s go to the IOTA website to find out more.
That’s the short description of the solution:
An Open-Source Distributed Ledger
The first open-source distributed ledger that is being built to power the future of the Internet of Things with feeless microtransactions and data integrity for machines.
The key technology behind IOTA (Internet of Things Applications) is called the Tangle:
IOTA is a revolutionary new transaction settlement and data transfer layer for the Internet of Things (IoT). It is based on a new distributed ledger technology, the Tangle, which overcomes the inefficiencies of current Blockchain designs and introduces a new way of reaching consensus in a decentralized peer-to-peer system. Using IOTA, for the first time ever, people and machines can transfer money and/or data without any transaction fees in a trustless, permissionless, and decentralized environment. This means that even nano-payments are possible without the need for a trusted intermediary of any kind.
Everything still feels a little abstract after reading the introduction, and description, but the summary of the talk at OpenIoT Summit explains some of the potential application of this type of technology:
Blockchain based protocols can be utilized to solve difficult problems in the IoT and Embedded spaces. In this BoF we will discuss how to use this technology to establish a decentralized root of trust, that allows device control, ownership, and secure data transfer for devices with constrained footprints. In addition to blockchain, we will delve into new distributed ledger technology, and zero-knowledge proofs which allow one party (the prover) to prove to another (the verifier) that a statement is true, without revealing any information beyond the validity of the statement itself. This is important for anonymous machine to machine transactions to occur with very little compute resources.
The latter appears to refer to IOTA without directly mentioning it.
You’ll read in many places that IOTA is the ideal solution for the Internet of Things, but others have a different opinion. Only time will tell.
The work was done by muXxer, and is described as “docker-compose.yml for IOTA IRI on ROCK64 including Nelson.cli, Nelson.gui and Field.cli”.
This is all alpha and beta software with four main components used:
- IOTA IRI – IOTA Reference Implementation
- CarrIOTA Nelson.cli – Allows auto-discovery (P2P) for IOTA-Fullnodes while at the same time protecting the network against attacks
- CarrIOTA Nelson.gui – Web based UI for Nelson.cli
- CarrIOTA Field.cli – Proxy for your IRI that sends regular statistics to the Field server, and optionally accepts jobs from the server’s load balancer
The first think it do is to download and flash ayufan Ubuntu Bionic containers image. At the time of writing, the latest release was bionic-containers-rock64-0.6.41-227-arm64.img.xz,and I just flashed with Etcher to my eMMC flash module, but a micro SD card would do. In case you don’t know how to perform that step, read Rock64 Ubuntu review. As we’ll see below you’ll also need a USB hard drive or SSD to store the Tangle, unless you have a large (64GB+) eMMC module or micro SD card.
Now we can insert the eMMC flash module or micro SD card int othe board, boot it up, and login via SSH or the serial terminal using rock64/rock64. Now we can make sure our system is up-to-date:
sudo apt update
sudo apt dist-upgrade
You may want to change the default password, or use public/private keys to login via SSH without a password.
We now need to mount our external hard drive and redirect the docker directory. I’ll use the EXT4 partition (volume name USB3_EXT4) on my USB drive. Let’s find out the UUID / PARTUUID:
sudo blkid | grep EXT4
/dev/sda2: LABEL="USB3_EXT4" UUID="309f587d-96d9-488e-9aa5-c67d7b0e2b57" TYPE="ext4" PARTUUID="0007fd4c-02"
Create a target directory for the external drive
sudo mkdir -p /mnt/iota-hdd/
and add the drive to your /etc/fstab:
PARTUUID=0007fd4c-02 /mnt/iota-hdd ext4 defaults,discard 0 2
All all storage devices, & check our drive are mounted correctly:
sudo mount -a
The next step is to redirect docker containers to our external drive with a symlink:
sudo systemctl stop docker
sudo mv /var/lib/docker/ /mnt/iota-hdd/docker
sudo ln -s /mnt/iota-hdd/docker/ /var/lib/docker
sudo chown -R root:root /mnt/iota-hdd/docker
sudo systemctl start docker
The instructions recommend to setup 8GB swap for Rock64 with 4GB RAM. Instead I tried to enable ZRAM first, but while the current Ubuntu 18.04 image comes with a kernel with ZRAM module, and zram-config is installed, the zram swaps are not configured automatically. So instead I just configured 2GB swap for my Rock64 1GB RAM board:
sudo mkdir -p /var/cache/swap
sudo fallocate -l 8G /var/cache/swap/swap0
sudo chmod 0600 /var/cache/swap/swap0
sudo mkswap /var/cache/swap/swap0
sudo swapon /var/cache/swap/swap0
Let’s check it’s properly enabled:
total used free shared buff/cache available
Mem: 920M 101M 568M 3.5M 251M 802M
Swap: 2.0G 0B 2.0G
Good, now we can add to /etc/fstab:
/var/cache/swap/swap0 none swap sw 0 0
and adjust some swap settings in /etc/sysctl.conf:
This will only make the system use swap if RAM is low, and try to keep more memory for applications instead of cache. The parameters are explained in details here.
We can reload the settings…
sudo sysctl -p
and get the IOTA Full node code for Rock64:
git clone https://github.com/muXxer/rock64-docker-iota-fullnode.git
Some scripts and documentation can be found in the folder:
docker-compose.yml install_latest_linux_kernel.sh update_containers.sh
dockerfiles LICENSE.md volumes
The first configuration step is to change the Nelson config in volumes/nelson.cli/config.ini file to match our requirements. I just changed the name, but as you can see there are plenty of other parameters in the file:
name = CNXSoft Nelson node
cycleInterval = 60
epochInterval = 300
apiPort = 18600
apiHostname = 0.0.0.0
port = 16600
IRIHostname = iri
;UDP doesn't seem to work properly in a docker container (maybe https://github.com/iotaledger/iri/issues/276 ?)
;IRIProtocol = any
IRIProtocol = tcp
IRIPort = 14265
TCPPort = 15600
UDPPort = 14600
dataPath = /data/neighbors.db
; maximal incoming connections. Please do not set below this limit:
incomingMax = 5
; maximal outgoing connections. Only set below this limit, if you have trusted, manual neighbors:
outgoingMax = 4
isMaster = false
silent = false
gui = false
getNeighbors = https://raw.githubusercontent.com/SemkoDev/nelson.cli/master/ENTRYNODES
; add as many initial Nelson neighbors, as you like
neighbors = mainnet.deviota.com/16600
neighbors = mainnet2.deviota.com/16600
neighbors = mainnet3.deviota.com/16600
neighbors = iotairi.tt-tec.net/16600
; Protect API with basic auth
;username=<SET YOUR USERNAME>
;password=<SET YOUR PASSWORD>
It mostly define some network & IRI (IOTA Reference Implementation) parameters, database path, etc…
Then we have to change the Field config in volumes/field.cli/config.ini. Again I only changed the name:
name = CNXSoft Field node
IRIPort = 14265
IRIHostname = iri
address = PHCIWQQIHQCAKPTJYXSRHIOSMZHHYVBBCALEBGXULYIAYJLBMFNAOHVJZUJZZZJXYUQSXHZZAKUBVLUDCE9AK9ZNVW
; Alternatively to address, you can provide a (NEW) seed
; In this case, the Field cient will be generating new, unused addresses dynamically.
; seed = XYZ
port = 21310
pow = yes
disableIRI = false
; If you want Field to generate a custom id, instead of using machine-id
customFieldId = true
You’ll likely want to change the address to you own IOTA address for donations, otherwise you can leave the default to give donations to muXxer (the developer).
If you want to generate your own address, you’ll need to download and install the IOTA Wallet on your computer to create one.
The first time we launch the wallet, we’re being asked to select between light node or full node. Now we can better understand that we are dong… Full node download the complete tangle database, while light node will only connect to a remote mode. It looks like the equivalent of nodes and gateways found in any IoT networks. A few more details here.
I went with the Light Node, and was asked to select a host from list:
The next screen asks you to login. You can do that with your Seed. But how to create one? Easy… just type a random string of 81 characters with uppercase Latin characters and the number 9 only in a text editor, safely save it (you’ll also all your token if you don’t), copy and paste it in the “Seed” filed and login.
You should then able to check your receive address and QR code, which you can share publicly. Just don’t do that with our Seed address, which must remain private. You can insert your receive address in volumes/field.cli/config.ini.
Time to download the Tangle (database), about 12.5GB large for now:
chmod +x download_mainnet_db.sh
The script will also decompress the files after which the download space used by the directory will be 17GB, after the 12.5GB compressed archives are deleted at the end. That means you need a least 29.5GB free space for this to work, and explains why we need to use a hard drive, although I’d assume a 64GB eMMC module or good micro SD card might do too.
You may have to open the following ports for Rock64 IP address in your firewall:
- 14600 UDP – IOTA/IRI UDP connection port
- 15600 TCP – IOTA/IRI TCP connection port
- 16600 TCP – Nelson.cli TCP connection port
- 21310 TCP – Field.cli TCP connection port
We can now start our IOTA full node in docker:
sudo docker-compose up -d
The first time many files will be downloaded, and extracted.
sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e91bf54bc17b muxxer/rock64_nelson.gui:latest "/usr/local/bin/nels…" About an hour ago Up About an hour 0.0.0.0:5000->5000/tcp iota_nelson.gui
3d38cdaff1d4 muxxer/rock64_field.cli:latest "/usr/local/bin/fiel…" About an hour ago Up About an hour 0.0.0.0:21310->21310/tcp iota_field.cli
3e255409e7d2 muxxer/rock64_nelson.cli:latest "/usr/local/bin/nels…" About an hour ago Up About an hour 0.0.0.0:16600->16600/tcp, 0.0.0.0:18600->18600/tcp iota_nelson.cli
bc7f2cd457b5 muxxer/rock64_iota_iri:latest "/usr/bin/java -XX:+…" About an hour ago Up About an hour 0.0.0.0:14265->14265/tcp, 0.0.0.0:15600->15600/tcp, 0.0.0.0:14600->14600/udp iota_iri
as well as the IRI logs…
sudo docker logs iota_iri
05/26 11:28:10.654 [main] INFO com.iota.iri.IRI - Welcome to IRI 184.108.40.206
05/26 11:28:49.118 [main] INFO c.i.i.s.r.RocksDBPersistenceProvider - Initializing Database Backend...
05/26 11:28:54.833 [main] INFO c.i.i.s.r.RocksDBPersistenceProvider - RocksDB persistence provider initialized.
05/26 11:28:54.890 [Latest Milestone Tracker] INFO com.iota.iri.Milestone - Waiting for Ledger Validator initialization...
05/26 11:28:54.901 [Solid Milestone Tracker] INFO com.iota.iri.Milestone - Initializing Ledger Validator...
05/26 11:28:55.301 [main] INFO com.iota.iri.network.UDPReceiver - UDP replicator is accepting connections on udp port 14600
05/26 11:28:55.306 [UDP receiving thread] INFO com.iota.iri.network.UDPReceiver - Spawning Receiver Thread
05/26 11:28:55.308 [UDP receiving thread] INFO com.iota.iri.network.UDPReceiver - Receiver thread processed/dropped ratio: 0/0
05/26 11:28:55.310 [main] INFO c.i.i.network.replicator.Replicator - Started ReplicatorSourcePool
05/26 11:28:56.470 [Thread-2] INFO c.i.i.n.r.ReplicatorSourcePool - TCP replicator is accepting connections on tcp port 15600
05/26 11:28:56.849 [pool-3-thread-1] INFO com.iota.iri.network.Node - Spawning Broadcaster Thread
05/26 11:28:56.908 [pool-3-thread-3] INFO com.iota.iri.network.Node - Spawning Neighbor DNS Refresher Thread
05/26 11:28:56.909 [pool-3-thread-3] INFO com.iota.iri.network.Node - Checking Neighbors' Ip...
05/26 11:28:56.906 [pool-3-thread-4] INFO com.iota.iri.network.Node - Spawning Process Received Data Thread
05/26 11:28:56.890 [pool-3-thread-2] INFO com.iota.iri.network.Node - Spawning Tips Requester Thread
05/26 11:28:56.936 [pool-3-thread-5] INFO com.iota.iri.network.Node - Spawning Reply To Request Thread
05/26 11:28:56.940 [pool-3-thread-2] INFO com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 8101473
05/26 11:29:06.943 [pool-3-thread-2] INFO com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 8101473
05/26 11:29:16.945 [pool-3-thread-2] INFO com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 8101473
05/26 11:29:27.373 [pool-3-thread-2] INFO com.iota.iri.network.Node - toProcess = 0 , toBroadcast = 0 , toRequest = 0 , toReply = 0 / totalTransactions = 8101473
05/26 11:29:32.046 [Solid Milestone Tracker] INFO com.iota.iri.LedgerValidator - Building snapshot... Consistent: #429999, Candidate: #430000
…and Nelson logs:
sudo docker logs iota_nelson.cli
Downloaded entry neighbor: mainnet.deviota.com/16600
Downloaded entry neighbor: mainnet2.deviota.com/16600
Downloaded entry neighbor: iotairi.tt-tec.net/16600
Downloaded entry neighbor: voss-hosting.de/16600
Downloaded entry neighbor: 220.127.116.11/16600
Downloaded entry neighbor: iotanode.party/16600
Downloaded entry neighbor: nelson.vanityfive.de/16600
Downloaded entry neighbor: tangle.vanityfive.de/16600
Downloaded entry neighbor: tanglenode.de/16600
Downloaded entry neighbor: nelson.iota.fm/16000
Downloaded entry neighbor: node.io7a.com/16600
Downloaded entry neighbor: us1.tangleno.de/16600
Downloaded entry neighbor: eu1.tangleno.de/16600
Downloaded entry neighbor: iota.bluemx.de/16600
Downloaded entry neighbor: nelson.iotacore.de/16600
11:28:18.693 16600::IRI IRI not ready on iri:14265, retrying...
11:28:23.873 16600::IRI IRI not ready on iri:14265, retrying...
11:28:28.884 16600::IRI IRI not ready on iri:14265, retrying...
11:28:33.890 16600::IRI IRI not ready on iri:14265, retrying...
11:28:38.902 16600::IRI IRI not ready on iri:14265, retrying...
11:28:43.914 16600::IRI IRI not ready on iri:14265, retrying...
11:28:48.929 16600::IRI IRI not ready on iri:14265, retrying...
11:28:53.967 16600::IRI IRI not ready on iri:14265, retrying...
11:29:06.868 16600::IRI IRI not ready on iri:14265, retrying...
11:29:19.176 16600::IRI IRI not ready on iri:14265, retrying...
11:29:28.510 16600::IRI IRI not ready on iri:14265, retrying...
11:29:33.620 16600::IRI IRI not ready on iri:14265, retrying...
11:29:38.633 16600::IRI IRI not ready on iri:14265, retrying...
11:30:33.835 16600::IRI IRI not ready on iri:14265, retrying...
11:31:04.704 16600::IRI IRI not ready on iri:14265, retrying...
11:32:20.277 16600::IRI IRI not ready on iri:14265, retrying...
11:32:36.775 16600::IRI IRI not ready on iri:14265, retrying...
11:33:04.465 16600::IRI IRI not ready on iri:14265, retrying...
11:33:30.791 16600::IRI IRI not ready on iri:14265, retrying...
11:33:37.101 16600::IRI Static neighbors:
11:33:37.234 16600::NODE WARNING: you have no static neighbors and outboundMax (4) is set below the advised limit (5)!
11:33:37.236 16600::NODE WARNING: incomingMax (5) is set below the advised limit (6)!
11:33:37.238 16600::NODE WARNING: incomingMax (5) is set below outgoingMax (5)!
11:33:38.144 16600::LIST Adding to the list of known Nelson peers: 18.104.22.168:16600
11:33:38.292 16600::LIST Adding to the list of known Nelson peers: node.io7a.com:16600
11:33:38.301 16600::LIST Adding to the list of known Nelson peers: iota.bluemx.de:16600
11:33:38.384 16600::LIST Adding to the list of known Nelson peers: nelson.vanityfive.de:16600
11:33:38.450 16600::LIST Adding to the list of known Nelson peers: tangle.vanityfive.de:16600
11:33:38.453 16600::LIST Adding to the list of known Nelson peers: tanglenode.de:16600
11:33:38.455 16600::LIST Adding to the list of known Nelson peers: voss-hosting.de:16600
11:33:38.458 16600::LIST Adding to the list of known Nelson peers: iotanode.party:16600
11:33:38.468 16600::LIST Adding to the list of known Nelson peers: nelson.iotacore.de:16600
11:33:38.499 16600::LIST Adding to the list of known Nelson peers: mainnet2.deviota.com:16600
11:33:38.508 16600::LIST Adding to the list of known Nelson peers: mainnet.deviota.com:16600
11:33:38.519 16600::LIST Adding to the list of known Nelson peers: us1.tangleno.de:16600
11:33:38.523 16600::LIST Adding to the list of known Nelson peers: eu1.tangleno.de:16600
11:33:38.609 16600::LIST Adding to the list of known Nelson peers: iotairi.tt-tec.net:16600
11:33:38.937 16600::LIST Adding to the list of known Nelson peers: nelson.iota.fm:16000
11:33:38.984 16600::LIST Adding to the list of known Nelson peers: mainnet3.deviota.com:16600
11:33:38.991 16600::LIST DB and default peers loaded
11:33:39.102 16600::NODE server created...
11:33:39.116 16600::HEART new personality 7 99c0987c1709c86bb8b2474dee5c4e5b8fc912c41cdc279182e267faae255b829d1b8cee50c1af41e08247e58512e3d5
11:33:39.118 16600::HEART Cycle/epoch intervals: 60 300
11:33:39.153 16600::NODE connecting peer us1.tangleno.de:16600
11:33:39.217 16600::NODE connecting peer nelson.vanityfive.de:16600
11:33:39.227 16600::NODE connecting peer tangle.vanityfive.de:16600
11:33:39.233 16600::NODE connecting peer nelson.iota.fm:16000
11:33:39.378 16600::NODE Nelson v.0.4.0 initialized
11:33:40.281 16600::IRI Neighbors removed (if there were any): udp://us1.tangleno.de:14600
11:33:40.287 16600::NODE connection closed us1.tangleno.de:16600 (remotely dropped)
11:33:40.291 16600::IRI Neighbors removed (if there were any): udp://tangle.vanityfive.de:14600
11:33:40.293 16600::NODE connection closed tangle.vanityfive.de:16600 (remotely dropped)
11:33:40.477 16600::IRI Neighbors removed (if there were any): udp://nelson.vanityfive.de:14600
11:33:40.479 16600::NODE connection closed nelson.vanityfive.de:16600 (remotely dropped)
11:33:49.687 16600::NODE connecting peer iotanode.party:16600
11:33:50.086 16600::NODE connecting peer 22.214.171.124:16600
11:33:50.091 16600::NODE connecting peer eu1.tangleno.de:16600
11:33:51.760 16600::NODE connection established iotanode.party:16600
11:33:54.098 16600::LIST Adding to the list of known Nelson peers: 126.96.36.199:16600
11:33:54.359 16600::LIST Adding to the list of known Nelson peers: 188.8.131.52:16600
11:33:54.371 16600::LIST Adding to the list of known Nelson peers: 184.108.40.206:16600
11:33:54.374 16600::LIST Adding to the list of known Nelson peers: 220.127.116.11:16600
11:33:54.379 16600::LIST Adding to the list of known Nelson peers: 18.104.22.168:16600
11:33:54.381 16600::LIST Adding to the list of known Nelson peers: 22.214.171.124:16600
11:33:55.247 16600::IRI Neighbors added: tcp://iotanode.party:15600
11:34:41.253 16600::NODE new cycle
11:35:41.989 16600::NODE new cycle
11:35:47.671 16600::IRI Neighbors removed (if there were any): udp://nelson.iota.fm:14600
11:35:47.674 16600::NODE connection closed nelson.iota.fm:16000 (remotely dropped)
11:35:52.440 16600::NODE connecting peer mainnet3.deviota.com:16600
11:35:54.743 16600::NODE connection closed mainnet3.deviota.com:16600 (remotely dropped)
11:35:57.420 16600::IRI Neighbors removed (if there were any): udp://126.96.36.199:14600
11:35:57.423 16600::NODE connection closed 188.8.131.52:16600 (remotely dropped)
11:35:57.665 16600::IRI Neighbors removed (if there were any): udp://eu1.tangleno.de:14600
11:35:57.668 16600::NODE connection closed eu1.tangleno.de:16600 (remotely dropped)
We can also access the Nelson GUI in a web browser using http://rock64_ip:5000.
This is what it looks like with a few (2) peers connected.
A full IOTA node is not exactly designed to run on ultra low end hardware:
total used free shared buff/cache available
Mem: 920M 802M 37M 3.0M 81M 101M
Swap: 2.0G 2.0G 2.9M
All my 1GB of RAM and 2GB of swap were quickly filled up, which must be why the instructions where for a Rock64 with 4GB RAM with 8GB swap space setup on a SSD… Sometimes while logging with SSH I could also see the following message:
System information disabled due to load higher than 4.0
At this point , I restarted the IOTA Wallet on my computer, edited the Node Configuration to see if it would connected to my full node.
And it did, you just need to use the API port in the address / URL.
I wanted to try to send sensor data to the Tangle, but I ran out of time for this first look. Some resources to look at would be the official documentation to send a transaction and a Raspberry Pi Project combining IOTA and MQTT. I can see companies can post data streams to the IOTA marketplace, and users/customers can pay tokens to access sensor data.
- Tamper-proof, quantum resistant and fast
- No fees involved
- IOTA tokens are not needed to transfer the data – the data is packed into the transaction and can be sent to whatever recipient is chosen. So you can send 0 IOTA and still deliver the data for free
- IOTA will be able to handle thousands of transactions per second with each transaction containing valuable data without fees involved
Based the answer to Reddit post, the Tangle does not actually store sensor data, but instead establish a connection and verifies integrity. So you’d still have your own database to store the data, so I understand IOTA just makes it easier to share securely with or without payment.
Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.