# Light-contracts
## AKA, what the hell is a predicate?
David Mihal - Fuel Labs
Slide: https://hackmd.io/@dmihal/predicate-ist
---
![image.png](https://hackmd.io/_uploads/HydUo9z7p.png)
New architecture for rollups
New VM, new language (Sway)
---
## Predicates
One of Fuel's coolest features...
But are predicates fully unique to Fuel?
Not really...
---
| Physical (bearer) assets | Digital assets |
| -------- | -------- |
| Ownership means physical possession | Ownership means ability to move assets |
---
On blockchains:
Ownership is the ability to move an asset following the rules of the chain.
---
# Basic Bitcoin rules
For a given coin, the owner can sign a message allowing them to "spend" the coin and create new coins with different owners.
```graphviz
digraph UTXO {
node [shape=box, style="rounded,filled", fillcolor="#E8F6FF", fontname="Arial"];
edge [style=invis];
subgraph cluster_UTXO {
label = "UTXO";
labeljust = "l";
fontname = "Arial";
color = "#A9D0F5";
style = "rounded,filled";
fillcolor = "#D6EAF8";
UTXO [label="0.1 BTC\nOwner: 12higD...Wv"];
}
}
```
Known as "Pay to Public Key Hash" (P2PKH)
---
What if we could define our own rules?
---
## Pay to Script Hash (P2SH)
"Create" script
1. Create script using Bitcoin Script
2. Hash the bytecode
3. Send funds to address derived from hash
Spend script
Include script bytecode in hash
---
```typescript
OP_2
<key1.public_key>
<key2.public_key>
<key3.public_key>
OP_3
OP_CHECKMULTISIG
```
---
```typescript
OP_IF
<$(
<current_block_time> <delay_seconds>
OP_ADD
)>
OP_CHECKLOCKTIMEVERIFY OP_DROP
<trusted.public_key>
OP_CHECKSIGVERIFY
<1>
OP_ELSE
<2>
OP_ENDIF
<first.public_key> <second.public_key> <2>
OP_CHECKMULTISIG
```
---
First time in history that assets are owned by _code_
---
Fast forward to EthereumLand...
---
Ethereum smart contracts:
Bitcoin P2SH (immutable code that can own assets)
\+ more powerful VM
\+ on-chain code
\+ on-chain storage 💾
---
Forget, simple multisigs...
* Dynamic multisigs
* Social recovery
* Liquidity pools
* Lending markets
* Rollups
---
# The Problem...
![](https://hackmd.io/_uploads/rkH6hSSLn.png)
---
### Now to Fuel land...
---
# Original Fuel philosophy:
Combine the efficiencies of Bitcoin with the expressivity and flexability of Ethereum
---
Simplicity of Bitcoin's stateless P2SH
\+ Expressivity of Ethereum's EVM
= Predicates!
---
Predicate is just an _address_
It's not created or deployed
It's only useful if it owns assets
Code is only revealed when trying to _take_ (spend) tokens from a predicate
---
# Free giveaway
```rust
predicate;
fn main() -> bool {
true
}
```
---
# Password-protected token
```rust
predicate;
use std::hash::sha256;
fn main(password: str[16]) -> bool
// sha256("Hello World ")
let expected_hash = 0x0a692e936c61cc37c9dc4517e88aa3604780b273fed61b7690d41efaa51fa03d;
sha256(password) == expected_hash
}
```
---
# Native account abstraction
New wallet signatures
```rust
predicate;
configurable {
PREDICATE_ADDR: b256 = ZERO_B256,
}
fn main(signature: B512) -> bool {
let evm_address: EvmAddress = EvmAddress::from(PREDICATE_ADDR);
let res = ec_recover_evm_address(signature, personal_sign_hash(tx_id()));
if res.is_ok() {
if evm_address == EvmAddress::from(res.unwrap().value) {
return true;
}
}
false
}
```
---
## Predicates are _stateless_
Can't access data stored on chain
* Can't read data from smart contracts
* Can't check the current date/time
* Can't read the block hash/number
_if a predicate evaluates to `true` then it will always evaluate to `true` in the future_
---
## What can a predicate access?
Anything included in the transaction!
* Predicate input parameters
* Input coins
* Output coins
* The transaction script
---
## Atomic Swap
"Create" order
```graphviz
digraph CoinMovement {
node [shape=circle, fontsize=12]
UserA [label="User A", shape=plaintext]
Coin [label="ETH"]
Predicate [label="Predicate", shape=plaintext]
UserA -> Coin
Coin -> Predicate
}
```
---
## Atomic Swap
```graphviz
digraph CoinMovement {
node [shape=circle, fontsize=12]
UserA [label="User A", shape=plaintext]
UserB [label="User B", shape=plaintext]
UserBOut [label="User B", shape=plaintext]
CoinA [label="ETH"]
CoinB [label="USDC"]
Predicate [label="Predicate", shape=plaintext]
Predicate -> CoinA
CoinA -> UserBOut
CoinB -> UserA
UserB -> CoinB
}
```
---
<!-- .slide: style="font-size: 20px;" -->
## Atomic Swap
```rust
predicate;
configurable {
ASSET_ID: ContractId = ContractId::from(0x0000000000000000000000000000000000000000000000000000000000000000),
RECEIVER: Address::from(RECEIVER_CONFIG),
}
fn main() -> bool {
// If the tx contains a single input from the receiver, cancel the order
if input_count() == 2u8 {
if input_owner(0).unwrap() == RECEIVER || input_owner(1).unwrap() == RECEIVER {
return true;
};
};
let output_index = 0; // Output 0 must pay receiver
let to = Address::from(__gtf::<b256>(output_index, GTF_OUTPUT_COIN_TO));
let asset_id = ContractId::from(__gtf::<b256>(output_index, GTF_OUTPUT_COIN_ASSET_ID));
let amount = output_amount(output_index);
(to == RECEIVER) && (amount == ASK_AMOUNT) && (asset_id == ASK_TOKEN)
}
```
---
```mermaid
graph TD;
A[UTXO validation] --> B[Signature verification]
A[UTXO validation] --> C[Predicate validation]
B[Signature verification] --> D[Script execution]
C[Predicate validation] --> D[Script execution]
```
---
## Current Limitations
* Want to change a parameter? Need a new predicate
* Want to change predicate? Need to send _all_ assets, plus update any smart contracts
* WIP: Upgradeability
* How do we know what predicates exist if code isn't public?
* Predicate announcement standard
---
## So... are predicates really stateless?
Can't access traditional smart-contract state, but UTXOs _are_ a form of state
_Example: What if we created a UTXO to represent a limit order?_
---
## So wait... are predicates just shitty smart contracts?
Smart contracts can do anything a predicate can do, right?
...but predicates can't access state, call contracts, etc?
---
# Let's talk about _state_
<style>
.container-x {
display: flex;
}
.col{
flex: 1;
text-align: center;
}
</style>
<div class="container-x">
<div class="col">
### Bitcoin State
* UTXO set
</div>
<div class="col">
### Ethereum State
* Account balances (ETH)
* Smart contract code
* Smart contract state
* Token balances
* Token approvals
* All other data
</div>
</div>
---
# State growth is a massive scaling constraint
![image.png](https://hackmd.io/_uploads/ryYchPGma.png)
---
Predicates are stateless, meaning much "lighter"
* Lower fees
* More throughput
More powerful than an account
Lighter than a smart-contract
---
## We're just scratching the surface of what's possible with predicates...
![](https://hackmd.io/_uploads/BkiTjXUU3.png =300x200)
---
Predicates + UTXOs open up a new paradigm for parallelized blockchain applications
What can you build with predicates that wasn't previously possible?
---
# Questions?
{"title":"Predicates - Istanbul","description":"View the slide with \"Slide Mode\".","contributors":"[{\"id\":\"614d3dfc-f939-4def-b3a0-c5f195aff96c\",\"add\":7921,\"del\":396}]"}