blank Skip to main content

In-Car Payment Systems: Automation of Toll Road Payments Based on IOTA

The Internet of Things (IoT) is starting to radically transform various aspects of our professional and everyday lives. At the same time, the blockchain has rushed into financial and other spheres, offering a different perspective on data validation and security. In this article, we take a look at a powerful combination of Internet of Things and blockchain technologies based on the IOTA platform. To illustrate how things work, we’ve sketched an example of a solution for automated toll road payments.

IOTA can be called a specialized quasi-blockchain platform. Different blockchain platforms include specific sets of features, which makes each platform suitable for particular applications. For example, some platforms work well for ICO projects and creation of cryptocurrencies; others are better used by enterprises for internal purposes. The IOTA platform is designed to be integrated into Internet of Things systems.

Key concepts of IOTA

When discussing IOTA, the first thing worth mentioning is that it’s actually not a blockchain platform. IOTA uses another data structure under the hood, though it’s somewhat similar to a blockchain. IOTA is an open-source distributed permissionless ledger that was specifically designed for the Internet of Things. It uses a novel invention called the Tangle. This determines everything else that makes IOTA different from other platforms. Due to Tangle technology, IOTA is free of blocks, chains, and miners. Let’s look closer at the Tangle structure.

In its design, the Tangle is an innovative data structure based on a directed acyclic graph. The vertices of the graph represent transactions. When a new transaction is added to the graph, it connects to the previous two vertices, thereby validating the last two transactions. Transactions that aren’t validated yet are called tips. The method for selecting the two tips to which a new transaction is attached is called the tip selection algorithm, which is based on the cumulative weight of a transaction (the number of other transactions referencing it).

Here’s what a confirmed transaction looks like in the Tangle explorer:

The Tangle explorer

There are two approaches to establishing consensus in a Tangle:

  1. Markov Chain Monte Carlo (MCMC)
  2. The Coordinator

The first approach is the Markov Chain Monte Carlo method. In short, it works as follows: Select 100 tips and check how many of them directly or indirectly reference the transaction. Based on this number, we can say that the transaction is 80% confirmed, for example. However, since the IOTA network is still developing and there aren’t very many nodes and there isn’t that much activity in the network, there’s a possibility of creating fraudulent transactions.

For this reason, the second approach of transaction validation was established, called the Coordinator. The Coordinator is a special node controlled by the IOTA Foundation that’s used for transaction validation. The Coordinator periodically creates zero-value transactions called milestones. A transaction is considered confirmed if it’s referenced by one of these milestones. Even taking into account the existence of this single node validating transactions, the network is still decentralized since each node of the network verifies that the Coordinator isn’t breaking consensus rules by creating transactions.

More details on the Tangle structure and underlying algorithms can be found in the IOTA documentation.

Now let’s take a look at how the Tangle makes IOTA suitable for IoT applications.

Transaction confirmation without miners. Transactions are approved by users who generate new transactions. This means that the system has no miners. Therefore there’s no need to pay any fee for approving a transaction. This in turn leads to the question of whether IOTA has its own currency. And it does. IOTA uses the IOTA token. But the difference between IOTA and Bitcoin or Ethereum is that the amount of available IOTA was defined in the genesis block and can’t be changed. In other words, all the existing IOTA have already been generated and there’s no way or need to mine them.

The structure of the Tangle also influences the speed of transaction confirmation. The more parties use IOTA, the higher the speed of confirmation because each new transaction approves the two previous transactions.

Micro transactions. Another distinctive feature of IOTA are so-called micro transactions, or transactions of small amounts of information. Moreover, IOTA supports not only value transactions for transferring funds but also zero-value transactions that don’t involve sending IOTA at all. These can be used by devices, for example, to transfer sensor data to a server.

Branching for local networks. IOTA supports so-called branching, which makes it possible to run a cluster in a local network that’s not connected to the internet. This cluster can be synchronized with the main network at any given frequency, but the integrity of the cluster will still be preserved.

The absence of transaction fees makes IOTA rather attractive for IoT applications. Moreover, the speed of transactions increases with more transactions being sent without any need to stay connected to the internet all the time.

Read also:
How to Develop an Ethereum Smart Contract for Application Licensing

Toll roads based on IOTA

It’s common practice to pay tolls when entering or exiting a highway in Europe. Each time a car reaches the gate, the driver needs to pay either with a card or cash to open the gate. In order to test drive IOTA, we decided to design a prototype of a system for automated in-car toll payments.

The general idea is shown in the image below.

IOTA for toll roads

Each car in our model is equipped with a mini computer responsible for communicating with a toll station. Cars and toll stations are connected over Bluetooth and all in-vehicle payments are conducted through IOTA.

Here’s the basic scenario:

  1. As soon as a car reaches the toll station, a small camera integrated into the windshield detects the QR code on the toll station. The QR code provides the address for connecting over Bluetooth.
  2. The scanned QR code acts like a trigger. So when the camera scans the QR code and receives the address, the mini computer integrated into the car tries to connect to the toll station over Bluetooth.
  3. The car and the toll station perform a handshake, during which the car verifies the identity of the toll station.
  4. The toll station sends an encrypted IOTA address and the payment amount to the car.
  5. The car performs a transaction in IOTA to transfer the amount due to the toll station’s address.
  6. The car sends the hash of the transaction to the toll station for verification.
  7. The toll station verifies that the transaction has been confirmed and checks the details to make sure that this is the correct transaction.
  8. If the transaction is successful, the toll station opens the gate. Otherwise, the driver receives a suggestion to pay the toll in another manner (by card or cash) due to some error (for example, not enough IOTA).

Related services

Blockchain-based Solution Development

Components of the system

This system includes several hardware and software components. Let’s start with hardware.


We need the following hardware components.

  1. A mini computer installed in the car. It should have Wi-Fi and Bluetooth modules in order to connect to toll stations and send transactions to the IOTA network.
  2. A camera integrated in the car’s windshield. The camera should also be connected to the mini computer in order to transfer captured images.
  3. A computer with a Bluetooth module and access to the internet at the toll station.


Since we have several hardware components, we’ll need software that can handle the following tasks:

  1. The client application running on the car mini computer should be capable of:
    –  Scanning a QR code captured by the camera
    –  Connecting via Bluetooth to a toll station computer
    –  Connecting to the IOTA node and sending transactions
  2. The server application running at the toll station should be capable of:
    –  Accepting and processing connections via Bluetooth
    –  Connecting to the IOTA node to verify transactions

We’ll use Python, PyCrypto for encryption, the PyBluez library for Bluetooth support, and PyOTA for interacting with the IOTA API.

Since actual in-car payment systems would tend to be rather large,  we’re going to reduce the scope a bit for the prototype. The prototype will be based on the Raspberry mini computer. Instead of a camera that scans the QR code, we’ll use a button as a trigger to start communication with the toll station. If the transaction goes through, an LED will blink showing that the car can pass. The toll station will be represented by a computer with Bluetooth support.

Here’s what the prototype circuit looks like:

IOTA prototype circuit


Image Credit: Fritzing

As you can see from the figure above, the button is connected to GPIO26 and the LED to GPIO19. We’re going to observe the state of GPIO26 to know when the button has been pressed. Pressing the button will trigger the start of the communication protocol. After successful payment and transaction verification, we’ll set the value of GPIO19 to make the LED turn on for a few seconds, indicating success.

Here’s the logic of checking the state of the GPIO and setting the necessary value. The RPi library is used to connect to the GPIO.

class Hardware:
   def __init__(self):
       IO.setup(LED_GPIO, IO.OUT)
       IO.setup(BUTTON_GPIO, IO.IN)
   def blink_light(duration=0.2):
       # turn the LED on (making the voltage level HIGH)
       IO.output(LED_GPIO, True)
       IO.output(LED_GPIO, False)
   def is_button_pressed():
       return not IO.input(26)

Car and toll station communication protocol

We considered several technologies that can be used for establishing communication between the car and toll station computers:

  • RFID reader
  • Wi-Fi
  • NFC
  • Bluetooth
  • infrared port

We decided to use Bluetooth for this purpose and here’s why:

  • No manual actions are required to initiate a connection (RFID and NFC require actions from the driver due to the short distance allowed between devices)
  • The range isn’t too far, lowering the risk of interference with other cars in the queue. At the same time, the range isn’t as short as with RFID and NFC.
  • There’s less probability of signal interference than with an infrared port.

In order to establish communication via Bluetooth, the toll station should act as a server, accepting connections from cars. Each car is a client.

As for the communication protocol, we need to take additional actions to ensure security. First of all, we need to make sure that we communicate with a trusted server. Then, we also need to add an encryption layer to the protocol to transfer the IOTA payment address. Finally, the server needs to verify that the received transaction hash is associated with a particular client to avoid fraudulent transactions that use previously confirmed transactions. The whole protocol looks as follows:

IOTA protocol

This is a simplified scheme. A better option would be to send messages via HTTPS over Bluetooth and validate the server’s certificate. The information about valid server certificates can be also stored in the Tangle.

In order to provide Bluetooth communication, the toll station should start the server and listen for connections.

self._server_sock = bluetooth.BluetoothSocket(protocol)
self._server_sock.bind(("", bluetooth.PORT_ANY))
self._service_name = service_name
bluetooth.advertise_service(self._server_sock, service_name,
client_sock, address = self._server_sock.accept()

 After that, each client is processed in a separate thread.

The car client has to find the necessary service based on the information retrieved from the scanned QR code.

services = bluetooth.find_service(name=service_name,
# connect to the necessary service
for i in range(len(services)):
   match = services[i]
   if match["name"] == service_name:
       port = match["port"]
       name = match["name"]
       host = match["host"]
       self._client_socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
       self._client_socket.connect((host, port))

 After successfully connecting, the client and the server exchange messages in the form of JSON files encrypted with RSA.

Read also:
Tezos Blockchain and Smart Contract Overview

Something more to know about IOTA

Seed and address are two important IOTA account concepts. In order to create or enter an account you need to generate a seed, which is a unique access key. This seed must not be shared with anyone. Then a pair of keys, public and private, is generated based on the seed. The public key is the address used for transferring funds. The private key associated with this address is used to sign the transaction. One of IOTA’s features is that it uses the Winternitz one-time signature. The Winternitz algorithm can be used for one-time signatures only since it reveals part of the private key with each signature. Because of that, the same address and public key should not be used more than once to transfer funds. Otherwise, with each transfer it becomes easier and easier to break the private key associated with that address. The same address can be used many times over when receiving funds, but a new address (and thus private key) needs to be generated every time you send funds.

This leads us to the question of whether the number of addresses is finite for any given seed. Basically, each address depends on the seed, the index value inside the seed, and the security level chosen for the address (the length of the address). So the number of possible addresses depends on the number of possible values of the index for the given seed and security level.

Another interesting fact is that with each transfer, the rest of the balance is sent to a newly generated address. To understand this process, let’s take a look at a particular example and examine the bundle of the transaction to transfer some IOTA.

Here’s the transaction:

IOTA transaction

And here are the contents of the bundle.

IOTA transaction contents

A transfer actually includes four transactions:

  1.  The balance is subtracted from the sender’s address. As a result, the transaction has a negative value.
  2. The required amount is transferred to the receiver’s address and the transaction has the positive value of 1.
  3. The third transaction is the zero-value meta transaction containing part of the signature. The signature is too long to be stored in one transaction and therefore is split into two transactions.
  4. The final transaction sends the rest of the sender’s balance to the newly generated address.

And here’s the state of the account after several transfers. As you can see, there are 37 addresses currently used for this seed.

IOTA account

As a result, when getting the balance all addresses are enumerated to calculate the total balance. The drawback is that this can take a significant amount of time, which increases as more and more addresses are used. This action takes even more time than the transaction itself.

We can save the latest address to avoid enumerating addresses and needing to get the latest index to generate a new address next time. This would provide significant time savings.

Read also:
Internet of Things Security: Challenges and Best Practices

IOTA integration

IOTA uses the IRI API to communicate with the network. It can be configured either for the local node or accessed from one of the remote nodes. The list of remote nodes to connect to is publicly available.

The production network and the so-called devnet used for testing are available. In order to monitor the state of transactions, network explorers such as TheTangle and its devnet version can be used.

You may also wonder where you can get some test IOTA for testing transactions. You can first try the devnet faucet. Sometimes the faucet isn’t working, in which case you may also connect to the Discord channel and request some IOTA there.

The PyOTA library facilitates work with the IRI API in Python, providing the core API and also the extended API, which hides some steps under the hood.

There are actually four functions we need for proper working of the system:

  • Generating a new address to be used by the client for transferring payment
  • Preparing and sending a transaction
  • Checking the current balance
  • Verifying the transaction

First of all, we need to initialize an IOTA instance.

NodeURL = "https://nodes.testnet.iota.org:443"
SeedSender = "YourSeed"
api = iota.Iota(NodeURL, SeedSender)

Since at the beginning we don’t know the latest address containing the user’s balance, we need to enumerate all addresses and get the actual address. This is performed in the constructor of the IOTA Manager class. This process may take a while, especially if a lot of addresses were used. Because of that, when we obtain the latest address we save it to the config file to speed up further initialization.

The latest available address can be received in the following way, where index indicates the latest address loaded from the config file:

account_data = api.get_account_data(start=index,
self._address = account_data["addresses"][-1]

 The balance can be checked using the get_balances function. We pass the specific address to it to avoid checking all addresses for that seed. 

balance_info = api.get_balances([self._address])

 Sending a transaction involves preparing the transaction object and sending the transfer. We pass the specific address as the inputs parameter to the send_transfer function. The send_transfer function is part of the PyOTA extended API and hides steps for generating a new address and transferring the rest of the funds to it. 

tx1 = iota.ProposedTransaction(address=iota.Address(receiver),
# Sending the iotas
bundle = api.send_transfer(depth=3,

 After that, we need to get the hash of the transaction from the bundle to pass it to the server. We also obtain a newly generated address to use in the next transfer. 

bundle_info = bundle['bundle']
tx_to_check = vars(bundle_info[0])["hash"]
self._address = iota.Address(vars(bundle_info[-1])["address"],
    key_index=self._address.key_index + 1,

 The transaction state can be checked with the help of the get_latest_inclusion function, and with the find_transactions call we can check the tag of our transaction.

def check_transaction(hash, tag):
   is_confirmed = api.get_latest_inclusion([hash])
   if is_confirmed:
       res = api.find_transactions(tags=[iota.Tag(tag)])
       return hash in res["hashes"]
   return False

Read also:
How to Implement a Custom Blockchain for Your Business: Graphene Framework


In this article we’ve considered a new approach to automating toll road connected car payments using IOTA and analyzed advantages and disadvantages of IOTA. The obvious benefits of IOTA are:

  • No transaction fees
  • Ability to send micro transactions and non-value transactions
  • No miners

On the other hand, the need to generate a new address for each transfer and enumerate all addresses for checking the balance can be considered a hidden pitfall, albeit one that can be overcome.

By the end of this decade, the number of connected cars on the road is expected to hit 250 million, which will offer tremendous opportunities for decentralized and secured applications based on IOTA Tangle and distributed ledger technology. Several major automotive manufacturers have already begun to integrate IOTA technology into their products.

As we advance into the future where cars will be able to pay autonomously for tolls and parking, the transmission of data over radio waves to vehicles will be core to maintaining order on the roads. The possibilities for IOTA Tangle-based technology go far beyond machine-to-machine payments as the need for real-time zero fee transactions and secure data transfers becomes even more apparent with driverless cars not that far in the future.

At Apriorit, one of our specialties is blockchain technology. Our developers have a high level of expertise in this sphere and can assist you in developing a blockchain-based solution from scratch.











Have a question?

Ask our expert!

Tell us about your project

Send us a request for proposal! We’ll get back to you with details and estimations.

By clicking Send you give consent to processing your data

Book an Exploratory Call

Do not have any specific task for us in mind but our skills seem interesting?

Get a quick Apriorit intro to better understand our team capabilities.

Book time slot

Contact us