IOTA is a protocol designed for use by IoT devices. These devices will happily follow any rules to use the protocol strictly, optimally and safe. Sadly, humans are not so good at following rules -if they know them at all- and they often have no idea of the consequences of certain actions. So I decided to write a list of best practices and explain the why in this article.
Here are the rules:
RULE 1: NEVER re-use an address. NEVER. NO exceptions.
RULE 2: ALWAYS attach a new receive address to the Tangle.
RULE 3: ALWAYS wait for a transaction to be confirmed before sending anything else.
And here are the whys:
It all has to do with multi-spending. Which is spending more than once from the same address. The problem here is that IOTA uses one-time signatures. After spending addresses are not supposed to be used any more because in the process of spending a random 50% of the private key to the address gets exposed. This in itself is not a problem, any funds arriving after a single spend are still pretty safe. Breaking the other 50% of the key is still a daunting task.
But when a second spend happens on the same address a new random 50% of the private key for that address gets exposed. Theoretically, statistics will tell you that now 75% of the private key is exposed. But here is the difference between theory and practice. Since it is a *random* 50% of the key that gets exposed, you could be unlucky enough that both 50% exposures only have a 10% overlap. In which case a whopping 90% of your key is exposed already! In which case your private key is toast and broken relatively easy.
So in short: 2 or more spends from the same address is VERY BAD!
Now let's see what scenarios could occur that will end up in a multi-spend and why these rules are good:
RULE 1: NEVER re-use an address. NEVER. NO exceptions.
I can immediately hear some people say: "But you are allowed to receive multiple times at a address!" And they are technically correct. IoT devices will do this all the time. But they have the advantage of knowing exvactly what the parties they are talking to are going to do and when. So they can safely do this. Here is a scenario that shows just one example of why it is a bad idea to send multiple times to the same address:
Let's say I withdraw X iotas from an exchange to address A in my wallet. The whole process takes a little time, but I end up with X iota in address A.
Encouraged by this success I decide to withdraw another Y iotas to that same address A. After all, I can send *to* an address multiple times, right? So I put in the order and the exchange starts processing the order. Note that this processing can sometimes take hours or even days.
In the mean time I tell my friend about IOTA, and to encourage him I want to send him a few (let's say Z) iotas. So he installs the wallet and gives me a receive address B. I tell the wallet to send Z iotas to address B. The wallet happily obliges and takes the iotas in address A, sends Z iotas to address B, and -to guard address A from multi-spending- it also sends the remaining X - Z iotas safely to a newly generated address C in my wallet.
Everything seems okay so far. But with one problem: The exchange did not process my withdrawal yet. When it finally does process it, the Y iotas will be sent to address A just like I instructed. Except that address now already has an earlier spend on it! Oops!
This situation could have been simply avoided by generating a new address D for the second withdrawal and using that instead of address A.
So case in point: NEVER re-use an address. Not even for receiving.
RULE 2: ALWAYS attach a new receive address to the Tangle.
I can immediately hear some people say: "But you don't really *have* to do this!" And again, they are technically correct. It is perfectly fine to send iotas to an address that was not attached to the Tangle explicitly. They will arrive just fine. Again, IoT devices do this all the time, but they also keep track of what addresses they gave out as receive addresses.
The IOTA wallet does it differently. Because it is possible to install the wallet on different devices, and log in both wallets with the same seed, the developers are determining the state of the wallet directly from the Tangle. That way both wallets will respond the same to events. Otheriwse one could have kept track of some important addresses and the other would have no knowledge of that. Pretty elegant solution.
But this solution comes with a hidden cost. To understand this we need to look at how the wallet decides which addresses have been used already. It does that by asking the node it is connected to for a list of transactions that incorporate that address. If there are no transactions yet it concludes that it has not used the address yet.
By attaching an address to the Tangle you explicitly create a zero-transfer transaction for that address. Now the wallet can find that transaction in the Tangle, so it knows it is in use already. And yes, in case someone sends iotas to that address, the wallet can find that transaction in the tangle and again sees that it is in use already. Therefore we don't need to explicitly attach it, right? Bzzzzt! *Wrong*!!
Let's say I have X iotas in address A. I decide to withdraw another Y iotas from the exchange to address B. That's what I learned from rule 1. Use a different address. I don't bother explicitly attaching address B to the Tangle, because I was told before that that was not strictly necessary. So I put in the order and the exchange starts processing the order. Which again takes time.
To spread more joy I decide to send Z iotas to my friend again. I initiate the transfer, and this time the wallet can take from address A, send Z iotas to my friend's address, and then it wants to send the remaining X - z iotas to a new receive address. So it looks in the tangle which address is not in use already. Aha! Address B is not used yet. So it merrily sends the results to address B. Oh dear. Now we are in the same situation as we were in with rule 1.
So if we now decide to send another amount of iotas to another friend, we will be spending address B before the withdrawal *to* address B has executed. And we end up with a guaranteed multi-spend again.
This situation could have been simply avoided by explicitly attaching address B to the Tangle. In which case the wallet would have seen it was in use already, and it would have sent the remainder to a new address C instead.
So case in point: ALWAYS attach a new receive address to the Tangle.
RULE 3: ALWAYS wait for a transaction to be confirmed before sending anything else.
I can immediately hear some people say: "But the wallet will keep me from multi-spending!" And again, they are technically correct. The wallet will check before spending if there already has been a confirmed spend on the address, and won't allow a second spend in that case. But consider the following scenario:
I have X iotas in address A. I now decide to send Y iotas to an exchange. This will generate a transaction #1 spending Y iotas from address A.
Now I also decide to send my friend his Z iotas before transaction #1 has been confirmed. Since the wallet still sees the X iotas in address A it will happily generate transaction #2 spending Z iotas from address A. Oops! Two spends from the same address.
This situation could have been simply avoided by waiting for transaction #1 to be confirmed before sending transaction #2.
So case in point: ALWAYS wait for a transaction to be confirmed before sending anything else.
Note that a lot of these situations are even muddier because you have no idea what address(es) the wallet is going to pick as input(s) for sending iotas somewhere.
Also note that I only provide one example of where things can go wrong for each rule. Things become even muddier when snapshots happen. But that is something for another article.