Skip to content

Commit

Permalink
Merge branch 'master' into correction_26_30
Browse files Browse the repository at this point in the history
  • Loading branch information
frankhillard authored Aug 19, 2020
2 parents 6f5a1c7 + 401e30f commit 0c63ef3
Show file tree
Hide file tree
Showing 42 changed files with 213 additions and 200 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2020 Octo Technology

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let b : nat = abs (1)

## Addresses

The address type in LIGO denotes Tezos addresses (tz1, tz2, tz3, KT1, ...). Currently, addresses are created by casting a string to the address type. Beware of failures if the address is invalid. Consider the following examples.
The address type in LIGO denotes Tezos addresses (tz1, tz2, tz3, KT1,...). Currently, addresses are created by casting a string to the address type. Beware of failures if the address is invalid. Consider the following examples.

You can define Tezos addresses by casting a string to an address type :

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Chapter 23 : Deploy contract

<dialog character="admiral"> Time to go live.</dialog>
<dialog character="admiral">Time to deploy into the battlefield Rookie!</dialog>

## Smart contract

Expand Down
64 changes: 32 additions & 32 deletions src/frontend/src/pages/Chapters/Camel/ChapterFA12/course.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
# Chapter 25 : Financial Application 1.2

<dialog character="mechanics">Captain, why are you trying to change the part yourself? Just write a function on the terminal and send it to a droid.</dialog>
<dialog character="mechanics">Captain, we received the bill for reparing the ship after the last battle: 1,000,000 TAT. I have no idea what TAT is or its convertion rate to Tez, that's likely an alien currency, you should probably find out!</dialog>

## Definition

A Financial Application is a non-physical asset whose value is derived from a contractual claim, such as bank deposits, bonds, and stocks. Financial assets are usually more liquid than other tangible assets, such as commodities or real estate, and may be traded on financial markets.
A Financial Application represents a non-physical asset whose value is derived from a contractual claim, such as bank deposits, bonds, or stocks. Financial assets are usually more liquid than other tangible assets, such as commodities or real estate, and may be traded on financial markets.

Financial assets are opposed to non-financial assets, property rights which include both tangible property (sometimes also called real assets) such as land, real estate or commodities and intangible assets such as intellectual property, like copyrights, patents, Trademarks etc.
Financial assets are opposed to non-financial assets, such as property rights which include both tangible properties (sometimes also called real assets) such as land, real estate or commodities and intangible assets such as intellectual property like copyrights, patents, Trademarks, etc.

### Fungible and non-fungible
## Fungible and non-fungible tokens

When talking about _token_ or _crypto-currency_, it is a numerical asset emitted on a blockchain.
A _token_ or _crypto-currency_ is a numerical asset emitted on a blockchain.

Fungible means secable
Fungible means divisible.

Fungible token is a Financial Application where account balance represents the value associated to an _address_. This value can be splitted into smaller parts which can be transfered to another account.
A Fungible token is a Financial Application where the account balance represents the value associated to an _address_. This value can be splitted into smaller parts which can be transfered to another account.

Non-fungible token (NFT) is a Financial Application whose balance cannot be splitted into smaller part. Crypto-kitties is an example of non fungible token (on Ethereum blcockchain). For example, a video game avatar (such as avatar on world of warcraft) is a character having some skills/attributes (strength, dexterity, ...) one can want to sell its avatar , but cannot sell strength property of its avatar separately. It makes sense to keep tha whole avatar into a unsecable set of attributes.
A Non-fungible token (NFT) is a Financial Application whose balance cannot be splitted into smaller parts. Crypto-kitties is an example of a game using non fungible tokens (on the Ethereum blockchain). For example, a video game avatar (such as avatar on world of warcraft) is a character having some skills/attributes (strength, dexterity,...) and one may want to sell his avatar, but cannot sell the strength property of his avatar separately. It makes sense to keep the whole avatar into a undivisible set of attributes.

### Standard
## Standard

A standard is a set of rules commonly accepted by the community.
The rules of Financial Application describes how to create currencies (and how to transfer tokens between accounts).
The rules of Financial Application describe how to create currencies (and how to transfer tokens between accounts).

Depending on the usage of the currency, many sets of rules have been commonly accepted :

- Financial Application 1.2 (FA1.2) are rules for fungible token.
- Financial Application 2.0 (FA2) are rules for non fungible token.
- Financial Application 1.2 (FA1.2) is a set of rules for fungible tokens.
- Financial Application 2.0 (FA2) is a set of rules for non fungible token.

For example, the creation of a crypto-currency is equivalent to creating a contract which supports the FA1.2 standard.
All smart contracts supporting the FA12 standard can interact with account and other contracts by transfering coins of our crypto-currency.
All smart contracts supporting the FA12 standard can interact with accounts and other contracts by transfering coins of our crypto-currency.

Similarily for ethereum, fungible token rules have been specified in a Ethereum forum blog (Ethereum Request Comment) the 20th answer was describing a good rule set and the ERC20 became the name for this standard (rule set).
ERC721 is the standard rule set for non-fungible token.
Similarily for Ethereum, fungible token rules have been specified on an Ethereum forum blog (Ethereum Request Comment), the 20th answer was describing a good rule set and the ERC20 became the name for this standard (rule set).
ERC721 is the standard rule set for non-fungible tokens.

## FA1.2 (Implementation of standard)

This Fungible token standard provides basic functionality to transfer tokens, as well as to allow tokens to be approved so they can be spent by another on-chain third party.

Possible actions :
*Appove* - Sender can specify an amount of token that can be spent by someone else (from his account)
*Transfer* - Transfer an amount a token from an account to another account (or third-party on-chain smart contract)
*GetAllowance* - Return the amount that can be spent by someone from sender's account
*GetBalance* - Returns sender's account balance
*GetTotalSupply* - Returns the number total of token
_Appove_ - Sender can specify an amount of token that can be spent by someone else (from his account)
_Transfer_ - Transfer an amount of tokens from an account to another account (or third-party on-chain smart contract)
_GetAllowance_ - Return the amount that can be spent by someone from sender's account
_GetBalance_ - Return the sender's account balance
_GetTotalSupply_ - Returns the number total of token

Let's see an implementation in Ligo of a fungible token (FA1.2 standard)

Expand Down Expand Up @@ -164,33 +164,33 @@ let main (a,s:action * storage) =

Let's assume that the _TezosAcamedyToken_ has been deployed.

Consider your account is _me_ (at address tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) which has been granted 1000000 tokens.
Consider alice account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7)
Consider your account is _me_ (at address tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) which has been granted 1,000,000 tokens.
Consider alice's account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7)

<!-- prettier-ignore -->1- We want you to simulate the transfer of 2 TAT (Tezos Academy Token) to *alice*. Write a ligo command line for preparing a simulated storage where you (tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) possess 1000000 tokens and no allowances.
<!-- prettier-ignore -->1- We want you to simulate the transfer of 2 TAT (Tezos Academy Token) to *alice*. Write a ligo command line for preparing a simulated storage where you (tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) possess 1,000,000 tokens and no allowance.

<!-- prettier-ignore -->2- Write a ligo command line for preparing invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
<!-- prettier-ignore -->2- Write a ligo command line for preparing the invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.

<!-- prettier-ignore -->3- Write a ligo command line that simulate your invocation of previous *Approval* on storage prepared at step 1. (Don't forget to specify that you are sending this transaction).
<!-- prettier-ignore -->3- Write a ligo command line that simulates your invocation of previous *Approval* on storage prepared at step 1. (Don't forget to specify that you are sending this transaction).

<!-- prettier-ignore -->4- Now that ligo compiler ensured us that simulation is good, we will try to simulate it with the tezos-client command line in order to know the right amount of gas needed to run execute *approval*. You can consider that step 2 produced the following Michelson expression:
<!-- prettier-ignore -->4- Now that the ligo compiler ensured us that the simulation is good, we will try to simulate it with the tezos-client command line in order to know the right amount of gas needed to execute *approval*. You can consider that step 2 produced the following Michelson expression:

```
(Left (Left (Left (Pair "tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7" 2))))
```

<!-- prettier-ignore -->5- Write a tezos command line that simulate your invocation.
<!-- prettier-ignore -->5- Write a Tezos command line that simulates your invocation.

<!-- prettier-ignore -->6- Now that approval has been exeucted on blockchain, 2 TAT can be transfered from your address to *alice*. Write a ligo command line for preparing invocation of a *Transfer* of 2 TAT (Tezos Academy Token) from you to *alice*.
<!-- prettier-ignore -->6- Now that the approval has been executed on the blockchain, 2 TAT can be transfered from your address to *alice*'s. Write a ligo command line for preparing the invocation of a *Transfer* of 2 TAT (Tezos Academy Token) from you to *alice*.

<!-- prettier-ignore -->7- Write a ligo command line for preparing a simulated storage where you (tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) possess 1000000 of token and allowances is initialized with 2 TAT that can be transfered from *me* to *alice* (tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7).
<!-- prettier-ignore -->7- Write a ligo command line for preparing a simulated storage where you (tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) possess 1,000,000 tokens and an allowance is initialized with 2 TAT that can be transfered from *me* to *alice* (tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7).

<!-- prettier-ignore -->8- Write a ligo command line that simulate your invocation of previous *Transfer* on storage prepared at step 7. (Don't forget to specify that you are sending this transaction).
<!-- prettier-ignore -->8- Write a ligo command line that simulates your invocation of the previous *Transfer* on storage prepared at step 7. (Don't forget to specify that you are sending this transaction).

<!-- prettier-ignore -->9- Now that ligo compiler ensured us that simulation is good, we will try to simulate it with the tezos-client command line in order to know the right amount of gas needed to run execute *transfer*. You can consider that step 6 produces the following Michelson expression:
<!-- prettier-ignore -->9- Now that the ligo compiler ensured us that the simulation is good, we will try to simulate it with the tezos-client command line in order to know the right amount of gas needed to run execute *transfer*. You can consider that step 6 produces the following Michelson expression:

```
(Right (Pair (Pair "tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ" "tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7") 2))
```

<!-- prettier-ignore -->10- Write a tezos command line that simulate your *Transfer* invocation.
<!-- prettier-ignore -->10- Write a Tezos command line that simulates your *Transfer* invocation.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// Modify the code below
ligo compile-storage fa12.mligo main '{total_amount=1000000n; tokens=(Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]); allowances=(Big_map.empty: ((address*address),nat)big_map)}'
ligo compile-storage fa12.mligo main '{total_amount=1,000,000n; tokens=(Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1,000,000n)]); allowances=(Big_map.empty: ((address*address),nat)big_map)}'
// Modify the code below
ligo compile-parameter fa12.mligo main 'Approve({spender=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})'
// Modify the code below
ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.mligo main 'Approve({spender=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})' '{total_amount=1000000n; tokens=(Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]); allowances=(Big_map.empty: ((address*address),nat)big_map)}'
ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.mligo main 'Approve({spender=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})' '{total_amount=1,000,000n; tokens=(Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1,000,000n)]); allowances=(Big_map.empty: ((address*address),nat)big_map)}'
// Modify the code below
tezos-client transfer 0tz from me to TezosAcamedyToken --arg '(Left (Left (Left (Pair "tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7" 2))))' --dry-run
// Modify the code below
ligo compile-parameter fa12.mligo main 'Transfer({address_from=("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address); address_to=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})'
// Modify the code below
ligo compile-storage fa12.mligo main '{total_amount=1000000n; tokens=Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]; allowances=Big_map.literal [((("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)) ,2n)]}'
ligo compile-storage fa12.mligo main '{total_amount=1,000,000n; tokens=Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1,000,000n)]; allowances=Big_map.literal [((("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)) ,2n)]}'
// Modify the code below
ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.mligo main 'Transfer({address_from=("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address); address_to=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})' '{total_amount=1000000n; tokens=Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]; allowances=Big_map.literal [((("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)) ,2n)]}'
ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.mligo main 'Transfer({address_from=("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address); address_to=("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address); value=2n})' '{total_amount=1,000,000n; tokens=Big_map.literal [(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1,000,000n)]; allowances=Big_map.literal [((("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)) ,2n)]}'
// Modify the code below
tezos-client transfer 0tz from me to TezosAcamedyToken --arg '(Right (Pair (Pair "tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ" "tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7") 2))' --dry-run

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ When error occurs, any FA2 contract entry point MUST fail with one of the follow
- string value which represents an error code mnemonic.
- a Michelson pair, where the first element is a string representing error code mnemonic and the second element is a custom error data.

#### Standard error mnemonics:
### Standard error mnemonics:

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Some helpers functions has been gatthered in a hook library which help defining
The hook pattern depends on the permission policy. A transfer hook may be unwanted, optional or required.

<!-- prettier-ignore -->If the policy requires a owner hook then the token owner contract MUST implement an entry point "tokens\_received". Otherwise transfer is not allowed.
<!-- prettier-ignore -->If the policy optionnaly accepts a owner hook then the token owner contract MAY implement an entry point "tokens\_received". Otherwise transfer is allowed.
<!-- prettier-ignore -->If the policy Optionnaly accepts a owner hook then the token owner contract MAY implement an entry point "tokens\_received". Otherwise transfer is allowed.

It is the same for permission policies including senders, the entry point _tokens_sent_ may need to be implemented.

Expand Down Expand Up @@ -199,6 +199,7 @@ let own_policy : permissions_descriptor = {

We are working on a fungible token which can handle multiple assets. We decided to implement a _hook pattern_. A FA2 core contract handles all FA2 entry points (BalanceOf, Transfer, ...) and a hook permission contract which implements the validation of a transfer with some custom rules.


![](/images/small-fa2-hook-exercise.png)

1 - we want to accept a transfer if transfer receiver is registered in a whitelist. This whitelisting is done via a tranfer hook.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Operator(Owner_transfer) * Receiver(Owner_no_hook) * Sender(Owner_no_hook)
## Your mission

We are working on a non_fungible/single-asset token.
Our NFT "token" is almost ready but to allow a new rule. We need Bob to transfert a token taken from Vera account and send it to Alice account.
Our NFT "token" is almost ready but to allow a new rule. We need Bob to transfert a token taken from Vera account and send it to alice's account.

- Alice's account address is "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN"
- Bob's account address is "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU"
Expand Down
Loading

0 comments on commit 0c63ef3

Please sign in to comment.