Design Principles

UTxOs as Single-Use Seals:

Physical single-use seals are rarer than their digital counterparts. We often use such seals to protect the integrity of secure shipping to ensure products were not tampered with in transit.

The principle, however, is deceptively simple: if the seal has yet to be opened, then it is still valid. Similarly, with digital single-use seals (first proposed by Peter Todd), it is possible to close a digital seal over a message to ensure that the message can be used once and only once.

Unspent Bitcoin transaction outputs (UTxOs) display this property. All Bitcoin transaction outputs are cryptographically unique (UTxOs exist as a TX_HASH:OUTPUT_INDEX, the hash and index ensure uniqueness); no two UTxOs will ever be the same.

All Bitcoin transaction outputs can only be spent once; this is an intentional design built into the blockchain's double-spend protection.

By leveraging these unique properties, it is possible to treat UTxOs as single-use seals where the spending of the UTxO constitutes breaking the seal. When instructions are attached to the breaking of a seal, one can create a consistent, deterministic state machine that represents a transfer in ownership.

Bitcoin as Truth and Consensus

The Bitcoin blockchain is the world's most used, most decentral, and most secure blockchain. Rather than relying on a centralised entity or company to verify whether single-use seals have been broken or not, we can pass this work on to the Bitcoin blockchain and, in turn, create a decentralised protocol.

More than single-use seals is needed to solve all our problems, however, we also need a mechanism to ensure that a particular state change is what the owner of the UTxO intended. The way we achieve this is that we can simply hash what the state change is and include this in the transaction that spends the UTxO.

We can solve this by including a hash and inserting it into an OP_RETURN code in a Bitcoin transaction. To prevent double spending, only the hash of the first OP_RETURN code is considered valid. This data can also be inserted into taproot descriptors.

This allows us to have a chain of contract interactions/transfer events that can be independently reconstructed and verified through hash analysis of a series of transactions. Users will need off-chain data from the instruction that was hashed to validate the contract fully.

This feature can be used to preserve and protect privacy and also creates an opportunity for hosts to provide this information to the community either for free or for some financial incentive.

SCL State Transitions

SCL uses the above-described mechanisms to create a series of contracts that operate through state transition. Every time a single-use seal is spent, some state transition, that changes the contract state, can occur. Let's look at a simple example and then expand it into an SCL01 contract:

The first thing that needs to happen for us to be able to transfer assets is for the assets to be minted to the blockchain. This is achieved by including a mint command in a transaction and binding the assets to the change address of the mint command.

MINT: [ TICKER, MAX_SUPPLY, DECIMALS, TXID:N ]

This is an example of what a mint command could look like, where TXID is the transaction that the command is in and will later become the contract ID, and N is the output number that the new assets get bound to.

MINT: [ TESTCOIN, 1000000000, 8, TXID:1 ]

In the above example, we mint 10 TESTCOIN, and we bind them to the second output of that transaction. After we have some tokens attached to a UTxO, we can then transfer them using a command somewhat like this:

TRANSFER: [ UTXOA, UTXOB (AMOUNT), UTXOC (AMOUNT) ]

As you can see, we can specify that we are spending UTxOA in order to send some amount to UTxOB and receive our change in UTxOC.

TRANSFER: [ bb8c1cc124d7a29313c7f9d4306afa308a0d4f1f25967192e4e3d2a3bd68bb2e:1,
a1ab93a0114313fc69e4b6f377799ed5b9bb1606113055c6561b361dccc54e4a:1(10000),
f788b96b716362adc80267f758441be2ccfdad75110683c3121c15074abc096f:0(99999000 0) ]

The above example shows how a transaction might look if the UTxOs are explicitly mentioned. Due to the fact that changing data in a transaction changes the hash of the transaction, it is not possible to include self-referential hashes in a Bitcoin transaction. Due to this, we can reference UTxOs that are created in the transaction using the "TXID:N" shorthand. Essentially, SCL views all UTxOs marked by TXID as internal (UTxOS in the specific transaction). If we adjust the above example to send to our first output and send change to our second output, the result looks more like this:

TRANSFER: [ bb8c1cc124d7a29313c7f9d4306afa308a0d4f1f25967192e4e3d2a3bd68bb2e:1, TXID:0(10000),
TXID:1(999990000) ]

However, our transfer command actually needs much more information for this to actually work. Not only that, but it would be much more preferable if we could perform multiple smart contract interactions with a single Bitcoin transaction. We also want to specify which contract we are referring to with a contract ID.

CONTRACT_ID_1:TRANSFER[[UTXO_SENDER_1, UTXO_SENDER_2, ... , UTXO_SENDER_N],
[UTXO_RECEIVER_1(AMOUNT), UTXO_RECEIVER_2(AMOUNT), ... , UTXO_RECEIVER_N(AMOUNT)]]

The above example showcases a more mature version of an SCL transfer command, where multiple sender UTxOs can be spent, and multiple receivers can be paid. We also specified the contract ID. This is an example of a command that could be batched with multiple commands for greater scalability.

Payloads And Batching

Due to the scalability constraints of layer one blockchains, SCL has developed a batching system designed to facilitate the batching of multiple commands into a single transaction hash. This allows SCL to scale in a block data conservative approach on layer one while also being transferable on layer two (inheriting layer two scalability and speed). We place all of our commands in what we call a payload. It is only the payload that is hashed and included in transactions, and it is the payload and hash that are used to validate any state transition.

<TXID, PAYLOAD>

From a validation perspective, one must know which transaction is associated with a particular payload. Therefore, we also include the transaction, which consists of a payload when representing a payload dictionary, which any client can use to recreate and verify the contract state independently.

Payloads are constructed out of a variety of contract commands; a more detailed breakdown of payload command structure can be seen below:

<TXID, {CONTRACT_ID_1:COMMAND}{CONTRACT_ID_2:COMMAND}... {CONTRACT_ID_N:COMMAND}>

Suppose we combine the above protocol with our earlier example of a scalable transfer command. In that case, we can create an instance of an SCL command performing multiple asset transfers with a single Bitcoin transaction!

<TXID, {CONTRACT_ID_1:TRANSFER[[UTXO_SENDER_1, UTXO_SENDER_2, ... , UTXO_SENDER_N],
[UTXO_RECEIVER_1(AMOUNT), UTXO_RECEIVER_2(AMOUNT), ... , UTXO_RECEIVER_N(AMOUNT)]]}
{CONTRACT_ID_2:TRANSFER[[UTXO_SENDER_1, UTXO_SENDER_2, ... , UTXO_SENDER_N],
[UTXO_RECEIVER_1(AMOUNT), UTXO_RECEIVER_2(AMOUNT), ... , UTXO_RECEIVER_N(AMOUNT)]]}...
{CONTRACT_ID_N:TRANSFER[[UTXO_SENDER_1, UTXO_SENDER_2, ... , UTXO_SENDER_N],
[UTXO_RECEIVER_1(AMOUNT), UTXO_RECEIVER_2(AMOUNT), ... , UTXO_RECEIVER_N(AMOUNT)]]}>

This innovation alone represents a significant improvement to crypto asset scalability. Comparatively, whenever more outputs are added to a Bitcoin transaction, the number of bytes increases, causing the transaction fee to increase. Because the entire payload is hashed regardless of the number of contract interactions, the number of bytes added to the blockchain is always thirty-two. Hence, payloads have a fixed cost.

In an EVM paradigm, users pay for the processing of the VM; this means as you increase smart contract interactions, you are performing more processing on the VM, which in turn increases transaction costs.

SCL effectively has a known cost per payload and can batch thousands of interactions together, allowing for greater efficiency and cheaper contract interactions.

Validation

Contracts, their states, and additional information can be thought of and visualised as objects. A mint command is valid as long as the hash in the command matches the desired mint parameters of the payload.

Once a mint command is validated, an initial state graph is created:

{ "ticker": "DFG", "contractid": "4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360", "supply":
100000000000000000, "decimals": 8, "owners": {
"4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:1": 100000000000000000 },
"payloads": [ “<4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360,{SCL01:[DFG,
100000000000000000,TXID:1]}>" ] }

Anyone can independently validate the mint command by comparing the initial payload hash to the hash stored in the OP_RETURN of the minting transaction. This same validation paradigm is applied to all payloads for all contract interactions.

The following is an example of a contract state after multiple transfer commands have occurred. It is important to note that anyone can securely validate the cryptographic integrity of the contract simply by checking the payload hashes against the hashes on the blockchain.

Since we cannot spend UTxOs twice and because we write the payload hash into the OP_RETURN of the transaction as an anchor, we inherit the consensus model and security of the underlying blockchain.

{ "ticker": "DFG", "contractid": "4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360", "supply": 100000000000000000, "decimals": 8, "owners": {
"f9b87b2907b55afe7d104398787aa5c427c6f5940215ff0434532ce17f674ebd:0": 60000,
"245f21e498c0e3eb2547298085d67518713eb44bb30f4511e14e5d8362784b64:0": 55000,
"0ab7b733d75c29caee531959e78c542ef32576331c8efb0edb30ed817ebde8a2:0": 420000,
"a074bdcf9954347f8e1ed233530abf2f58f5c0da3b9acd2158ea98afa519b41a:0": 420000, "4f85e172762dabd1dfca9e3eb7c753156f78af41f743983e04776c16cba31585:0":
60000, "b5210f5a098f9f258b9cf3883df5a7103cbb3ed46caae0c6907e110cc8d08496:0": 75000,
"cf58521c0ad86cdcef2d1bc21a2eb1c940085b5029095b3df96ec9ccf3d54d9f:0": 175000,
"f9b87b2907b55afe7d104398787aa5c427c6f5940215ff0434532ce17f674ebd:2": 190000,
"cf58521c0ad86cdcef2d1bc21a2eb1c940085b5029095b3df96ec9ccf3d54d9f:2": 99999999998545000 },

"payloads": [ “<4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360,{SCL01: [DFG,100000000000000000,8,TXID:1]}>",
"<4bad9f4de415695991f2864f204984daab87e36c3e80787701961fc0021ffc29,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[4eae21aa41695
b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:1], [TXID:0(250000),TXID:2(99999999999750000)]]}>",
"<245f21e498c0e3eb2547298085d67518713eb44bb30f4511e14e5d8362784b64,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[4bad9f4de4156
95991f2864f204984daab87e36c3e80787701961fc0021ffc29:2], [TXID:0(55000),TXID:2(99999999999695000)]]}>",

"<0ab7b733d75c29caee531959e78c542ef32576331c8efb0edb30ed817ebde8a2,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[245f21e498c0e
3eb2547298085d67518713eb44bb30f4511e14e5d8362784b64:2], [TXID:0(420000),TXID:2(99999999999275000)]]}>",
"<a074bdcf9954347f8e1ed233530abf2f58f5c0da3b9acd2158ea98afa519b41a,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[0ab7b733d75c
29caee531959e78c542ef32576331c8efb0edb30ed817ebde8a2:2], [TXID:0(420000),TXID:2(99999999998855000)]]}>",
"<4f85e172762dabd1dfca9e3eb7c753156f78af41f743983e04776c16cba31585,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[a074bdcf99543
47f8e1ed233530abf2f58f5c0da3b9acd2158ea98afa519b41a:2], [TXID:0(60000),TXID:2(99999999998795000)]]}>",
"<b5210f5a098f9f258b9cf3883df5a7103cbb3ed46caae0c6907e110cc8d08496,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[4f85e172762da bd1dfca9e3eb7c753156f78af41f743983e04776c16cba31585:2],
[TXID:0(75000),TXID:2(99999999998720000)]]}>", "<f9b87b2907b55afe7d104398787aa5c427c6f5940215ff0434532ce17f674ebd,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[4bad9f4de4156
95991f2864f204984daab87e36c3e80787701961fc0021ffc29:0],[TXID:0(60000),TXID:2(190000)]]}>",
"<cf58521c0ad86cdcef2d1bc21a2eb1c940085b5029095b3df96ec9ccf3d54d9f,
{4eae21aa41695b59ccfbcc2b37417c6e5f3e63028690d1ab9d8705dd0ce47360:TRANSFER[[b5210f5a098f9f
258b9cf3883df5a7103cbb3ed46caae0c6907e110cc8d08496:2], [TXID:0(175000),TXID:2(99999999998545000)]]}>" ] }

Contract Hosting

All contracts can be independently validated. However, the transfer and storage of the extra validation data might be onerous for users. While users can host their own contracts, they can also pass this responsibility to others. Since the hosting of a contract does not require consensus, there are no risks in allowing others to host contracts from a data transparency perspective. Allowing users to host contracts independently, in clusters, in DAOs, or privately actually lends itself to having higher levels of decentralisation especially when compared to EVM, where all contracts are hosted redundantly in every full node.

SCL contract hosts can also charge or not, depending on business requirements. As an example, a video game company might host contracts for all their in game assets free of charge as they are financially incentivised by the success of the game. Alternatively, a DAO could host their contracts across a variety of devices in a decentralised manner.

Last updated