This Developer Guide aims to provide a technical reference and all the information you need to understand Elixium and start contributing to Elixium or to build Elixium-based applications, but is not a Decentralized Application Development Guide, and is also not a specification. This guide is best supplemented by having the Elixium Core Source installed locally.

Questions about Elixium development are best asked in the Telegram Channel. Errors or suggestions for this documentation can be submitted as an issue.

In the following documentation, some strings have been shortened or wrapped: “[…]” indicates extra data was removed, and lines ending in a single backslash “\” are continued below.

Block Chain Overview

Basic Blockchain Overview

The diagram above shows a simple representation of a block chain. Transactions are grouped together into a block, hashed, then paired together and hashed continuously until a merkle root representing the transactions is calculated.

This merkle root is part of the block header, along with the index of the block, the timestamp of the block, a nonce, the block’s version, and the hash of the previous block’s header.

Because each block contains the hash of the block before it in its header, blocks are interlinked with all previous blocks. Consequently, since the merkle root of a blocks transactions are stored in the block header, if any transaction within the block is changed, the merkle root will change, which will change the hash of the block’s header. Changing the block’s header will also change the headers of all the blocks following.

Transactions are also chained within blocks. Elixium wallet software may give the illusion that elixir is sent from one wallet to another, or that an address may have a balance associated with it, but really elixir is transferred through transactions. Each transaction spends elixir that was previously received in one or more previous transactions, i.e the output of one transaction will be used as an input in a future transaction.

Transaction Chaining Diagram

Every transaction can create multiple outputs, such as when creating a transaction to send elixir to multiple addresses. Each output of any given transaction can only be used as an input to a transaction one time in the entire blockchain – using the same output as an input in multiple transactions is invalid as this is an attempt to spend the same elixir; this is classified as a double spend.

Outputs are directly tied to the transaction they are created in – each output has a TXOID which ID of the transaction followed by its index in the transaction’s outputs. An output that is at index 5 of the output list within a transaction with the hash “9B96A1FE1D548CBBC960CC6A0286668” would have the TXOID of “9B96A1FE1D548CBBC960CC6A0286668:5”.

Since each output can only be spent once (used as an input once), each output must be spent in full. An output with the value of 5 elixir can not be used as an input once to use 3 elixir and then used as an input again to spend 2 elixir in another transaction. This leads to a classification of two different types of outputs: unspent transaction outputs (UTXOs) and spent transaction outputs. A transaction is only valid if it solely consists of UTXOs as inputs.

Transaction fee calculation

Excluding Coinbase transactions, if the value of a transactions outputs exceeds the value of its inputs, the transaction is invalid and will be rejected. If the value of a transactions inputs exceeds the value of its outputs, the difference will be claimed by as a mining fee by the miner who includes the transaction into a block.

Block Encoding

Block Binary Encoding

Block headers are 218 bytes total. Blocks are encoded into binary format when they are stored on disk, and having a fixed-size header is necessary for enforcing a maximum block size limit; if header size is constant, it is easy to deduce the remaining capacity for transaction data within a given block.

Blocks are encoded in the same way as the above image, where each attribute is combined together with no separating flags. This is because there is an order in which blocks must be encoded; index, hash, previous hash, merkle root, timestamp, nonce, difficulty, version, followed by transaction data.

The block index is represented as 4 bytes, which provides a maximum possible index of 4294967295. At an average of 2 minutes per block, it would take 16,343 years to reach the maximum index, therefore 4 bytes is more than enough to represent index.

Hash, previous hash, and merkle root are all 32 bytes, as the result of SHA256 provides us a 32 byte hash.

Timestamp is 4 bytes, which successfully represents a UTC unix timestamp.

Nonce values will always be an integer. We only use 8 bytes (representing up to the integer 18446744073709551615) to represent a nonce – if a nonce lapses over 8 bytes, a miner can allow it to overflow and instead update the blocks timestamp.

The maximum value for difficulty can be 16^64, and difficulty can not be negative. Difficulty is stored in 8 bytes according to the IEEE float specification.

The block version is stored in 2 bytes, which allows us to specify up to version 65535.

All data following these fields is treated as transaction data.

Proof of Work

The block chain is a distributed public ledger maintained by anonymous peers on the network. In order to protect against malicious peers from adding to or modifying the blockchain at will, Elixium requires that each block is crafted by expending a significant amount of computing power, and by extension electricity. This means that blocks can not be created instantaneously, and forces malicious actors to have to expend more computing power to modify past blocks than honest nodes which are just adding new blocks to the chain. This disincentivizes malicious behavior by making it expensive to run attacks against the network, and helps prevent against sybil attacks.

Chaining blocks together makes it impossible to modify any part of a transaction or block without modifying all subsequent blocks, meaning that it becomes more computationally expensive to modify a given block as more blocks are added to the chain after it.

Nodes on the network will always build on the chain with the most computation expended on it. This is not the chain with the most blocks, but rather the chain with the highest cumulative difficulty – a long chain can easily be created when mined at a low difficulty, but when a chain is both long and has been mined at a high difficulty, it can be inferred that the majority of the network’s hashing power has been expended mining on this chain, and this chain is the most secure.

Difficulty is calculated using the WWHM (Weighted-Weighted Harmonic Mean) difficulty algorithm. The target solve time in Elixium is set to be 120 seconds, so every 2 minutes, on average, a new block will be mined. Before each block is mined, it’s difficulty is calculated by finding the cumulative difficulties and weighted cumulative solve times of the previous 60 blocks, and then solving for difficulty (D’) where T is target solve time, W is weighted solve times, and D is cumulative difficulties in the following equation:

D' = D / (61 / 2 * T) * W

Difficulty is used to maintain the creation of new blocks to the target solve time regardless of network hashrate fluctuations – blocks should take 2 minutes to mine whether there are 10 nodes on the network or 10,000. If the hashrate of the network increases, the difficulty will scale accordingly. The same is true in the case of a network hashrate decrease.

Nodes will only accept blocks if their hash was at least as challenging as the blocks difficulty (which every node will calculate when receiving the block). Because each block header must hash to a target threshold, and because each header must contain the hash of the header of the block that preceded it, it requires (on average) as much hashing power to propagate a modified block as the entire Elixium network expended between the creation of the original block and the current time. An attacker who holds 51% or more of the hashing power of the network can execute such an attack where they can modify an existing block and outpace the rest of the network to become the most computationally secure chain.

Since cryptographic hash functions are deterministic, meaning that given the same input they will always produce the same output, the same block header will always produce the same hash. In the process of mining, the miner is looking to calculate a hash that is below a certain target threshold that is defined by the block’s difficulty, but if the block header does not change, the miner will always get the same hash and will likely not get a satisfactory hash. Because of this, the block header consists of a nonce value that can be freely modified in order to generate different hashes. The block header is also fixed in size. Since hash functions take longer to complete when given a larger input, and since the transactions of a block must all be represented in the header, miners would be disincentivized from including large amounts of transactions in their blocks as each hash cycle would take longer than if they had included minimal transactions in their block. In order to set an equal time per cycle, transactions are represented within the header as a fixed size merkle root which need only be calculated once.

Token Emission

Block rewards in Elixium are determined by a smooth token emission algorithm. Rather than distributing elixir in a logarithmic fashion (such as in Bitcoin), Elixium block rewards scale down smoothly over time. Elixium will have a total of 1 billion tokens in existence after the token emission period.

With a target emission period of 2,628,000 blocks (~ 10 years), we determine the block reward for any given block with the following equation, where X is total token supply, T is emission period (in blocks), I is block index, and S is the sigma of the total token supply:

BLOCK_REWARD = (X * max(0, T - I)) / S