Skip to main content
Version: 2.0.0

Casper Network Design

Introduction

Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a transaction. Transactions may contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

A transaction executes in the context of the user's Account but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an Unforgeable Reference or URef. After a node accepts a transaction as valid, it places the transaction in a proposed Block and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction.

  1. Execution Semantics

  2. Accounts

  3. Unforgeable Reference (URef)

  4. Block Structure

  5. Tokens

Execution Semantics

A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model.

Measuring Computational Work

Computation is done in a WebAssembly (Wasm) interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses Gas to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a Gas cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter.

Costs for opcode instructions on the Casper Mainnet network can be found here.

All executions are finite because each has a finite gas limit that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction.

Although the network measures costs in Gas, payment for computation occurs in motes. Therefore, there is a conversion rate between Gas and motes.

note

Casper networks support configurable fee, refund, and pricing strategies to incentivize the Casper Runtime Economics by efficiently allocating computational resources. The consensus-before-execution model implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions.

The Casper Network Runtime

A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state.

Casper Network Runtime

All these features are accessible via functions in the Casper External FFI.

Generating URefs

URefs are generated using a cryptographically secure random number generator using the ChaCha algorithm. The random number generator is seeded by taking the blake2b256 hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same transaction).

Generating URefs

Accounts

The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The global state trie store requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants.

The Casper platform supports two types of keys for creating accounts and signing transactions:

  • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
  • Secp256k1 keys, commonly known as Ethereum keys, which are 68 bytes long

By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see Tokens for more information).

This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts.

Creating an account

Account creation automatically happens upon transferring tokens to a yet unused PublicKey. On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the PublicKey used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse.

Account Data Structure

An Account contains the following data:

Permissions Model

Actions and Thresholds

An account can perform two types of actions: sending transactions and managing keys. A transaction is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a transaction; therefore, a key management action implies that a transaction is also taking place.

The ActionThresholds contained in the Account data structure set a Weight, which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a transaction, the key management threshold should always be greater than or equal to the transaction threshold.

Associated Keys and Weights

Addressable entities on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An addressable entity's associated keys are the set of public keys allowed to provide signatures on transactions for that entity. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each transaction must be signed by one or more keys associated with the entity that transaction is for, and the sum of the weights of those keys must be greater than or equal to the transaction threshold weight for that account. We call the keys that have signed a transaction the "authorizing keys". Similarly, if a transaction contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the entity.

note

Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.

Key Management Actions

A key management action is a change to the account permissions, including:

  • Adding or removing an associated key
  • Changing the weight of an associated key
  • Changing the threshold of any action

Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys.

Account security and recovery using key management

This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign transactions from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the transaction threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone.

note

It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").

The Account Context

A transaction is a user request to perform some execution on the blockchain (see Execution Semantics for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity's context.

note

In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity.

Unforgeable Reference (URef)

This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

Permissions for URefs

In the runtime, a URef carries its permissions called AccessRights. Additionally, the runtime tracks what AccessRights would be valid for each URef in each context. The system assumes that a sent URef is invalid, regardless of declared AccessRights, and will check it against the executing context to determine validity on each usage. Only the host logic can add a URef, in the following ways:

  • It can exist in a set of "known" URefs
  • It can be freshly created by the runtime via the new_uref function
  • For called contracts, the caller can pass it in via the arguments to call_contract
  • It can be returned to the caller from call_contract via the ret function

Note that only valid URefs may be added to the known URefs or cross-call boundaries; this means the system cannot be tricked into accepting a forged URef by getting it through a contract or stashing it in the known URefs.

The ability to pass URefs between contexts via call_contract / ret, allows them to share state among a fixed number of parties while keeping it private from all others.

URefs and Purses

Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual entities do not own ‘URef’s. As described above, entities possess certain Access Rights, allowing them to interact with the given URef. While an account entity will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required.

Block Structure

A block is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure.

Data Fields

A block consists of the following:

  • A block_hash
  • A header
  • A body

Each of these fields is detailed in the subsequent sections.

block_hash

The block_hash is the blake2b256 hash of the block header.

The block header contains the following fields:

  • parent_hash

    A list of block_hashes giving the parents of the block.

  • state_root_hash

    The global state root hash produced by executing this block's body.

  • body_hash

    The hash of the block body.

  • random_bit

    A boolean needed for initializing a future era.

  • accumulated_seed

    A seed needed for initializing a future era.

  • era_end

    Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field.

  • timestamp

    The timestamp from when the block was proposed.

  • era_id

    Era ID in which this block was created.

  • height

    The height of this block, i.e., the number of ancestors.

  • protocol_version

    The version of the Casper network when this block was proposed.

Body

The block body contains an ordered list of transaction hashes. All transactions, including mint, auction, install_upgrade and standard transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no transactions.

The block body also contains the public key of the validator that proposed the block.

Refer to the Serialization Standard for additional information on how blocks and transactions are serialized.

Tokens

Casper is a decentralized Proof-of-Stake blockchain platform that may use either the Highway or Zug consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

This chapter describes tokens and how one can use them on the Casper platform.

Token Generation and Distribution

A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available here. In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage.

The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis.

Token Lifecycle

Divisibility of Tokens

Typically, a token is divisible into some number of parts. We call the indivisible units which make up the CSPR token motes. Each CSPR is divisible into 109 motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 1018 parts called Wei.

The concept of CSPR is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with motes.

Purses and Addressable Entities

All entities on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the source and the main purse of the account entity at the provided key as the target.

The Casper Mint Contract

The Casper mint is a system contract that manages the balance of motes within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's main purse. Each balance is associated with a URef, which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as purses and conceptually represent a container for motes. The URef is how a purse is referenced externally, outside the mint.

The AccessRights of the URefs permissions model determines what actions can be performed when using a URef associated with a purse.

As all URefs are unforgeable, the only way to interact with a purse is for a URef with appropriate AccessRights to be validly given to the current context.

The basic global state options map onto more standard monetary operations according to the table below:

Global StateAction Monetary Action
AddDeposit (i.e. transfer to)
WriteWithdraw (i.e. transfer from)
ReadBalance check

The mint Contract Interface

The mint system contract exposes the following methods:

  • transfer(source: URef, target: URef, amount: Motes) -> TransferResult
    • source must have at least Write access rights, target must have at least Add access rights
    • TransferResult may be a success acknowledgment or an error in the case of invalid source or target or insufficient balance in the source purse
  • mint(amount: Motes) -> MintResult
    • MintResult either gives the created URef (with full access rights), which now has a balance equal to the given amount; or an error due to the minting of new motes not being allowed
    • In the Casper mint, only the system account can call mint, and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account
  • create() -> URef
    • a convenience function for mint(0) which cannot fail because it is always allowed to create an empty purse
  • balance(purse: URef) -> Option<Motes>
    • purse must have at least Read access rights
    • BalanceResult either returns the number of motes held by the purse, or nothing if the URef is not valid