Skip to content
Gav Wood edited this page Nov 14, 2017 · 10 revisions

Welcome to the polkadot-spec wiki!

Polkadot is primarily described by the Relay chain protocol; key logic between parachain protocols will likely be shared between parachain implementations but are not inherently a part of the Polkadot protocol.

Relay chain

The relay chain is a proof-of-stake blockchain in a similar balance/nonce mould to Ethereum, backed by a Web Assembly (Wasm) engine.

State & Transition Function

Its state is roughly similar to Ethereum: accounts contained in it are a mapping from a U64 account index to code (H256, a SHA3 of Wasm code) and storage (H256, a Merkle-trie root for a set of H256 to U8[] mappings). All such accounts are actually known as "high accounts" since their ID is close to 2**64 and, notionally, they have a "high" privilege level.

state := U64 => [ code_hash: H256, storage_root: H256 ]

In reality almost all account indices would not represent these high accounts but rather be "virtual". High accounts would each fulfil specific functions (though over time these may expanded or contracted as changes in the protocol determine). The accounts on genesis block can be listed:

  • Account 0: Unauthenticated sender. Doesn't actually do anything but represents the unauthenticated (external transaction) origin.
  • Accounts 1...: The virtual account indices.
  • Account ~7: Balances contract. Stores a mapping from U64 -> [U256 (balance), U64 (nonce)].
  • Account ~6: Authentication account. Basic account lookup account. Stores a mapping U64 -> H160 providing a partial public-key derivative ("address", similar to an Ethereum address) for each account index. Can be used to register new accounts (in return for some price). All U64s begin at 0x1.
  • Account ~5: Para-chain management account. Stores all things to do with para-chains including para-chain balances and current state.
  • Account ~4: Staking account. Stores all things to do with the proof-of-stake algorithm particularly currently staked amounts. Informs the Consensus account of its current validator set.
  • Account ~3: Consensus account. Stores all things consensus and code is the relay-chain consensus logic. Requires to be informed of the current validator set and can be queried for behaviour profiles.
  • Account ~2: Administration account. Stores and administers low-level chain parameters. Can unilaterally read and replace code/storage in all accounts, create DOTs, &c. Hosts and acts on stake-voting activities.
  • Account ~1: System origin. Doesn't actually do anything but represents the system origin.

For PoC-1, high accounts are likely to be built-in, though eventually they should be implemented as Wasm contracts.

The transition function may be compared to Ethereum, where:

is mostly similar to an unmetered variant of Ethereum runnong that all but removes smart contracts. Exceptions:

  • Utilisation of Wasm engine for code execution rather than EVM.
  • High accounts do not harbour or increment a nonce when deploying.
  • Wasm intrinsics replace each of the EVM externality functions/opcodes:
    • CALLDATA* -> n/a (if coming straight from a transaction message data will be passed as bytes into the function)
    • BLOCKHASH -> blocks
    • TIMESTAMP -> timestamp
    • NUMBER -> current_number
    • LOG* -> deposit_log
    • CREATE -> deploy (which takes a new account index and clobbers any existing code there; no init function is run).
    • CALL -> call
    • RETURN -> (return in Wasm)
    • BALANCE -> n/a
    • ORIGIN -> n/a
    • GASPRICE -> n/a
    • EXTCODE -> n/a
    • COINBASE -> n/a
    • DIFFICULTY -> n/a
    • GASLIMIT -> n/a
    • GAS -> n/a
    • CALLCODE/DELEGATECALL/SUICIDE -> n/a

Data formats

Data structures are RLP-encoded using normative Ethereum RLP.

Block

A block contains all information required to evaluate a relay-chain block. It includes extrinsic data specific to the relay chain.

Block: [
    header: Header,
    extrinsic: [
        timestamp: U64,
        transactions: Transaction[]
    ]
]

Transaction

Transactions are isolatable components of extrinsic data used in blocks to describe specific communications from the external world.

Transaction: [
    destination: U64,
    function_name: bytes,
    message_data: [...]
]
  • destination is the contract on which the function will be called.
  • function_name is the name of the function of the contract that will be called.
  • message_data are the parameters to be passed into the function; this is a rich data segment and will be interpreted according to the function's prototype. It should contain exactly the number of the elements as the function's prototype; if any of the function's prototype elements are structured in nature, then the structure of this parameters should reflect that. A more specific mapping between RLP and Wasm ABI will be provided in due course.

Header

header: [
    parent_hash: H256,
    number: U64,
    state_root: H256,
    transaction_root: H256,
    parachain_activity_bitfield: bytes,
    logs: bytes[],
    signatures: [[U256, U256, U8], ...]
]
Clone this wiki locally