Skip to content
60 changes: 54 additions & 6 deletions fatips/0.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ and so are ignored to prevent replay attacks.
| --------- | ------ | ------------------------------------- | ------------------------------------------------------------ | -------- |
| `inputs` | object | The inputs of the transaction | Mapping of Public Factoid Address => Amount. Amount must be am integer greater than or equal to zero. May not be empty or contain duplicate Addresses. | Y |
| `outputs` | object | The outputs of the transaction | Mapping of Public Factoid Address => Amount. Amount must be am integer greater than or equal to zero. May not be empty or contain duplicate Addresses. May overlap with addresses found in `inputs` to form a send-to-self transaction. Sum of the Amounts must equal the sum of the `inputs` Amounts. | Y |
| | | | | |
| `contract` | string | The contract publication chain to use to establish a contract at output address 0 | Valid Factom chain ID. Valid [FATIP-104](104.md) contract datastore. May not be specified alongside `func` or `args`. See [Contract Publication Transactions](#Contract-Publication-Transactions). | N |
| `func` | string | The full function name to call | Function must exist in the ABI of the contract at `contract`. Must be specified with `args`. See [Contract Call Transactions](#Contract-Call-Transactions). | N |
| `args` | array | The array of arguments to call `func` with | Arguments must comply with the function signature argument types specified in the ABI at `contract`. Must be specified with `func`. See [Contract Call Transactions](#Contract-Call-Transactions). | N |
| | | | | |
| `metadata` | any | Optional metadata defined by user | This may be any valid JSON type. | N |

For a Transaction to be well-formed it must follow the above defined structure
Expand Down Expand Up @@ -246,6 +251,22 @@ described above, but with the Coinbase Address as the sole input in the
output addresses may not intersect. Thus a Coinbase Transaction may not
directly burn the tokens it issues.

### Contract Publication Transactions

Contract Publication Transactions are transactions that establish a WASM based smart contract at a given Factoid address. Establishing a contract at an address removes the address from human control and delegates control of the address to the contracts code.

Contract publication transactions are identified by a zero amount input-output transaction from the desired contract address to itself, while specifying the `contract` key value pair in the Transaction JSON. The `contract` field specifies the [FATIP-104](104.md) contract chain to use at the address.

An address may hold a balance of FAT-0 tokens before having a contract established, allowing contracts to have a starting balance.

### Contract Call Transactions

Contract Call Transactions are transactions that call a specific function with given arguments inside of a contract established at an address. The field `func` and `args` are used to carry the intended function to call and the arguments to call it with.

To call a contract, a single-input single-output transaction is constructed with the output being the contract Factoid address and `func` & `args` in the main JSON body. A nonzero amount of FAT-0 tokens may be sent in the transaction to denote a fee or other use of tokens.

Normal transactions may be sent to a contract address without `func` & `args` to deposit tokens to the contract address.

#### Coinbase Signing Set

A signature from the current key establised by the Issuer's Identity key is
Expand Down Expand Up @@ -291,7 +312,7 @@ Normal transactions must meet all T.x and N.x requirements.
[FATIP-103](103.md). No additional RCD/Signature pairs beyond those that
correspond with an input may be included.

### C.x Requirements for Coinbase distribution transactions
### C.x Requirements for Coinbase transactions

Coinbase transactions must meet all T.x and C.x requirements.

Expand All @@ -302,26 +323,53 @@ Issuance entry (if not unlimited).
- C.3.1: The entry must be signed by the Issuer's currently established key in
the Identity chain according to [FATIP-101](101.md) and [FATIP-103](103.md).

### CP.x Requirements for Contract Publication Transactions

Contract Publication Transactions must meet all T.x and CP.x requirements.

- The target address must be the only input
- The target address must be the only output
- The sum of all amounts must equal zero
- The target address may not already have a contract established on it
- The contract at `contract` must pass all validation, `func` and `args` may not be specified

### CC.x Requirements for Contract Call Transactions

Contract Publication Transactions must meet all T.x and CC.x requirements.

- The calling address must be the only input
- The target address must be the only output
- The target address must already have a contract established on it
- The `func` and `args` field must be present and pass validation. The `func` and `args` submitted must match and comply with the function signature of `func`'s `args` specified in the contract ABI.



## Computing the Current State

Implementations must maintain the state of the balances of all addresses in
order to evaluate the validity of a transaction. The current state can be built
by iterating through all entries in the token chain in chronological order and updating the state for any valid transaction.

Additionally, implementations must maintain the state of contracts and their calls, which are conducted by FAT transactions and may affect the balances of their host token. Contracts have the ability to send, receive, and burn their host FAT tokens. Each contract call results in a return value from the function and arguments submitted, which is then persisted in the state of the contract and linked to the transaction. Thus, the result of a contract call is obtained and identified by it's transaction entryhash.

The following pseudo code describes how to compute the current state of all
balances. A transaction must be applied entirely or not at all. Entries that
are not valid transactions are simply ignored. Transactions must be evaluated
in the order that they appear in the token chain. This assumes the token has
already been properly initialized.
are not valid transactions are simply ignored. Contract call results, including errors stemming from Contract Call Transactions are independent of transaction validity, and are persisted in the implementation for later retrieval. Transactions must be evaluated in the order that they appear in the token chain. This assumes the token has already been properly initialized.

```
for entry in token_chain.entries:
if entry.is_valid_transaction():
if !entry.is_coinbase_transaction():
for input in entry.inputs:
balances[input.address] -= input.amount
for output in entry.outputs:
balances[output.address] += output.amount
for output in entry.outputs:
balances[output.address] += output.amount
else balances[entry.outputs[0]] += output.amount

if entry.is_contract_call():
transaction.result = token_chain.contracts[entry.inputs[0]][func](args...)
else if entry.is_contract_publication():
token_chain.contracts[entry.inputs[0]] = entry.contract
```

# Implementation
Expand Down
124 changes: 124 additions & 0 deletions fatips/104.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
| FATIP | Title | Status | Category | Author | Created |
| ----- | ----------------------------- | ------ | -------- | --------------------------------- | --------- |
| 104 | Contract Publication Standard | WIP | Core | Devon Katz\<<devonk@dbgrow.com>\> | 9-16-2019 |



# Summary

This standard describes a type of FATIP-107 Factom Data Store with specialized validation used to publish WebAssembly(WASM) contract bytecode to a Factom chain. This standard is used in conjunction with FATIP-0 to establish contracts at Factoid addresses, which then can be interacted with by users of FAT via transactions.

An Application Binary Interface(ABI) object structure is defined in this standard. The ABI lists the functions and arguments are available to be called in the contract, as well return types of those functions and is critical for interacting with contracts.

# Motivation

Our [proof of
concept](https://github.com/Factom-Asset-Tokens/wasm-contract-poc) successfully
demonstrated that raw WASM bytecode could successfully be stored published and
interpreted from the External Ids of Factom entry. While effective, this simple
system created a hard limit of 10KB in contract size as it used a single entry.

This standard uses the robust FATIP-107 datastore standard to publish WASM contract binaries to the Factom blockchain. FATIP-107 gives contract code a dedicated chain, allowing the reuse of established
and vetted contracts by chain Id. For example, an escrow contract established by a law firm
could be implemented directly by multiple different FAT tokens & contracts at
their addresses by specifying the chain Id of the contracts compiled source
code.

# Specification

This standard uses a FATIP-107 Data Store to host contract code and specify a contract ABI. Therefore, all functionality defined in this standard is built on top of the content, metadata, and name Ids of a FATIP-107 Data Store. No additional functionality is added to FATIP-107 as a result of this standard.

## Data Block Entries

The FATIP-107 Data Store data block entries shall be filled with the complete raw byte buffer of the compiled WASM bytecode.

The total size FATIP-107 content shall be limited to 100KB or less in final on-chain size, regardless of compression. Contract bytecode may be compressed as per FATIP-107 if desired.

## Content Metadata Object

The FATIP-107 Data Store metadata residing in the content object shall be used to define the contract's Application Binary Interface.

There is no limit on the number of functions or their respective arguments; however, the datastore content object must necessarily be less than 10KB in size as per Factom's per-entry size limit.

### Application Binary Interface

The ABI is a datastructure that defines how the higher level smart contract
platform interfaces with the low level binary WASM code. At it's heart a WASM
VM is a very low level machine which needs help understanding how to interpret
more complex types like strings from the host environment, and vice versa.

The ABI is defined in the root of the `metadata` key in the Content Metadata Object. All fields are inheritied and comply to FATIP-107's Content Metadata Object requirements.

### Content Metadata Object Example

```json
{
"data-store": "1.0",
"size": 999,
"dbi-start": "4da6c4ba7c9f3d01a52df43ae5d67d7d8b3909babf6817463b8ceff3c74065ee",
"metadata": {
"_add":{
"args":[
"i32",
"i32"
],
"returns":"i32"
}
}
}
```

### Content Metadata Object Field Summary & Validation

Please note validation of fields inherited from FATIP-107 is not covered in this table.

| Name | Type | Description | Validation | Required |
| --------------------- | ------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- |
| `metadata[*]` | string | The full function name | | Y |
| `metadata[*].args` | array | The ordered array of argument types that the function signature accepts. | All elements must be strings. Must be one of the [Supported Argument And Return Types](https://github.com/Factom-Asset-Tokens/FAT/blob/FATIP-S-Smart-Contracts-And-Supporting-Standards/fatips/104.md#Supported-Arguments-and-Return-Types) | Y |
| `metadata[*].returns` | string | The type of return value to expect from the function | Must be a string. Must be one of the [Supported Argument And Return Types](https://github.com/Factom-Asset-Tokens/FAT/blob/FATIP-S-Smart-Contracts-And-Supporting-Standards/fatips/104.md#Supported-Arguments-and-Return-Types) | Y |
| | | | | |

##### 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 callable externally it must exist in the ABI
object. Typically C compilers and linkers will append an underscore onto the
function name in code when making an exported function available. For example,
in C `add(int x)` will be exported as `_add `.

Note that it is only possible to derive a function's name, not it's signature
from a WebAssembly binary. The publisher must to declare the proper function
argument types, counts, and ordering in the ABI to avoid undefined behavior.



## Contract Validation

The contract residing in the FATIP-107 Data Store must be validated to be considered a valid FAT compatible contract:

- The resulting data bust be a valid WASM binary (See this standard's [Implementation](#Implementation) section for tooling notes)
- All functions defined inside the ABI must be present in the compiled contract and externally callable by the host environment. However, it is not required that all internal or external functions in the contract be defined in the ABI so as to restrict host access to certain functions within the contract.



# Implementation

The official [WebAssembly Toolkit
(WABT)](https://github.com/WebAssembly/wabt)'s
[wasm-validate](https://webassembly.github.io/wabt/doc/wasm-validate.1.html)
command line tool is a very popular way of validating WASM binaries.


# Copyright

Copyright and related rights waived via
[CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Loading