Skip to content

State

A blockchain is a sequence of diffs applied to some initial state. In fact, it may be more intuitive to conceive of blockchains as "statechains", since the state is, in a sense, "what the network is reaching consensus on."

For example, the network needs to agree on which chain has the most Work. This can be calculated by adding up the difficulty of every block in the chain. Thus, we have an initial piece of state (work = 0) to which we apply diffs (work += difficulty). The same principle applies to each other piece of state. What we call "the state" (or sometimes "consensus state") is simply the set of all such values that are necessary to perform Block validation and application. This comprises the following fields:

  • Index: The height and ID of the current block. One of the primary uses of this is to implement hardforks, which activate at particular heights.
  • PrevTimestamps: The timestamps of the 11 previous blocks. This is used to implement the median timestamp rule.
  • SiafundTaxRevenue: The sum of taxes on all file contracts. This is used to calculate the value of siafund dividends.
  • Attestations: The total number of Attestations in the chain. This enables trustless downloads of the attestation set.
  • The Foundation subsidy address.
  • Proof-of-work values, including the Difficulty, TotalWork, OakTime, and OakWork.
  • Elements: The Element Accumulator, a cryptographic data structure that "contains" all Outputs and File Contracts, among other things.

In most blockchain implementations, the state is somewhat amorphous, singular, and ambient. That is: the system does not explicitly define what the state is; the system only stores one state at any given time; and the system permits global access to the single state. All of these are consequences of the fact that their state is simply too large. Specifically, their UTXO set is too large, often multiple GB in size. Sia represents its UTXO set as a cryptographic accumulator that occupies around 1 KB.

Making state explicit reveals its true size. For example, in Sia v1, an output was automatically created whenever a file contracts expired. This meant that all unresolved file contracts were part of the state, just like all unspent siacoin and siafund outputs. Furthermore, a contract's storage proof index was chosen using entropy derived from a block ID prior to the contract's proof window; since the window could begin at any height, this implies that the state must also contain every block ID. In v2, both of these rules are implemented via Merkle proofs and can therefore be omitted from the state. A secondary benefit of this is that the amount of "work" performed by a node in response to a block is always proportional to that block, unlike v1 where a single block could trigger an unbounded amount of "maintenance" (such as contract expiration or output maturation).

Though it is more common to speak of the "genesis block," the existence of such a block implies a genesis state to which the block is applied. The genesis state has mostly zero-valued fields, but does specify an initial difficulty.

In v1

Like many blockchain implementations, Sia v1 lacked an explicit state type, instead defining a separate type of block augmented with state metadata.

Of course, the biggest difference was that v1 tracked the UTXO set with a database instead of an accumulator.