Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/109_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions fatips/109.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
| FATIP | Title | Status | Category | Author | Created |
| ----- | -------------------------- | -------- | -------- | ------------------------------------------ | ---------- |
| 108 | Gas System | WIP | Core | Sergey Bushnyak \<sergey@kompendium.co\> | 2020-02-02 |

# Stateful Contracts

## Summary
FATIP-109 introduces the characteristic of “state” to FAT smart contracts, which enables stateful composition to in-contract storage. FATIP-109 accomplishes this by using the FATIP-107 defined specialized format for storing and offloading data of arbitrary size on the Factom Blockchain through sequences of connected data blocks to allow specialized contracts for storing data. To be stateful means that some amount of storage on the chain is used to store values. This storage can be either global or local. Local storage refers to storing values in an account balance record if that account participates in the contract. Global storage is data that is specifically stored on the blockchain for the contract globally.

## Motivation

Stateless smart contracts are used to approve or reject spending or asset transfer transactions and often govern all transactions from a specific account. These types of contracts are already available as part of the FAT ecosystem.

FATIP-109 further enables the FAT ecosystem to support stateful smart contracts that hold application logic and can store and update on-chain values.

The capabilities available through the use of stateful contracts or the combination of stateful and stateless contracts significantly extend the range of decentralized application (dApp) functionalities possible on FAT and will allow developers to combine application logic and user state with the on-chain handling of tokens or various other on-chain assets. The following is a short survey of use case examples possible with adding stateful contracts to the FAT ecosystem:

- A global value required before approving escrow payments. Example, a tracking dApp storing location on the blockchain
- Dates or specific rounds specified to restrict transaction times. Example, a voting dApp storing results on-chain
- Asset or balance information from the ledger required to approve transactions. Example, a trading dApp requiring a specific token to participate
- A requirement for filling orders fully or partially. Example, a digital exchange dApp

Stateful smart contracts fundamentally function as state-holding entities. They store on-chain values for the contract globally or for individual accounts that have opted into the smart contract.
These contracts live on the blockchain and can be initiated by anyone. They are callable by users with stateful smart contract transactions. These transactions initiate the logic stored in the stateful smart contract.

## Specification

Stateful smart contracts have specific global values and per-user values. They control the logic of how these values are modified.
Stateful smart contracts are implemented with two exposed interface calls:
- `call()` function is responsible for processing all application calls to the contract, with the exception of the `close`call. This addition is responsible for implementing the majority of application logic. Like stateless contracts, this program will succeed only if one nonzero value is left on the WASM stack upon completion.
- `update()` function is used to handle internal operations and uses a `close`call to detach the smart contract from its address. This program will pass or fail the same way the `call()` does. In either function, if a global or local state variable is modified and the program fails, the state changes will not be applied.
Stateful smart contracts can create, update, and delete values in the global or local state. The number of values that can be written is limited based on how the contract was initially created. The state is represented in a key-value pair. The key and value are limited to 64 bytes of storage each for both global and local storage. These values are stored as byte slices and WASM opcodes provide read/write functionality.

FATIP-109 identifies standard internal calls. Calls to stateful smart contracts are implemented using `call()` actions. These transactions types are as follows:
- `exec()` - generic application calls to execute the `call()`
- `nullify()` - call to delete the application
- `update()`- call to update contract
- `close()` - call function can fail based on the WASM opcodes logic, to freeze contract and stop accepting other calls

### Writing State

During smart contract creation, a user needs to identify a set of key-value pairs that need to be tracked, setup the “fds” key reserved to link EntryChainId that is used for large storage and requires separate access, and uses a FATIP-107 Data Store to store contract global states.

Collection of global key-value pairs will store required data on-chain and available only by the contract creator for change, which will add updated key/value data to the end of the sequence.

Metadata structure

```
{
"data-store": "1.0",
"size": 999,
"fds": "4da6c4ba7c9f3d01a52df43ae5d67d7d8b3909babf6817463b8ceff3c74065ee",
"metadata": {
"gstate":
[ "key-1":"value1",
..
"key-N":"valueN"
..
"key-M":"valueM"
]
}
}
}
```
Collection of local key-value pairs will store required data in an attached key-value database and available values will be distributed through the synchronization process and change their state during execution on the particular node.

### Reading State

This is a read-only operation and does not allow one smart contract to modify the local/global state of another smart contract. Additionally, referenced addresses can be changed per smart contract call (transaction).

#### Local State
Local storage values are stored in the address balance record. Any address that sends a transaction to the smart contract can have its local storage modified by the smart contract as long as the address has been listed in the smart contract.
Any call to the smart contract is able to reference additional addresses which can also have their local storage manipulated for the current smart contract. These addresses which specify the application identity of the smart contract can read local values. A contract’s creator should explicitly list those addresses that are allowed read capability.

#### Global State
Global storage for the current contract can also be modified by the smart contract code. The global storage can list additional contracts able to be read.
Each internal call accepts execution requests only from the contract owner and listed smart contracts:

Examples:

```
func distribute (arg: int) {
var readGlobal = get(FA…, varName)
var newVal = readGlobal + arg
update(FA…, varName, newVal)
// tx logic
}
func main() {
// Call stateful contract from another and do something
if ( distributionDate >= currentDate)
// call function `distribute` in reward distribution contract, and assign parameter
call(FA.., distribute, 1000)
else
// do something else
}
```

Stateful Contract Lifecycle Diagram:

![img1](/assets/109_1.png)

## Implementation
WASM-metering The metering counts computation time for a given program in units of gas.
FAASM a high-performance stateful serverless runtime.

## Copyright
Copyright and related rights waived via CC0.