diff --git a/assets/109_1.png b/assets/109_1.png new file mode 100644 index 0000000..d48d94f Binary files /dev/null and b/assets/109_1.png differ diff --git a/fatips/109.md b/fatips/109.md new file mode 100644 index 0000000..7e0f678 --- /dev/null +++ b/fatips/109.md @@ -0,0 +1,107 @@ +| FATIP | Title | Status | Category | Author | Created | +| ----- | -------------------------- | -------- | -------- | ------------------------------------------ | ---------- | +| 108 | Gas System | WIP | Core | Sergey Bushnyak \ | 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.