How It Works

From RunWiki
Revision as of 00:38, 29 April 2023 by Zhell (talk | contribs)
Jump to: navigation, search

Overview

A jig is a JavaScript object that Run syncs with the blockchain. All of its code and method calls are stored on-chain in op_return metadata. Run can reconstruct the state of jigs by loading the code and replaying every method call, but usually intermediate states are cached by indexers. Most jigs are paired with a Bitcoin output so that only the owner of that output can make changes to the jig. All updates taken together form a transaction chain that enables consensus through user verification. This design is similar to other Layer-2 UTXO-based token systems because miners don't verify the JavaScript code. If anyone publishes an incorrect update, it not only destroys the jig but also leaves an immutable record.

Transaction

A transaction in Run is an atomic update to jigs or code.
Inputs => Computation => Outputs

Sample code for a transaction:

class Dragon extends Jig { }

const dragon = new Dragon()

Inputs are the jigs and code which will be updated. Computation is stored as executable statements in an op_return. The Run Virtual Machine executes these statements and produces outputs which are the jigs and code updated or created fresh. The data for these jigs are not stored in Bitcoin outputs, but instead are stored in an off-chain cache and able to be recomputed by others from the blockchain data. In this way Run transactions are kept small. There may also be payment inputs and outputs too that are not used by Run but part of the transaction. Here is the transaction format for the example to the right:
 
Inputs Outputs
1. payment 1. op_return: RUN metadata


2. p2pkh: Dragon Class


3. p2pkh: dragon jig instance


4. change output for payment
 
The op_return data is made up of both push data and a JSON payload. It has the following structure:
[op_false] [op_return] 'run' <version> '<app-id>' '<json-payload>'

Each data field starts with an op_push specifying its length.
The protocol version is currently 0x05.
The app-id field enables applications to identify their Run transactions.
Strings are UTF-8 encoded.
[op_false] [op_return] is the standard prefix for metadata on Bitcoin SV since the Quasar hard fork.
You can easily identify Run transactions and its outputs using the op_return metadata.

Inspecting RUN metadata

const rawtx = await run.blockchain.fetch(txid)
const metadata = Run.util.metadata(rawtx)
console.log(metadata)
 

JSON Payload

The JSON payload stores Run-specific metadata. To the right is a JSON payload for the example above. Its fields are:
Name Description
in Number of jig and code inputs
ref Array of references to jigs and code used by not spent
out State hashes of jigs and code in transaction outputs
del State hashes of jigs and code deleted
cre New owners of jigs and code created
exec Statements to execute on the jigs
The exec field in particular contains the statements for Run to execute. There are 4 opcodes supported by the RUN protocol in 0.6:
Opcode Description Data Format
DEPLOY Upload new code [<src1>, <props1>, <src2>, <props2>, ...]
NEW Instantiate a jig [<jig class>, <args>]
CALL Call a method on a jig [<jig>, <method>, <args>]
UPGRADE Replace code with new code [<code>, <src>, <props>]
The state hashes used in the out and del arrays are calculated by taking the sha-256 of the JSON serialization of the jigs. This state cache format will also be documented soon. Finally, the Run VM provides certain native classes, like Jig and Code, that are built-in to its virtual machine. Eventually this virtual machine will be stored on-chain too ensuring total trustlessness.

The protocol will be documented more in a coming spec. Reach out for any questions!
Sample JSON payload:

{
    "in": 0,
    "ref": [
        "native://Jig"
    ],
    "out": [
        "e494cd3d0c33615620c22f44cddf85f2bf613fd608dbfc53822664581205d198",
        "9a99596f417e8925cb25f2acf99abe28f014aaad47ce93c427ee3afd3bcc5084"
    ],
    "del": [],
    "cre": [
        "mhhHzeLjRTD4cjuygJFjqmCHCFpDKGrp75",
        "mhhHzeLjRTD4cjuygJFjqmCHCFpDKGrp75"
    ],
    "exec": [
        {
            "op": "DEPLOY",
            "data": ["class Dragon extends Jig { }", { "deps": { "Jig": { "$jig": 0 } } }]
        },
        {
            "op": "NEW",
            "data": [{ "$jig": 1 }, []]
        }
    ]
}

Serialization

Sandboxing

Safety Checks

Ownership Rules

Privacy

Backwards Compatibility