Integrating physical devices with IOTA — Managing price and addresses
The 4th part in a series of beginner tutorials on integrating physical devices with the IOTA protocol.
This is the 4th part in a series of beginner tutorials on integrating physical devices with the IOTA protocol. In this tutorial we’ll be adding a couple of new features to our IOTA payment system. These features are related to how we manage the price of our service in a volatile IOTA market and how we deal with the IOTA one-time signature problem.
This tutorial will be more software oriented compared to the previous tutorials in this series as we will not be adding any new hardware to our project.
The Use Case
Now that we have our LCD based user interface in place we should take a closer look at a couple of issues that was briefly touched upon in the previous tutorial. Let’s start with the topic commonly referred to as address reuse.
Just to be clear, when i use the term “IOTA one-time signature problem”, i’m not referring to “problem” as in any error or bug in IOTA. The IOTA one-time signature scheme is a protection mechanism that was added to the IOTA protocol by design. Still, it’s something we need to be aware of, and deal with, when building applications on top of the IOTA protocol. As described in the previous tutorial “as long as the hotel owner do not spend any funds from his refrigerator addresses they are completely safe, however, as soon as he spends any funds from one of the addresses, the address is no longer safe and must be replaced by a new IOTA payment address”. What this actually means is that each time you spend funds from an IOTA address, a part of its private key is exposed, making it possible for a bad actor to forge it’s signature and steal it’s funds. So, how do we deal with this “problem”? We have to assume that the hotel owner wants to spend his hard earned IOTA’s at one point, right? Well, one option would be for him to just replace the old refrigerator payment address with a new address whenever he wants to spend from the old address. A better alternative might be to simply generate a new address for every payment so that we could ignore the address reuse problem all together. Now that we have our new LCD in place, we also have the practical means of implementing this solution.
The second issue i want to discuss in this tutorial is how we manage the price of our refrigerator service with respect to the volatile IOTA market. Having a static IOTA price for our refrigerator service, say 1 MIOTA for 1 hour of service, might not be the best business model for our hotel owner. After all, the price he pays in USD for electricity and maintenance of his refrigerator service is pretty much static and decoupled from the day to day volatility of the IOTA market price. I think a more sustainable business model for our hotel owner would be to price his refrigerator service in USD, say 1 USD for 1 hour service, and instead convert the USD price to MIOTA at the beginning of each transaction. So how do we implement this feature? Again, our new LCD comes to the rescue. By using an API call to the popular coinmarketcap.com website we can lookup the current IOTA price in USD, convert our USD price to IOTA’s, and display the correct IOTA price on the LCD. Another issue that we need to take into account is that our price in USD also might change from time to time depending on external factors such as the price of electricity. So we have to make sure we have an easy method of updating the USD price, and at the same time make sure the guest get’s the time of service he paid for. This should all be possible with the use of some basic math.
It should be noted that the new Trinity wallet already have a built in feature for converting fiat currency to IOTA. So in that sense it might be good enough to just display the refrigerator price in fiat currency, and have Trinity take care of the fiat to IOTA conversion.
The payment process
Next, lets see how a new payment process based on generating new addresses for each payment might look like.
- Generate new payment address
We start by using the get_new_addresses() function in PyOTA to generate a new payment address. Notice that we now have to provide a valid seed when creating our api object. This seed will be used by the function when generating addresses. Also notice that get_new_addresses() is a deterministic function, meaning that we need to provide a unique index to the function each time to make sure we don’t generate the same address twice. There may be different methods for providing a unique index to the function, such as timestamps etc. In my example, i simply use a counter that is incremented by 1 for each payment.
- Generate and display new QR code
Next, we take the new address and send it to our QR code generator. Notice that when making IOTA payments we have to include a checksum with the payment address. So before sending our address to the QR code generator we add the checksum to the address by using the with_valid_checksum() function.
- Check address for transactions
Next, we start looking for incoming payments to our address. As soon as a new transaction has been added to our address, we know that an incoming payment is on the way.
- Hide QR code
Next, we hide the QR code from our GUI to prevent new payments being sent to the same address while the first transaction is waiting to be confirmed. In my example i’m replacing the QR code with a message indicating that a new payment has been detected and that we are waiting for the payment to be confirmed.
- Get address balance
Next, we start checking our address for a positive balance, meaning that the transaction (payment) detected in step 3 has been confirmed.
- Add time to lightbalance
As soon as a positive balance has been detected, we take the new IOTA balance and convert it to time according to the current time/USD price. We finally add the calculated time to our current light balance and the process repeats itself.
There are no additional components required with respect to the previous tutorial.
Required Software and libraries
There are no additional software or libraries required with respect to the previous tutorial.
The Python Code
Now let’s have a look at some of the new functions that has been added to the Python code since the previous tutorial.
The most important change is of course that we no longer have a fixed payment address where all of our payments are collected. Instead we generate a new address for each payment. For this reason we now have to provide a seed to the IOTA address generator. So make sure you replace the seed in the Python code with your own seed. See here to learn more about creating IOTA seeds.
The index counter
A new read/write index counter function has been added to make sure we keep track of the latest address index used in case of a power failure etc. The index counter function uses the Python configparser library that stores data as a text file with the .ini format. Make sure you download and place the “let_there_be_light.ini“ file in the same folder as your Python program, otherwise you will get an error. You can download the file from here.
The waiting icon
To prevent the user from making multiple payments to the same IOTA address, we temporarily replace our QR code with an hourglass icon as soon as a new payment has been detected. Notice that the pyQRcode library uses the TkInter BitmapImage function when rendering our QR code to the GUI. This function uses a special graphics file format called XBM, meaning that we can not use our typical graphics formats such as bmp, jpg, png etc. However, in case you want to create your own icon, there are applications and online services that allows you to convert your typical graphics formats to XBM. To prevent any errors when using my Python example code, make sure you download and place the “hourglass.xbm” file in the same folder as your Python program. You can download the file from here.
As discussed earlier, we want to have the flexibility of easily changing the price of our service whenever appropriate. For this reason i have created the lightprice_USD variable that is read at startup of our Python program. The lightprice_USD variable is also used when converting our USD service price to IOTA’s. To change the price of your service, simply update the lightprice_USD variable to whatever value matches the price of your service. Notice that lightprice_USD is a floating number and that the price is in USD pr. minute of service.
You can download the Python source code from here
Running the project
To run the project, you first need to save the code in the previous section as a text file on your Raspberry PI.
Notice that Python program files uses the .py extension, so let’s save the file as let_there_be_light_addr.py on the Raspberry PI.
To execute the program, simply start a new terminal window, navigate to the folder where you saved let_there_be_light_addr.py and type:
You should now see the GUI appear on your LCD/Monitor, showing a QR code for the automatically generated IOTA payment address. As soon as one payment has been confirmed, a new address will be generated and displayed in the GUI. To exit the Python program you simply press the Exit button.
Make sure you download and place the “iota_logo75.jpg” file in the same folder as your python file before executing the program, otherwise you will get an error. The logo file can be downloaded from here.
Pay the light
To turn on the LED (or in my case, set the Light is ON status) you simply use your favorite mobile IOTA wallet, scan the QR code displayed in the GUI, and transfer some IOTA’s. As soon as the transaction is confirmed by the IOTA tangle, the LED should light up (or in my case, set the Light is ON status), and stay on until the light balance is empty, depending on the amount of IOTA’s you transferred.
If you like this tutorial and want me to continue making others, feel free to make a small donation to the IOTA address shown below.