## Predicates are the new Contracts
<br />
![image](https://hackmd.io/_uploads/rJxODUXsQ0.png =x100)
<br />
David Mihal (@dmihal)
Senior Architect
https://hackmd.io/@dmihal/predicates-v3
---
## Blockchains are getting heavy
---
<style >
img {
max-height: 90vh !important;
}
</style>
![image](https://hackmd.io/_uploads/rkkxCMcXA.png)
---
### What happens when a blockchain gets heavy?
---
![image.png](https://hackmd.io/_uploads/ryYchPGma.png)
---
![blockchain-cycle.excalidraw](https://hackmd.io/_uploads/BJM18E570.png)
---
![image](https://hackmd.io/_uploads/rkkxCMcXA.png)
---
### How do we break the cycle?
---
### How do we break the cycle?
### Make a chain that doesn't grow as quickly
---
### We need to change the way we build applications
---
# Let's rewind a bit
---
## Bitcoin has:
* Coins
* Accounts
<br />
<br />
```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"];
}
subgraph cluster_UTXO1 {
label = "UTXO";
labeljust = "l";
fontname = "Arial";
color = "#A9D0F5";
style = "rounded,filled";
fillcolor = "#D6EAF8";
UTXO2 [label="0.2 BTC\nOwner: 12higD...Wv"];
}
subgraph cluster_UTXO2 {
label = "UTXO";
labeljust = "l";
fontname = "Arial";
color = "#A9D0F5";
style = "rounded,filled";
fillcolor = "#D6EAF8";
UTXO3 [label="0.15 BTC\nOwner: b1cDh...4a"];
}
}
```
---
## Bitcoin account types
<style>
.container-x {
display: flex;
}
.col{
flex: 1;
text-align: center;
}
</style>
<div class="container-x">
<div class="col">
### Public keys
_Pay to public-key hash (P2PKH)_
<br />
Spend coins by signing the transaction with the associated private key.
</div>
<div class="col">
### Scripts
_Pay to script hash (P2SH)_
<br />
Spend the coins by providing a script that:
- Bytecode hashes to the address
- Executes successfully
</div>
</div>
---
### "Create" a script
![p2sh.excalidraw](https://hackmd.io/_uploads/SJWuUcqXA.png =x450)
_Notice we never sent the code?_
---
## "Run" a script
Provide a transaction with:
- Input coins
- Matching script bytecode
- Any script inputs (signatures, etc)
The script is _still_ never stored in the chain state.
---
## What goes into "state"?
<div class="container-x">
<div class="col">
### Bitcoin
* UTXOs<br />(amount & owner)
</div>
<div class="col">
### Ethereum
* Accounts<br />(ETH balance & nonce)
* Contract bytecode
* Contract storage
</div>
</div>
---
Can we combine the lightweight simplicity of Bitcoin with the power & expressivity of Ethereum?
---
![image](https://hackmd.io/_uploads/SJK395qXC.png)
---
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
---
## Let's look at some example predicates
---
## 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
}
```
---
### We've built predicate-based accounts...
### Can we build predicate-based apps?
---
## Predicate-based limit order?
```
fn main() {
// I'll give you any of my ETH IF:
// - You send 3800 USDC to David for each ETH you take
// - Or your name is David Mihal
}
```
---
![predicate-limit-order.excalidraw](https://hackmd.io/_uploads/r1PxPMjmC.png)
---
### Predicates can pay gas
---
## Gas-sponsoring predicate
```
fn main() {
// I'll let you spend my ETH on gas if:
// - You hold a Pudgy Penguin NFT
// - AND your transaction is playing PudgyWorld
}
```
---
### Let's dig into what a predicate is
---
## 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
---
### Predicates are executed _before_ any smart contracts
Fuel transaction lifecycle:
1. Check inputs exist
2. Check input/output amounts add up
3. Check normal signatures
4. **Execute predicates**
5. Execute script (smart-contract calls)
---
## Are predicates intents?
![image](https://hackmd.io/_uploads/Hy6P-fsQ0.png)
---
| | Rigid | Flexible |
| ----------- | -------------- | --------- |
| **Account** | Public Key/EoA | Predicate |
| **Action** | Transaction | Intent |
---
### But... you can use predicates to _build_ intent-powered accounts
---
### What else can we do with predicates?
![image](https://hackmd.io/_uploads/HyRr2fiXR.png)
---
## Predicates are key for<br />"State-Rehydration"
_**State-Rehydration**:<br />The technique of storing minimal state-commitments on-chain, and including the full state inside transactions._
---
### Predicates _already_ "rehydrate" code
![state-rehydration-code.excalidraw](https://hackmd.io/_uploads/HymTgQsXA.png)
---
### Full state-rehydration
![state-rehydration-dynamic.excalidraw](https://hackmd.io/_uploads/By5fWQjQR.png)
---
### Full state-rehydration with predicates & UTXOs
* State commitments inside UTXO asset IDs
* State commitments inside predicate configurable values
---
## Uniswap V2 Predicate
```rust
configurables {
ASSET_A: AssetId = AssetId::zero(),
ASSET_B: AssetId = AssetId::zero(),
RESERVE_A: u64 = 0,
RESERVE_B: u64 = 0,
TOTAL_LIQUIDITY: u64 = 0,
}
fn main() {...}
```
---
![predicate-univ2.excalidraw](https://hackmd.io/_uploads/H16_FEjXR.png)
---
![predicate-univ2-transition.excalidraw](https://hackmd.io/_uploads/Bk5EKVs70.png)
---
![roulette](https://hackmd.io/_uploads/ryYJG7sX0.jpg)
---
## What have we achieved by this?
An architecture for decentralized apps that are _sustainably_ fast and cheap.
An architecture for blockchains that can _stay decentralized_.
---
### That's our mission at Fuel
![image](https://hackmd.io/_uploads/rJxODUXsQ0.png)
{"contributors":"[{\"id\":\"614d3dfc-f939-4def-b3a0-c5f195aff96c\",\"add\":7483,\"del\":2443}]","breaks":true,"description":"View the slide with \"Slide Mode\".","title":"Predicates are the new Contracts"}