Skip to content

Commit

Permalink
26, 27,28
Browse files Browse the repository at this point in the history
  • Loading branch information
OCTO-FRAH committed Aug 18, 2020
1 parent bb1794b commit e1dc4b0
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 142 deletions.
55 changes: 23 additions & 32 deletions src/frontend/src/pages/Chapters/Camel/ChapterFA20/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@

## Definition

There are multiple dimensions and considerations while implementing a particular token smart contract. Tokens might be fungible or non-fungible. A variety of permission policies can be used to define how many tokens can be transferred, who can initiate a transfer, and who can receive tokens. A token contract can be designed to support a single token type (e.g. ERC-20 or ERC-721) or multiple token types (e.g. ERC-1155) to optimize batch transfers and atomic swaps of the tokens.
There are multiple considerations while implementing a particular token smart contract. Tokens might be fungible or non-fungible. A variety of permission policies can be used to define how many tokens can be transferred, who can initiate a transfer, and who can receive tokens. A token contract can be designed to support a single token type (e.g. ERC-20 or ERC-721) or multiple token types (e.g. ERC-1155) to optimize batch transfers and atomic swaps of the tokens.

The FA2 standard proposes a _unified token contract interface_ that accommodates all mentioned concerns. It aims to provide significant expressivity to contract developers to create new types of tokens while maintaining a common interface standard for wallet integrators and external developers.

In the following chapter on Financial Application 2.0 , we will focus on _TZIP-12_ which stands for the 12th Tezos Improvement Proposal (same as EIP-721 for Ethereum).

## Architecture

FA2 proposes to leave it to implementers to handle common considerations such as defining the contract’s token type(s) (e.g. non-fungible vs. fungible vs. semi-fungible), administration and whitelisting, contract upgradability, and supply operations (e.g. mint/burn).
The FA2 standard proposes to leave it to implementers to handle common considerations such as defining the contract’s token type(s) (e.g. non-fungible vs. fungible vs. semi-fungible), administration and whitelisting, contract upgradability, and supply operations (e.g. mint/burn).

FA2 also leaves to implementers to decide on architecture pattern for handling permissioning. Permission can be implemented
The FA2 standard also leaves to implementers to decide on architecture pattern for handling permissioning. Permission can be implemented

- in the the same contract as the core transfer behavior (i.e. a “monolith”),
- in a transfer hook to another contract,
- in a separate wrapper contract.

## Interface and library

The FA2 interface formalize a standard way to design tokens and thus describes a list of entry points (that must be implemented) and data structures related to those entry points. A more detailed decription of the interface is broken down in following sections.
The FA2 interface formalizes a standard way to design tokens and thus describes a list of entry points (that must be implemented) and data structures related to these entry points. A more detailed decription of the interface is broken down in following sections.

In addition to the FA2 interface, the FA2 standard provides helper functions to manipulate data structures involved in FA2 interface. The FA2 library contains helper functions for :

Expand Down Expand Up @@ -50,12 +50,11 @@ type fa2_entry_points =

### Metadata

<!-- prettier-ignore -->FA2 token contracts MUST implement the *token\_metadata* entry point which get the metadata for multiple token types.
<!-- prettier-ignore -->FA2 token contracts MUST implement the *token\_metadata* entry point which gets the metadata for multiple token types.

<!-- prettier-ignore -->It accepts a list of *token\_ids* and a callback contract, and sends back a list of *token\_metadata* records.

FA2 token amounts are represented by natural numbers (nat), and their granularity (the smallest amount of tokens which may be minted, burned, or
transferred) is always 1.
FA2 token amounts are represented by natural numbers (nat), and their granularity (the smallest amount of tokens which may be minted, burned, or transferred) is always 1.

The _decimals_ property is the number of digits to use after the decimal point when displaying the token amounts. If 0, the asset is not divisible. Decimals are used for display purposes only and MUST NOT affect transfer operation.

Expand All @@ -80,7 +79,7 @@ type token_metadata_param = {

### Balance of

<!-- prettier-ignore -->FA2 token contracts MUST implement the _Balance of_ entry point which get the balance of multiple account/token pairs (because FA2 supports mutiple token).
<!-- prettier-ignore -->FA2 token contracts MUST implement the _Balance of_ entry point which gets the balance of multiple account/token pairs (because FA2 supports multiple token).

```
| Balance_of of balance_of_param
Expand Down Expand Up @@ -115,7 +114,7 @@ type balance_of_param = {

### Totalsupply

FA2 token contracts MUST implement the _Totalsupply_ entry point which get the total supply of tokens for multiple token types (because FA2 supports mutiple token).
FA2 token contracts MUST implement the _Totalsupply_ entry point which gets the total supply of tokens for multiple token types (because FA2 supports multiple token).

```
| Total_supply of total_supply_param
Expand Down Expand Up @@ -145,7 +144,7 @@ type total_supply_param = {

### Transfer

FA2 token contracts MUST implement the _Transfer_ entry point which transfer tokens between and MUST ensure following rules.
FA2 token contracts MUST implement the _Transfer_ entry point which transfers tokens between owners and MUST ensure following rules.

```
| Transfer of transfer list
Expand All @@ -157,20 +156,15 @@ FA2 token contracts MUST implement the transfer logic defined by the following r

1. Every transfer operation MUST be atomic. If the operation fails, all token transfers MUST be reverted, and token balances MUST remain unchanged.

2. The amount of a token transfer MUST NOT exceed the existing token owner's balance. If the transfer amount for the particular token type and token owner
exceeds the existing balance, the whole transfer operation MUST fail with the error mnemonic "INSUFFICIENT_BALANCE"
2. The amount of a token transfer MUST NOT exceed the existing token owner's balance. If the transfer amount for the particular token type and token owner exceeds the existing balance, the whole transfer operation MUST fail with the error mnemonic "INSUFFICIENT_BALANCE"

3. Core transfer behavior MAY be extended. If additional constraints on tokens transfer are required, FA2 token contract implementation MAY invoke additional
permission policies (transfer hook is the recommended design pattern to implement core behavior extension). (See Chapter FA2 - Hook)
3. Core transfer behavior MAY be extended. If additional constraints on tokens transfer are required, FA2 token contract implementation MAY invoke additional permission policies (transfer hook is the recommended design pattern to implement core behavior extension). (See Chapter FA2 - Hook). If the additional permission hook fails, the whole transfer operation MUST fail with a custom error mnemonic.

If the additional permission hook fails, the whole transfer operation MUST fail with a custom error mnemonic.

4. Core transfer behavior MUST update token balances exactly as the operation parameters specify it. No changes to amount values or additional transfers are
allowed.
4. Core transfer behavior MUST update token balances exactly as the operation parameters specify it. No changes to amount values or additional transfers are allowed.

#### Interface

It transfer tokens from a _from\__ account to possibly many destination accounts where each destination transfer describes the type of token, the amount of token, and receiver address.
It transfers tokens from a _from\__ account to possibly many destination accounts where each destination transfer describes the type of token, the amount of token, and receiver address.

```
type token_id = nat
Expand All @@ -196,8 +190,7 @@ type transfer_aux = {

### Error Handling

This FA2 tandard defines the set of standard errors to make it easier to integrate FA2 contracts with wallets, DApps and other generic software, and enable
localization of user-visible error messages.
This FA2 standard defines the set of standard errors to make it easier to integrate FA2 contracts with wallets, DApps and other generic software, and enable localization of user-visible error messages.

Each error code is a short abbreviated string mnemonic. An FA2 contract client (like another contract or a wallet) could use on-the-chain or off-the-chain registry to map the error code mnemonic to a user-readable, localized message.

Expand All @@ -210,25 +203,23 @@ When error occurs, any FA2 contract entry point MUST fail with one of the follow

#### Standard error mnemonics:

Error mnemonic - Description

<!-- prettier-ignore -->"TOKEN_UNDEFINED" - One of the specified *token\_ids* is not defined within the FA2 contract
<!-- prettier-ignore -->"*TOKEN\_UNDEFINED*" - One of the specified *token\_ids* is not defined within the FA2 contract

"INSUFFICIENT_BALANCE" - A token owner does not have sufficient balance to transfer tokens from owner's account
<!-- prettier-ignore -->"*INSUFFICIENT\_BALANCE*" - A token owner does not have sufficient balance to transfer tokens from owner's account

<!-- prettier-ignore -->"TX_DENIED" - A transfer failed because of *operator\_transfer\_policy* == *No\_transfer*
<!-- prettier-ignore -->"*TX\_DENIED*" - A transfer failed because of *operator\_transfer\_policy* == *No\_transfer*

<!-- prettier-ignore -->"NOT_OWNER" - A transfer failed because *operator\_transfer\_policy* == *Owner\_transfer* and it is initiated not by the token owner
<!-- prettier-ignore -->"*NOT\_OWNER*" - A transfer failed because *operator\_transfer\_policy* == *Owner\_transfer* and it is initiated not by the token owner

<!-- prettier-ignore -->"NOT_OPERATOR" - A transfer failed because *operator\_transfer\_policy* == *Owner\_or\_operator\_transfer* and it is initiated neither by the token owner nor a permitted operator
<!-- prettier-ignore -->"*NOT\_OPERATOR*" - A transfer failed because *operator\_transfer\_policy* == *Owner\_or\_operator\_transfer* and it is initiated neither by the token owner nor a permitted operator

"RECEIVER_HOOK_FAILED" - The receiver hook failed. This error MUST be raised by the hook implementation
<!-- prettier-ignore -->"*RECEIVER\_HOOK\_FAILED*" - The receiver hook failed. This error MUST be raised by the hook implementation

"SENDER_HOOK_FAILED" - The sender failed. This error MUST be raised by the hook implementation
<!-- prettier-ignore -->"*SENDER\_HOOK\_FAILED*" - The sender failed. This error MUST be raised by the hook implementation

"RECEIVER_HOOK_UNDEFINED" -Receiver hook is required by the permission behavior, but is not implemented by a receiver contract
<!-- prettier-ignore -->"*RECEIVER\_HOOK\_UNDEFINED*" -Receiver hook is required by the permission behavior, but is not implemented by a receiver contract

"SENDER_HOOK_UNDEFINED" - Sender hook is required by the permission behavior, but is not implemented by a sender contract
<!-- prettier-ignore -->"*SENDER\_HOOK\_UNDEFINED*" - Sender hook is required by the permission behavior, but is not implemented by a sender contract

## Your mission

Expand Down
34 changes: 18 additions & 16 deletions src/frontend/src/pages/Chapters/Camel/ChapterInterop/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

<dialog character="alien">We need to hack aliens, decompile their code to understand how their informatic works </dialog>

LIGO can work together with other smart contract languages on Tezos. However data structures might have different representations in Michelson and not correctly match the standard LIGO types.
Tezos smart contracts are written in Michelson language. The LIGO transpiler helps developers to produce Michelson scripts. However LIGO data structures might have different representations in Michelson. For example, LIGO allows to define a record (a structure containing many fields) but once transpiled in Michelson this record is transformed in a pair of pairs, and there can be many pairs of pairs representing the same record.

In this chapter, we will see that some built-in functions are available in LIGO language in order to address this problem.

## Annotations

Expand All @@ -27,7 +29,7 @@ will accept these definitions and fail with the ones that does not respect the t

### Entrypoints and annotations

<!-- prettier-ignore -->As seen in chapter Polymorphism, a contract can be called by another contract. The predefined function *Tezos.get\_entrypoint\_opt* allows to call a specific entry point of the called contract.
<!-- prettier-ignore -->As seen in the chapter Polymorphism, a contract can be called by another contract. The predefined function *Tezos.get\_entrypoint\_opt* allows to call a specific entry point of the called contract.

Here is an example. Let's consider the following "Counter" contract :

Expand All @@ -45,7 +47,7 @@ let main ((p, x): (parameter * storage)): (operation list * storage) =
))
```

Thre following contract sends a transaction to the "Counter" contract.
The following contract sends a transaction to the "Counter" contract.

```
type storage = int
Expand All @@ -66,15 +68,15 @@ let main (p, s: parameter * storage): operation list * storage = (
)
```

⚠️ Notice how we directly use the _%left_ entrypoint without mentioning the _%right_ entrypoint. This is done with the help of annotations. Without annotations it wouldn't be clear what our int would be referring to.
⚠️ Notice how we directly use the _%left_ entry point without mentioning the _%right_ entry point. This is done with the help of annotations. Without annotations it wouldn't be clear what our _int_ would be referring to.

These annotations works for _or_'s or _variant_ types in LIGO.
These annotations work for _or_'s or _variant_ types in LIGO.

## Interop with Michelson
## Interoperability with Michelson

<!-- prettier-ignore -->To interop with existing Michelson code or for compatibility with some development tooling, LIGO has two special interop types: *michelson\_or* and *michelson\_pair*. These types give the flexibility to model the exact Michelson output, including field annotations.
<!-- prettier-ignore -->To interoperate with existing Michelson code or for compatibility with some development tooling, LIGO has two special interoperability types: *michelson\_or* and *michelson\_pair*. These types give the flexibility to model the exact Michelson output, including field annotations.

Take for example the following Michelson type that we want to interop with:
Take for example the following Michelson type that we want to interoperate with:

```
(or
Expand Down Expand Up @@ -114,7 +116,7 @@ let x: z_or = (M_right (y_1) : z_or)

## Helper functions

Conversions from Ligo types to Michelson types require a precise knowledge of data structures representation.
Conversions from Ligo types to Michelson types require a precise knowledge of the representation of data structures.

So it becomes even more relevant with nested pairs because there are many possible decompositions of a record in pairs of pairs.

Expand Down Expand Up @@ -158,7 +160,7 @@ Converting between different LIGO types and data structures can happen in two wa

#### Pair

<!-- prettier-ignore -->Conversion between the Michelson type and record type is handled with the functions *Layout.convert\_from\_left\_comb* and *Layout.convert\_to\_left\_comb*.
<!-- prettier-ignore -->Conversion between the Michelson type and record type is handled with functions *Layout.convert\_from\_left\_comb* and *Layout.convert\_to\_left\_comb*.

Here's an example of a left combed Michelson data structure using pairs:

Expand All @@ -184,24 +186,24 @@ type l_record = {

This snippet of code shows

<!-- prettier-ignore -->\* how to use *Layout.convert\_from\_left\_comb* to transform a Michelsontype into a record type.
<!-- prettier-ignore -->\* how to use *Layout.convert\_to\_left\_comb* to transform a record type into a Michelsontype.
<!-- prettier-ignore -->\* how to use *Layout.convert\_from\_left\_comb* to transform a Michelson type into a record type.
<!-- prettier-ignore -->\* how to use *Layout.convert\_to\_left\_comb* to transform a record type into a Michelson type.

```
type Michelson= l_record michelson_pair_left_comb
type Michelson = l_record michelson_pair_left_comb
let of_michelson (f: michelson) : l_record =
let p: l_record = Layout.convert_from_left_comb f in
p
let to_michelson (f: l_record) : Michelson=
let to_michelson (f: l_record) : Michelson =
let p = Layout.convert_to_left_comb (f: l_record) in
p
```

#### Variant

<!-- prettier-ignore -->In the case of a left combed Michelson or data structure, that you want to translate to a variant, you can use the *michelson\_or\_left\_comb* type.
<!-- prettier-ignore -->In the case of a left combed Michelson or a data structure, that you want to translate to a variant, you can use the *michelson\_or\_left\_comb* type.

```
type vari =
Expand Down Expand Up @@ -286,6 +288,6 @@ let make_abstract_record (z: string) (y: int) (x: string) (w: bool) (v: int) : t

## Your mission

We want you to modify our "inventory" contract. As you can see the storage is mainly composed of an item inventory where each item is a right combed nested pairs. The contract possess a single entry point AddInventory. This _AddInventory_ function adds each element in the inventory (don't worry about duplicates it has already been taken care of).
We want you to modify our "inventory" contract. As you can see the storage is mainly composed of an item inventory where each item is a right combed nested pairs. The contract possesses a single entry point AddInventory. This _AddInventory_ function adds each element in the inventory (don't worry about duplicates it has already been taken care of).

<!-- prettier-ignore -->1- Complete the implementation of the *update\_inventory* lambda function. This function takes a list of item as parameter and must transform each item in a combed pair structure and add this resulting structure in the storage inventory. (When naming your temporary variables, use *acc* for the accumulator name and *i* for the current item)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<dialog character="mechanics"></dialog>

Instead of writing the whole code in a single file, it is possible to split code into different files and include some external code into our file. The pre-processor is responsible to handle code inclusion. While working with multiple files we may encounter a problem of cyclic inclusion. To prevent such situation some pre-processor commands are available.
Instead of writing the LIGO code in a single file, it is possible to split the code into different files and include some external code into our file. The pre-processor is responsible for handling code inclusion. While working with multiple files we may encounter a problem of cyclic inclusion. To prevent such situation some pre-processor commands are available.

* #if
* #define
Expand Down Expand Up @@ -53,7 +53,7 @@ let substr_special (s: string) : string =

⚠️ Notice that the conditionnal *#if* can be used to customize your includes.

⚠️ Notice that this pattern prevents from redefinition in case of cyclic inclusion.
⚠️ Notice that this pattern prevents variable or type redefinition in case of cyclic inclusion.

```
#if !X
Expand Down
Loading

0 comments on commit e1dc4b0

Please sign in to comment.