Assets and contracts deployed on the ledger be queried for specific information regarding their state, history of all previous states, and all participants involved in their history.

Integrating Private State

The private state file contains values to use with Storage Commitment Scheme.

To check whether a private state file matches the locals in a contract:

$ uplink scripts compile contracts/locals.s -s contracts/locals_state.json

To commit a private state file to the local db for a specific contract and account:

$ uplink data commit contracts/locals_state.json <contract_addr> <account_addr>

Private state allows two parties to load some private values shared between them into a contract. These values can then have certain operations applied to them by a contract. After a contract is finalized, the creator of the contract can then reveal a parameter of the commitment process, which allows other parties to verify there initial values were the same.

Query Language

If Uplink users are running a relational database backend, they can query the state of the ledger using a SQL-like query language by sending a query string to the RPC interface, receiving results in the form of either Account, Asset, or Contract values.

This language allows the users to query the state of the uplink ledger similar to the way in which one would query a relational database comprised of tables. However, since the Uplink ledger is a layer on top of traditional database architectures, the way users interact with and the internal, higher level representation of these ledger values are not relational in nature. In order to store Uplink ledger data in a relational database, a relational schema must be derived from the higher level data structures Uplink uses internally.

The resulting schema is complex and results in a non-intuitive interface through which to query data. Instead of requiring users to learn the underlying schema that Uplink stores the ledger data in, a SQL-like query language has been implemented such that users can perform aggregate queries over ledger values in and intuitive and familiar style.

Query strings in this language are of the form:

query       := QUERY <ledgervalue>; | QUERY <ledgervalue> WHERE <whereclause>;
ledgervalue := accounts | assets | contracts | transactions
whereclause := <condition> AND <whereclause> | <condition> OR <whereclase> | <condition>
condition   := <columnname> =  <columnvalue>
             | <columnname> >  <columnvalue>
             | <columnname> >= <columnvalue>
             | <columnname> <  <columnvalue>
             | <columnname> <= <columnvalue>
  • where column names and column values are specified in the tables below.

Each ledger value has fields that can be specified in the conditional part of the query string:

Queryable Fields


Field Type
address Address
timezone Text


Field Type
name Text
issuer Address
issuedOn Int
supply Int
reference Text
assettype Text
address Address
holder Address


Field Type
timestamp Int (POSIX time)
state Text
owner Address
address Address


Field Type
txtype Text
origin Address
timestamp Int (POSIX time)


Currently, there is one interface through which to query the ledger values from the database using this SQL-like query language: the RPC interface.


To query all assets where account address ‘H1tbrEKWGpbPjSeG856kz2DjViCwMU3qTw3i1PqCLz65’ has holdings:

QUERY assets WHERE holder='H1tbrEKWGpbPjSeG856kz2DjViCwMU3qTw3i1PqCLz65';

To query all transfer transactions submitted by account address ‘H1tbrEKWGpbPjSeG856kz2DjViCwMU3qTw3i1PqCLz65’:

Query transactions WHERE origin='H1tbrEKWGpbPjSeG856kz2DjViCwMU3qTw3i1PqCLz65' AND txtype="Transfer";

To query all contracts created between “Sat, 20 Jan 2018 00:00:00 GMT” and “Mon, 22 Jan 2018 12:00:00 GMT” that are currently in their “initial” state:

QUERY contracts WHERE timestamp > 1516406400000000 AND timestamp < 1516622400000000 AND state = "initial";

Querying Ledger Database

The uplink command line exposes two ways to get data:

Get a contract, asset, or account by address

$ uplink data get <address>

Dumping all contracts, assets, accounts, and blocks

$ uplink data list

Exporting to SQL

To export ledger data to SQL, a node must be run using a postgres backend. Once the node joins the Uplink network, it will request the first block in the ledger, and subsequently all other blocks in the chain, consecutively applying the block transaction to the ledger state and writing the resulting state to the postgreSQL database. After the node has synced it’s local state with the network, the ledger data will be stored in the postgreSQL database and can be read by any user with the proper permissions on the local machine.

Currently there is no way to export ledger data to SQL from a LevelDB database other than to boot an Uplink node with a postgreSQL backend specified, and syncing with the network.

Future versions of Uplink will support the specification of a “boot” database, a database from which to load the ledger state, as well as the “working database”, the database to which the node will write both old and new ledger data. By default the “boot” database is the same as the “working database”.

Exporting to XML

Exporting to XML:

$ uplink data export backup.xml
<?xml version="1.0" encoding="UTF-8"?>
    <block index="0">
            <BlockSignature signature="AE4xMTUxMzY4MDA4MjA0NTY4MzM3Mzc5OTQxMjY3NzEzODYwMTUwMjYyODcwOTUwMzQ2MjU2MjM2NDQxODYyNzgxMDg5MjY2OTA3Nzk1Njc6AE0zNDMyMDI5NDIxMzI4MTA2OTgzNTQwNjkyMDAxNDY1MTc4NDA1MjA5ODQ4MjkxMTA0NDYzMjk1NDcwODM5OTc0OTU1MzIzNTc2ODcwNA==" signerAddr="fwBVDsVh8SYQy98CzYpNPcbyTRczVUZ96HszhNRB8Ve"/>
        <header origin="fwBVDsVh8SYQy98CzYpNPcbyTRczVUZ96HszhNRB8Ve" prevHash="" merkleRoot="a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" timestamp="1231006505">
            <consensus validatorSet="fromList []" blockPeriod="1" blockGenLimit="1" blockSignLimit="1" threshold="1" minTxs="1"/>