One of the most important aspects of any blockchain is the wallet creation algorithm. The wallet creation algorithm defines how public and private keys will be created as well as how much space is required for storage.
At Contractless we decided to use the same algorithm as is used by Bitcoin. The algorithm is called secp256k1. I won't get into the tech details of how it works but I will say it generates a public key that is 33 bytes (66 characters) and a signature that is 64 bytes (128 characters).
Wallet addresses can vary based on the blockchain and how they are created. For example bitcoin has 2 wallet address sizes that use secp256k1. One wallet type is 42 characters in length and the other is 62.
We handled our wallet address creation process different than the way other chains do. We used a method called XOR encoding. We took the public key, and encoded it with XOR using the public key length as that XOR key when encoding.
If you have no idea what XOR encoding is, that's okay as its not so important to this discussion. All thats important it that it is an encoding (think for example base64), it produces an encoded output that is exactly the same length as the input (33 bytes), and it can easily be decoded back to its original form.
The reason this is so important is that each of these values, take up space in a blockchain. On a typical blockchain, every transaction needs to have a wallet address, a public key, and a signature. The private key is used to sign the data and create a signature. That signature can then be verified using the public key to ensure the data is valid, has not been tampered with, and was created by a specific wallet address.
So a typical blockchain transaction would include a public key, 33 bytes in out case; a signature, 64 bytes in our case, and a wallet address of undisclosed size. As such every transaction will always be a minimum of 97 bytes + the wallet address size.
We handled this differently at Contractless. In order to create our wallet address as we explained already we encoded our public using XOR. This means our wallet addresses are 33 bytes. This also means we do not have to include the public key in our transactions, saving us 33 bytes on every transaction included in a block.
The reason we don't need to included the public key is that by having our wallet address be XOR encoded public keys, we can always decode them to get the original public key from the address, without having to include both.
You can find how the XOR encoding works to create the wallet address in the generate_wallet function of the Wallet Creation Code and you can see how it is extracted from the wallet address during the verification process by checking the decode_address function in the Signing and Verifying Transactions.