Skip to content

Safexcore Advanced Functionality

Marko Atanasievski edited this page Jul 16, 2019 · 14 revisions

This document is draft, and current work in progress. Comments and contributions are welcome.

Introduction

This proposal document describes advanced Safex functionality intended for milestone 2 release, as stated on the roadmap.

Transactions with advanced functionality

Basic Safex blockchain offers two types of outputs (UTXO - unspent transaction output) - token outputs and cash outputs. Equivalent types of inputs exists, and additionally block reward input for coinbase transaction input (miner reward) and token migration input. Transactions with version 1 are currently used exclusively on the network.

Transaction fields:

Transaction Fields

To attach advanced state to the UTXO and enable advanced scenarios, new type of UTXO named txout_to_script will be used. Transaction version 2 will be used for transactions that can have txout_to_script outputs. They carry state, context of the advanced Safex blockchain entities and operations. Similarly, txin_to_script inputs that process, "spend" txout_to_script outputs have a script field that represents command that must be executed as part of transaction and that will produce new txout_to_script output in that transaction. Additionally, version 2 transactions will have additional domain field in the extra signature, that should ease transaction verification with respect to the transaction domain. For example, domain could be “token_stake”, “title_markets”... . Version 1 transaction will continue to coexist on network for ordinary cash, token and migration transfers.

Script transaction output

Script transaction output keeps state of previous command execution on the blockchain. For example

Fields:

Output type - txout_to_script output type, specifies output type (e.g. staked tokens)

Keys - array of public keys of the output owners. By having private key that matches public key, owner can use, “spend” script output. In some cases (e.g. token staking), there is one owner, but in more complex cases (e.g. escrow), there could be multiple owners (for example 2 out of 3 owners must sign output and transaction output must go through multiple steps to be fully utilized).

Amount - Safex cash amount that exist in the output. Like txout_to_key output can hold Safex Cash, in the same way txout_to_script output keeps Safex Cash.

Token Amount - Safex token amount that exist in the output. Like txout_token_to_key output can hold Safex Tokens, in the same way txout_to_script output keeps Safex Tokens.

Data - output data field, keeps result of the command execution on input and final state and data of output. Depends on the type of output.

Txout_to_script fields

C++ definition of txout_to_script:

    struct txout_to_script
    {
        uint32_t output_type;
        std::vector<crypto::public_key> keys;
        uint64_t amount = 0; //Safex Cash amount
        uint64_t token_amount = 0; //Safex Token amount
        std::vector<uint8_t> data; //Key value store with the output state
    };

Script transaction input

Fields:

Key Offsets - reference to previous inputs that should be spent

Key Image - proof that the owner of inputs that shuold be spent has private keys and is able to “spend” it. Also prevents double spend.

Amount - cash amount input to the transaction, must be equal to spent txout_to_script amount

Token Amount - token amount input to the transaction, must be equal to spent txout_to_script token amount

Script - script is a command executed on the input of transaction in the process of transaction verification. txin_to_script script field is parsed for command and its arguments, and is then executed. Input data/state of the referenced (spent) txout_to_script gives context for the command execution. Result of the execution is used further in creation of the transaction outputs.

Txin_to_script

C++ definition:

struct txin_to_script
{
 std::vector<uint64_t> key_offsets; //offsets of previous inputs that should be spent
 crypto::key_image k_image = AUTO_VAL_INIT(k_image); // double spending protection, only owner of previous txout_to_script can use it
 uint64_t amount = 0; //Safex Cash amount as input
 uint64_t token_amount = 0; //Safex Token amount as input
 std::vector<uint8_t> script; //Contains Safex protocol layer commands executed on txout_to_script state

};

Safex command protocol

Safex Command protocol is intended to expand functionality of the blockchain and to enable easy addition of the new features without having to make significant changes to the current blockchain core protocol. It may be arguably considered as new protocol layer on top of current Safex blockchain basic protocol.

Commands in txin_to_script script field have the following format:

Command

Wallet/client will create command and put it result execution in the txout_to_script data field. Node will execute command again and check if the transaction/output state is correct and valid.

Data byte field in the output will keep result of the input command execution and final state of the output. Command parameters and result format and meaning is command specific and will be fixed for every command.

Domain Command Command code Arguments Result
nop 0x00 None Ignore script field, nothing to execute
token_staking Token Stake 0x01 Local token amount Output with staked tokens
token_staking Token Unstake 0x02 Id of the staked token output on blockchain Token output with unlocked tokens
token_staking Collect Interest 0x03 Id of the staked token output on blockchain Output with staked tokens and Safex cash output with interest

Token staking/unstaking

In order to earn interest from tokens in possession, token holders will be able to stake tokens. Tokens must be staked for at least minimum defined period of time to collect fee (for example 1000 blocks) and will stay staked until they are manually unstaked by request with another transaction. There will be minimum amount of tokens to be staked (for example 10000 tokens). Token interest will be calculated for every rounded 1000 blocks, by summing all collected fees from trading and dividing it to the number of staked tokens. If one token holder tokens stay staked for example for 20400 blocks, interest would be calculated as sum of twenty 1000-blocks-window interests for that period.

Fee collection will happen in the token unstake procedure, where calculated interest will be output of the transaction together with the unstaked tokens that return to their holder as txout_token_to_key UTXO. No tokens will be burned during stake/unstake process. On demand token staking/unstaking will cost only small Safex Cash transaction fee that miners take to include transaction in the block. Alternative solution to regularly distribute fee to all token holders with staked tokens is abandoned because of the high cost and possible big number of token holders. It will also be possible for token holder to collect interest, and restake tokens (restart window for staked tokens) in one single atomic transaction, named collect.

Staked token outputs (in the form of txout_to_script) will be tracked in the separate database table. Nodes will also keep track of all collected network fee outputs.

Token Stake

Token Unstake

Token Collect

Tokens default staking period will be determined (for example 1 year). That means that tokens will collect interest for a default period without user intervention. If the tokens are unstaked/staked again, or interest is collected with special transaction (collect command), default locking period is restarted. If the default locking period expires, token will stay staked, but will not collect interest until they are restaked or collect interest transaction is performed on them. Token holder will not loose first default period interest no matter how long tokens stay staked. Purpose of this default period is to prevent cumulative loss of Safex cash supply in the case of forgotten wallets or lost private keys of token holders.

Nodes will track number of staked tokens that participate in fee distribution and update active token balance after every stake/unstake transaction. They will also track expiry period for every staked token output, and will know how many tokens are staked and should earn interest at beginning of every interval (interval will begin at every round number of blocks+1, for example first interval is from 0001-1000, second 1001-2000, etc). At the first block of new interval, number of staked tokens is frozen and is used for fee distribution calculation during that period. Number of staking/unstaking/expiry events that happen during that period will impact fee distribution calculation in the next 1000 blocks window.

Database

Output tables

Table name key value
output_txs Output ID {TxHash, local index}
output_advanced Output ID {output type specific data}...
output_advanced_type Output type {Output Id of outputs from output_advanced table}...
token_locked_sum interval token sum
network_fee_sum interval collected fee sum
token_lock_expiry block_number {list of staked outputs that expiry on this block number}

New type of outputs, txout_to_script will be processed as part of transaction in the same way as existing cash and token outputs. Global output ID of the txout_to_script will be placed to the output_txs table, togther with transaction and output local transaction index.

Detailed txout_to_script data will be placed to output_advanced table. Id of the txout_to_script will be autoincrement Output ID from the output_txs table. In transaction intputs, txout_to_script outputs will be referenced by Output ID. Table output_advanced_type will cache indexes per type of advanced output (for example, for type staked token output, it will keep array of Output ID values of outputs that are of that type).

Interval table token_locked_sum will track amount of tokens at the beginning of every fee interval (e.g. 1000 blocks).

Table network_fee will hold information of the sum of total collected network fees for interval periods.

Table token_lock_expiry will cash info about token outputs and their default period expiry blocks, to speed up calculation of token sum for intervals in token_locked_sum table.

To ease calculations and comparisons, intervals will be represented with latest block number in that interval, for example second interval is 2000, 23 interval is 23000 etc.

Fee collection

Accounts and trade offers will be covered later in this document. This illustration is for the purpose of fee collection demonstration. As output of every fulfilled trade offer, there will be Safex cash output that will belong to the network and will be input in fee calculation and redistribution.

Trade offer purchase

Accounts

Account is basic user profile on the Safex blockchain. It is used for access of higher level services on the blockchain.

Account has following properties:

  • Account key
  • Username
  • Email (opti
  • Avatar
  • Description
  • Keys for message encryption (TBD: PGP keys or more modern alternatives)
  • Reputation

Account key and username are immutable and identify account. Account key, username, keys for message encryption and reputation are mandatory fields for normal account functionality. Rest is optional. Mandatory account fields must be specified at the moment of account creation. Optinal fields could also be added/edited later. User must be able to choose amount of informations he wants to reveal about himself.

Account is not cryptographically linked to any Safex address. Wallet will automatically manage available Safex cash addresses for payments and refunds when account actions (e.g. trade, create offer) are performed. In this case buyer addresses will be anonymous by default protected by ring signature, i.e. transaction observer will not know which input from ring signature belongs to account that is buying something. On the other side, buyer will have to publish refund address (for example he could create some subaddress used only as refund address). Vendor will be able to specify receiving address for trade offers he is creating.

Account fields

Account key is public key, used for verification of account actions, that are signed with account private key. Username is human readable name of the account, unique in the whole blockchain. PGP keys (mandatory) are used for encrypted messaging between accounts. Messaging will be performed offchain. Optimally use some other cryptographic scheme for messaging. Wallet should manage those keys and encrypted messaging for user convenience. Reputation (mandatory) is linked to an account. Will be described in separate chapter. Email (optional) – for email communication with a user. Avatar (optional) is link to the avatar image. It could be stored on IPFS or somewhere else. Description (optional) is link to the off-chain description of the user. Could be for example remote IPFS JSON file, with additional user info.

Additional account properties (fields) could be added in future network updates.

Mandatory account information is kept on chain. Optional fields may be kept off-chain, and url to them kept on-chain. There will be separate transaction mechanisms for creation, editing and closing of accounts.

Account creation will require account creational token. Account creational token will be generated with a separate transaction where 100 Safex Tokens are staked for a period of around 1 month and then returned to the owner in full amount. Account creational token will be transferable to other persons (for example user could give away account creational tokens to invite new users to the Safex blockchain network). In the early days of the network there may be faucet for distribution of creational tokens to speed up platform adoption.

On the blockchain, account will be created with account creational transaction, where account creational token and all the data are transaction input, and txout_to_script utxo with account entity is transaction output.

Some possible actions that account may be able to perform:

  • Account can be buyer, seller, and moderator in the trade
  • Send encrypted messages to other accounts.
  • Create and manage simple trade offers.
  • Create and manage title markets.
  • Create and manage auctions and crowdfunding campaigns.
  • Buy and bid on offers.
  • Perform as an arbiter on escrow.
  • Rate other user accounts (only if participated in trade).
  • Become voting member of governance (TBD).