Skip to content
Open
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
76 changes: 76 additions & 0 deletions fatips/110.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
| FATIP | Title | Status | Category | Author | Created |
| ----- | -------------------------- | -------- | -------- | ------------------------------------------ | ---------- |
| 110 | Cross-Contract Calls | WIP | Core | Sergey Bushnyak \<sergey@kompendium.co\> | 2020-02-02 |

# Cross-Contract Calls

## Summary
This standard updates FATIP-104 to extend FAT smart contract functionality by adding the ability for smart contracts to conduct external cross-contract calls. This standard uses a FATIP-107 Data Store to host contract code and specify a cross-contract Application Binary Interface (ABI). All functionality defined in this standard is built on top of the content, metadata, and name Ids of the FATIP-107 data storage definition.

## Motivation
FATIP-110 was developed to increase the versatility of FAT smart contracts to expand the variety and quantity of use case solutions serviceable with FAT/Factom. The ability for a smart contract to call functions of other contracts and to create and deploy additional contracts opens a large variety of composable solutions not previously possible with FAT.

One considerable improvement made available by FATIP-110 is the introduction of an ability to upgrade deployed FAT smart contracts. Due to the immutable nature of the blockchain, it’s not possible to change the code of a deployed smart contract; however, by using the FATIP-110-enabled mechanisms for delegating calls, a proxy contract can be deployed pointing (delegating function calls) to an external contract to upgrade the business logic governing the original deployed contract.

This mechanism provides this capability by furnishing a different target address to the proxy contract, for example, a newly deployed version of the target contract with fixes to original contract bugs. The same principle can be leveraged to use other contracts as libraries, thus reducing deployment costs, as the contract could leverage all the benefits of library accessibility without the costly requirement of including the entire library within the contract code itself.

A second considerable improvement enabled by FATIP-110 is the ability of smart-contracts to be used as a data store proxy under the system defined within FATIP-109. This introduces the capability to separate contract logic and contract data into different smart contracts. By being separate, the logic-contract could be updated via proxy while retaining all the relevant states within the data-contract. Being able to call and create contracts from other smart contracts is a powerful concept that will significantly extend the possible functionalities available within the FAT ecosystem.

## Specification

FATIP-110 extends the FAT ecosystem smart contract calling functionality by providing the ability to do cross-contract calls and identify functions that need to be called.
- `call` - executes code of another contract, already defined in the FAT
- `delegate_call` - executes code of another contract, but with the state (storage) of the calling contract. It uses FATIP-107 as the storage foundation system.

Note: In order to support additional calls between contracts, the system requires a gas-mechanism such as described within FATIP-108; a typical call could appear as:

`someAddress.delegatecall.gas(100).value(1).("register", "Kompendium")`

For direct gas entry and
`someAddress.delegatecall.gasEstimate().value(1).("register", "Kompendium")`

For a call with dynamic gas estimation, as described in FATIP-108, users will need to apply an estimation function which calculates gas based on: the complexity of the call, length of the function and the number of potentially executed WASM operations, and the functioning capacity of the particular chain’s latest 5 blocks. Further details are available within FATIP-108.

## Implementation

### Content Metadata Object
FATIP-107 stipulates that the metadata of the datastore contents object should define the smart contract's ABI. The contract’s structure is further extended by definitions within FATIP-108 and FATIP-109 that introduce a gas-mechanism for network contract execution and stateful contracts that includes enhanced contract storage to enable smart contracts to hold data without corresponding and colocated logic.
When defining ABI for the contract there is no limit to the number of functions that can be held in a smart contract or respective arguments; however, the datastore content object must be less than Factom's per-entry size limit of 10KB and if it’s used specifically as data beacon, it should leverage FATIP-107’s data storage specification.

### Application Binary Interface (ABI)
The ABI is a structure that defines how the higher-level smart contract platform interfaces with the lower-level binary WebAssembly (WASM) code. At its heart, a WASM Virtual Machine is a very low-level machine that requires instruction to interpret more complex data types such as strings from the host environment and vice versa.
The ABI is defined in the root of the metadata key within the Content Metadata Object. All fields are inherited and comply with FATIP-107's Content Metadata Object definitions.
### Content Metadata Object Example
```
{ "data-store": "1.0"
, "size": 999
, "dbi-start": "4da6c4ba7c9f3d01a52df43ae5d67d7d8b3909babf6817463b8ceff3c74065ee"
, "metadata": { "delegate":"5bc6c4ba7c9f3d01a52df43ae5d67d7d8b3909bab"
"_add":{ "args":[ "i32", "i32" ]
, "returns":"i32"

} } }
```

Supported Arguments and Return Types
- i32 - 32 Bit integer
- i64 - 64 Bit integer
- string - i32 pointer to an array of null-terminated character bytes in linear memory
- array[i32] - i32 pointer to an array of i32 bytes in linear memory
- array[i64] - i32 pointer to an array of i64 bytes in linear memory

### Functions
For a contract function to be externally callable by a separate contract the function must exist within the ABI object. Typically at the code level, C-language compilers and linkers will append an underscore onto the function name when making an exported function available. For example, in C add(int x) will be exported as `_add`.
It is only possible to derive a function's name and not its signature from a WASM binary. The publisher must declare the proper function argument types, counts, and ordering within the ABI to avoid undefined behaviors. A valid ABI defines all used functions; if the interface does not define a function that is part of the contract then that function falls within a `private` scope.

### Contract Validation
A contract residing in the FATIP-107 Data Store must be properly validated to be considered an acknowledged and recognized FAT-compatible contract: the resulting data must be a valid WASM binary. All functions defined inside the ABI must be present in the compiled contract and externally callable by the host environment. However, within a valid FAT-compatible contract all internal or external functions within the compiled contract are not required to be defined within the ABI.
Validation of each separate contract ensures cross-call validation, users need to be sure that versioning of the ABI stays the same due to potential changes in smart contracts. So, if both WASM binaries validate and expose external delegate calls we consider them valid.


## Implementation
WABT WASM-validation command-line tool is the best way of validating
WASM binaries and to identify their correctness.

## Copyright
Copyright and related rights waived via CC0.