Network Design

Introduction

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

A deploy 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 deploy as valid, it places the deploy 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 deploy.

  1. Execution Semantics

  2. Accounts

  3. Unforgeable Reference (URef)

  4. Block Structure

  5. Tokens

Execution Semantics

A Girrona network is a decentralized computation platform. This section describes aspects of the Girrona 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 Girrona blockchain. Similar to Ethereum, Girrona uses GAS to measure computational work in a way that is consistent from node to node in a Girrona 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.

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 deploy. The gas limit is set by executing the payment code specified within the deploy.

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

NOTE

Please note that Girrona will not refund any amount of unused gas.

This decision is taken to incentivize the Girrona Runtime Economics by efficiently allocating the computational resources. The consensus-before-execution model implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys.

The Girrona 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.

All these features are accessible via functions in the Girrona 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 deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same deploy).

Accounts

The Girrona 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 Girrona 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 Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Girrona blockchain (i.e., "deploys") 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 Girron tokens.

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.

An Account contains the following data:

  • A URef representing the account's "main purse"

  • A collection of named keys (playing the same role as the named keys in a stored contract)

  • A collection of "associated keys" (see below for more information)

  • "Action thresholds" (see below for more information)

Permissions Model

Actions and Thresholds

An account can perform two types of actions: sending deploys and managing keys. A deploy 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 deploy; therefore, a key management action implies that a deploy action 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 deploy action, the key management threshold should always be greater than or equal to the deploy threshold.

Associated Keys and Weights

Accounts on a Girrona network can associate other key pairs through a multiple signature scheme for sending transactions. An account's associated keys are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy 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 account.

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 deploys 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 deploy 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 (Girrona currently does not support "inactive recovery").

The Account Context

A deploy 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 account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account'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.

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 Girrona network. URefs exist as a top-level entity, meaning that individual accounts do not own ‘URef’s. As described above, accounts and contracts possess certain Access Rights, allowing them to interact with the given URef. While an account will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Gittona mint. The individual balance key within the Girrona mint is the account's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

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

Block Structure

A block is the primary data structure by which network nodes communicate information about the state of a Girrona 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.

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 Lasper network when this block was proposed.

Body

The block body contains an ordered list of DeployHashes which refer to deploys, and an ordered list of DeployHashes for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, 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 deploys and / or native transfers.

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 deploy are serialized.

Tokens

Girrona is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called Highway. 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 Girrona 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 ONE billion GIRRO. 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.

Divisibility of Tokens

Typically, a token is divisible into some number of parts. We call the indivisible units which make up the GIRRO token motes. Each GIRRO 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 GIRRO is human-readable convenience and does not exist within the actual infrastructure of a GIRRO network. Instead, all transactions deal solely with motes.

Purses and Accounts

All accounts on the GIRRONA system have a purse associated with the Girrona 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 account (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 main purses. For this reason, Girrona supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the source and the main purse of the account at the provided key as the target.

The Girrona Mint Contract

The Girrona mint is a system contract that manages the balance of motes within a Girrona network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Girrona network but maintains an internal ledger of the balances for each Account'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 URefwith appropriateAccessRights` 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

Add

Deposit (i.e. transfer to)

Write

Withdraw (i.e. transfer from) Read Balance 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 Girrona 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

Last updated