Think about your seed as the combined username and password that grants access to your bank account. If anyone obtains your seed, they can login and access your funds.

You must generate a random 81 character seed using only A-Z and the number 9. It is imperative that your seed be an 81 character random assortment of A-Z and 9. Use one of the options below to generate your seed:

Depending on your operating system, you can use onboard tools to generate such a seed:

Windows

Linux
cat /dev/urandom |tr -dc A-Z9|head -c${1:-81}

Mac
cat /dev/urandom |LC_ALL=C tr -dc ‘A-Z9’ | fold -w 81 | head -n 1

 

Basics of Generating Addresses

The starting point for generating an address is obviously your seed, which is a unique 81-char string that is the “master unlock key” for your personal account. From a seed you derive a private key at a specific key index which you then in turn use to get the actual address.

Lets Do it! Generate an address

var seed = 'ABCDEFG';
var options = {}
iota.api.getNewAddress( seed, options, function( error, address ) {
    console.log(address);
    // Address:
});

As you can see, we’re generating an address from the seed ABCDEFG. The address, with no options that we get returned is:

LZQOPWMHGGGDBDGWRKABFSARXDBSNPAWK9FYFZKODVEWVNPKLQXNTUOKBCBQTLGUENHZDVKLNIZKMNGOL

It’s a 81-char (trytes, is more correct) address. As you can see, we’ve not supplied any options to the getNewAddress function. If we look at the documentation, there are several options that we can supply to better control the address generation process:

  • index: `Int` If the index is provided, the generation of the address is not deterministic.
  • checksum: `Bool` Adds 9-tryte address checksum
  • total: `Int` Total number of addresses to generate.
  • security: `Int`  Security level to be used for the private key / address. Can be 1, 2 or 3
  • returnAll: `Bool` If true, it returns all addresses which were deterministically generated (until findTransactions returns null).

Lets take a look at these options and provide some more context.

What is the key index?

‍As previously mentioned, when generating an address you need to know the key index of the private key in order to get the same address each time. The libraries give you two options in order to get that key index: one is to supply it as an optional input parameter, the other is to get it deterministically. Lets look at the first option.

var seed = 'ABCDEFG';
var options = {
    index: 1
}
iota.api.getNewAddress( seed, options, function( error, address ) {
    console.log(address);
    // Address:
});

The same seed with index 1 generates the address:

9AMLQAQURNSXWHCMZYDTSSXKF9M9EIFERLHJRNTKYYRTFFWGRPNCWSCCHOBQTQX9UBKMDASIKCYSPSNI9

They key index, starting from 0, is simply incremented in order to get a new private key, which in turn generates a new address. By supplying the index yourself, you are able to generate a new address on any key index you prefer. Keep in mind that this leaves the key management to you. IOTA uses winternitz one-time signatures, as such you should ensure that you know which private key (and which address) has already been used in order to not reuse it.

Why generate addresses “deterministically”?

‍Because of the security concerns associates with re-using private keys for addresses and signatures, the library makes it easy to deterministically generate addresses. This way you can easily keep track of the addresses that you’ve already used and get a new address each time you use the getNewAddress API call.

The way the library does this, it makes use of findTransactions to figure out if there is any address in the Tangle that has already been used. If findTransactions returns associated transactions, the key index is simply incremented, a new address generated and findTransactions called again until it returns null. Fairly simple, but effective.

Because of this, we encourage users to “attach” their address to the Tangle in order to increment the counter and get a new address the next time you want an address. Below is an example code that shows you how attaching to the Tangle looks like.

var seed = 'ABCDEFG';
var options = {
    index: 1
}
iota.api.getNewAddress( seed, options, function( error, address ) {
    // We attach the address to the tangle with an empty message transaction 
    var transfer = [{
        address: address,
        value: 0,
        message: '',
        tag: ''
    }]
    // Depth for the tip selection
    var depth = 4;
    // If we're on the mainnet, minWeightMagnitude is 18
    var minWeightMagnitude = 18;
    // Call the sendTransfer API wrapper function 
    // It takes care prepareTransfers, attachToTangle, broadcast and storeTransactions
    iota.api.sendTransfer( seed, depth, minWeightMagnitude, transfer, function( e, attached ) {
        if (!e) {
            console.log("Successfully attached your transaction to the Tangle with transaction", attached);
        }
    })
});

Key security option

‍IOTA gives you the options of choosing your own security level for your private keys. This means that you have can choose between low, mid and high tier security levels, which in turn means varying computational effort and transaction sizes when generating signatures. There are 3 security levels:

  • Security Level 1: 81-trit security
  • Security Level 2: 162-trit security
  • Security Level 3: 243-trit security

Technically speaking, a single seed has 3 accounts. The same key index on a different security level returns a completely different address. Make sure you keep track of your security levels similarly to your key indexes, as it will be needed for spending your inputs.

Address checksums and why they’re useful

As an additional security measure, we make it possible to use address checksums. A checksum is basically an additional 9-trytes which can be used to validate the integrity and validity of the address. The getNewAddress API function makes it possible to directly return checksum’ed addresses. In combination with the utility functions addChecksumnoChecksum and isValidChecksum you have a great set of functionality to secure and validate addresses.

var seed = 'ABCDEFG';
var options = {
    index: 1,
    checksum: true
}
iota.api.getNewAddress( seed, options, function( error, address ) {
    console.log(address);
// 90-tryte address 
})

The above function will return the 90-tryte address (81-trytes for the address itself and 9-trytes for the checksum.

9AMLQAQURNSXWHCMZYDTSSXKF9M9EIFERLHJRNTKYYRTFFWGRPNCWSCCHOBQTQX9UBKMDASIKCYSPSNI9Y9WFPBMPP