For people who are new to IOTA, the address system might seem very confusing at first. To lift the confusion, the following will cover all specialties about IOTA addresses you need to know.
Non reusable addresses
Contrary to traditional blockchain based systems such as Bitcoin, where your wallet addresses can be reused, IOTA's addresses should only be used once (for outgoing transfers). That means there is no limit to the number of transactions an address can receive, but as soon as you've used funds from that address to make a transaction, this address should not be used anymore. The reason for this is, by making an outgoing transaction (if you send IOTAs) a part of the private key of that specific address is revealed, and it opens the possibility that someone may bruteforce ("hack") the full private key to gain access to all funds on that address. The more outgoing transactions you make from the same address, the easier it will be to bruteforce the private key. It should be noted that having access to the private key of an address will not reveal your seed or the private key of the other addresses within your seed / "account".
So again in short: It is safe to receive any number of transactions to a given address until an outgoing transfer (a "send" transfer) is made. After that, this address should no longer be re-used!
Perhaps you are now wondering: "What if I make a payment to someone; do I need to worry about the safety of the rest of my IOTAs?" The answer would is no, the wallet takes care of everything automatically and your tokens remain absolutely safe. We will dive into the details of this later.
When a new address is generated it is calculated from the combination of a seed + Address Index, where the Address Index can be any positive Integer (including "0"). The wallet usually starts from Address Index 0, but it will skip any Address Index where it sees that the corresponding address has already been attached to the tangle.
What “attached to tangle” means
The process of making an transaction can be divided into two main steps:
1. The local signing of a transaction, for which your seed is required.
2. Taking the prepared transaction data, choosing two transactions from the tangle and doing the POW. This step is also called “attaching”.
The following analogy makes it easier to understand:
Step one is like writing a letter. You take a piece of paper, write some information on it, sign it at the bottom with your signature to authenticate that it was indeed you who wrote it, put it in an envelope and then write the recipient's address on it. Step two: In order to attach our “letter” (transaction), we go to the tangle, pick randomly two of the newest “letters” and tie a connection between our “letter” and each of the “letters” we choose to reference. The “Attach address” function in the wallet is actually doing nothing else than making an 0 value transaction to the address that is being attached.
Why addresses are attached to the tangle
When generating an address in the wallet we should always attach it to the Tangle before using it. The reason for this is that the wallet doesn’t save any account data locally, but instead gets all necessary data from the Tangle. As such, if an address isn't attached to the Tangle, it can safely receive IOTAs but you wouldn't necessarily see the balance in your account because the wallet might not associate it with your account. Now here is where it gets a bit more sophisticated if we want to fully understand this, so incase you don't want to dig in deeper, feel free to skip to the next section.
The interesting thing is, if we make a transaction to an address that wasn’t attached to the Tangle yet, the address will automatically be attached through that transaction. But why do we need to attach addresses at all, if they get attached automatically when receiving an transaction? As we have already learned, addresses are generated with an Address Index which starts at 0. Now when the wallet looks for associated addresses in the tangle, it will start by looking for the address at index 0. If it finds a match, it will continue to look for an address at index 1 and then for index 2, 3, etc. until it does not find a matching address to the index number. Let's assume address 0, 1, 2 and 3 are attached, address 4 isn't and address 5 is attached again with some balance on it. The wallet would stop searching for associated addresses in the tangle after it doesn’t find address 4 and as such would not see the balance of address 5. In order that such gaps can't happen we need to attach an address to the tangle before the wallet allows us to generate a new address.
The wallet's address management
The wallet in the animation above starts with a balance of 174 IOTA and then sends 24 IOTA to Bob. The transaction deducts all 174 IOTAs from the first address of our seed / "account" and, after splitting them, sends 150 IOTA to the next address within our account, while the other 24 IOTA get sent to Bob's address. This way it is ensured that the first address, which is now considered used, is left with a balance of 0, while the new address now holds the rest of the balance. The same thing happens with the next transaction, where 60 IOTA are sent to Alice.
What happens after a snapshot
Now that we know how addresses are used by the wallet, we can also learn why the balance appears to drop to 0 after a snapshot. When a snapshot happens, all transactions are being deleted from the Tangle, leaving only the record of how many IOTA are owned by each address. For example, if a snapshot was made after the transaction to Alice, the snapshot would record that address "EJMQH…" has 90 IOTA. However, the next time the wallet scans the Tangle to look for used addresses, the transactions will be gone because of the snapshot and the wallet will not know anymore that address "EJMQH…" belongs to it. This is the reason for the need to regenerate 3 addresses (address index 0, 1 and 2) in the example so that the wallet can check the balance of each address. The more transactions were made before a snapshot, the further away the balance moves from address index 0 and the more addresses have to be (re-) generated after the snapshot.