Skip to content

Instantly share code, notes, and snippets.

@Earlz
Created June 28, 2018 05:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Earlz/10246daf0c1bd20409e6652a58eb0b6e to your computer and use it in GitHub Desktop.
Save Earlz/10246daf0c1bd20409e6652a58eb0b6e to your computer and use it in GitHub Desktop.

Qtum x86 Trusted Library Mode

A mode exists called Trusted Library Mode. Calling a contract that uses this mode from another contract requires an explicit "allow" option because of the abilities given to the library code. This supports similar use cases as EVM's delegate-call function, but with more control by the calling contract.

Trusted Library mode is designed to be ideal for helper code and computations.

Execution Differences

When executing (and writing) trusted library code, a different memory model is used. Basically, all of the calling contract memory is "mounted" into the bottom 2Gb of the address space. Basically, all of the standard expected memory space for execution is moved up to address 0x80000000. This means when compiling Trusted Library code, care must be taken to ensure that the program is aware it will be executed at this address. Memory allocation is allowed in trusted library execution, but can only be located in the special memory allocation area. This is to prevent potential memory map conflicts. This memory is destroyed and freed upon the completion of the trusted library execution.

Trusted Library Restrictions

A number of restrictions must be observed when writing trusted library code:

  1. The contract must have the Trusted-Library flag active in the deployment flags
  2. The contract must have the Static-Only, Not-Payable, and Not-Upgradeable flags active
  3. Only a subset of the standard smart contract APIs are available, and only dependent on if the calling contract chose to allow them
  4. There is no fault handling facilities. If a fault occurs, execution ends immediately and returns to the calling contract
  5. The calling and parameter passing model is restricted to only allow up to 6 DWORDs back and forth (more data than that should use a memory pointer)
  6. A trusted library can not self-destruct (avoid Parity issue)
  7. External contracts can not access the code of trusted library contracts. This is to make pre-compilation easier to accomplish
  8. Trusted Library contracts can not use mounted memory calls to avoid even more complexity with the memory model

Permissions

All Trusted Library executions must be provided with a list of permissions for what is allowed to be done in this execution. A trusted library behaves as if it is executing in the context of the calling smart contract. So, if the trusted library tries to send coins, it sends them as the calling contract. The following permissions are defined:

  1. Write to contract memory (by default only reading contract memory is permitted)
  2. Write to contract storage (reading is always allowd)
  3. Upgrade contract bytecode
  4. Call external contracts (sender would be calling contract, not the library contract)
  5. Send coins (Must be coupled with call external contracts)
  6. Allocate and Free memory in calling address space

Calling Other Trusted Library Contracts

It is possible to call external Trusted Library contracts. However, the communication process is somewhat specialzied due to the way memory is mounted. Memory can be allocated in the "Trusted Common Communication area" (0x70000000-0x80000000) but it must be observed that any contract called may corrupt this area of memory. For this reason it is highly discouraged from calling untrusted or unknown contracts from critical trusted library functions if using this area of memory extensively.

The communication area should not be used for any purpose but to pass and receive data to/from external trusted library contracts. It has the following restrictions and implications:

  • This area of memory is persistent only to the next uninterrupted trusted call level. So, if call stack is A->B->C->D with A,B, and D being trusted libraries and C being a standard one, D will not have access to the communication area that could be used by A and B
  • This area of memory is completely inacessible to standard contracts. This is to make precompiled versions easier to create and to prevent state leaks that can break consensus when using precompiles
  • No memory conflict detection facilities are provided beyond the MemoryReadable and MemoryWriteable API calls. Trusted Library contracts should be careful to analyze their dependencies to ensure that no conflicts could corrupt needed data in this space
  • Trusted Library calls within threads maintain the same aspect with the area of memory being persistent, but it is not possible to call external contracts that aren't Trusted Libraries.

When calling external Trusted Library contracts, the given permissions can not supersede the permissions given to it by the calling contract. However, if a Trusted Library calls a normal contract, the normal contract can grant whatever permissions desired to another Trusted Library contract (since it would be this contract that the trusted library has permission to act on behalf of)

Standard Library APIs

Computation/Helper APIs

Several functions should be supported from the start:

  • Stripped down libc (include things like string functions, etc.. but no need to include things like fopen, etc)
  • Base58 address encoding/decoding
  • Encryption/decryption/signatures compatible with Ethereum and Bitcoin's algorithms
  • Hashing algorithms for sha256 and sha3
  • Decompression algorithm?
  • Ethereum ABI encode/decode functions
  • Malloc/realloc/free algorithm that gets large chunks of memory and divides them up into small granular pieces to optimize gas usage

Standard Library Model

In order to rectify the storage waste, and difficulties in developing for the EVM without a set of common basic functions, Qtum will rectify this by providing a standard library of common functions. This set of functions can be extended later by using DGP proposals. In addition, standard library functions can have gas costs that are set by DGP proposals, allowing for their cost to be adjusted dynamically.

Despite calling this a "standard library", the blockchain is decentralized, and the Qtum team only hopes to faciliate the community in developing it's own standard library. And so there is no specialized "standard library" mode that only Qtum or DGP participants can use. Basically the provided set of standard library functions are merely a set of "blessed" Trusted Library contracts. This blessing occurs through the DGP mechanism. And the blessing is only in the form of granting the following to the contract:

  • A fixed gas price for it's execution
  • A gas price discount (can be combined with fixed prices, or set to 100% to make gas completely free other than the fixed prices)
  • A fixed gas price per iteration within it's execution (up to 4 complexity levels supported)
  • Precompile Preferred - If set, indicates that a pre-compile should be used if possible. This should be set in all blessed functions unless a vulnerability or consensus break is later discovered in a pre-compiled version. In this case, DGP can be used to disable the pre-compiled form to restore proper consensus functionality. When removing the blessing, precompile functionality is also disabled

The blessing can be removed or modified at any time by the DGP participants. In this way, commonly used functions in the ecosystem can be optimized or become pre-compiled easily, with cheaper gas usage to further encourage their utilization. And if a function becomes flawed in some way later, this blessing can be removed or modified to prevent attacks on the blockchain.

Non-Consensus Criteria for Standard Library Additions

The following are not enforced by code on the blockchain, but should be followed to prevent attacks and to keep the blockchain effecient when blessing new standard library functions.

  • Gas prices should not be drastically reduced for any function that uses any permission except for memory writing
  • Functions should usually rely only on other standard library functions, or at least only other trusted library functions
  • Mulit-function contracts should not be blessed. Multiple functions should be split into multiple contracts and blessed individually
  • All functions should be evaluated to ensure they can be precompiled and are secure before blessing

Gas Discount Exceptions

The following are not affected by gas price discounts:

  • Storage Writes and Reads
  • Calling external contracts (external contract gas prices are not affected by gas discounts in the trusted library)
  • Calling other trusted library contracts (unless they have also been given a blessing)
  • Sending coins
  • Loading code data from external contracts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment