diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5e40f5a
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterAddresses/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterAddresses/course.md
index af1586f..79530ee 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterAddresses/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterAddresses/course.md
@@ -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 :
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterDeployContract/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterDeployContract/course.md
index 06bee2b..36cd5b7 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterDeployContract/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterDeployContract/course.md
@@ -1,6 +1,6 @@
# Chapter 23 : Deploy contract
-
+
## Smart contract
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA12/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterFA12/course.md
index 95fdcf4..93ca781 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA12/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA12/course.md
@@ -1,49 +1,49 @@
# Chapter 25 : Financial Application 1.2
-
+
## 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)
@@ -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)
-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.
+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.
-2- Write a ligo command line for preparing invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
+2- Write a ligo command line for preparing the invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
-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).
+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).
-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:
+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))))
```
-5- Write a tezos command line that simulate your invocation.
+5- Write a Tezos command line that simulates your invocation.
-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*.
+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*.
-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).
+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).
-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).
+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).
-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:
+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))
```
-10- Write a tezos command line that simulate your *Transfer* invocation.
+10- Write a Tezos command line that simulates your *Transfer* invocation.
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA12/solution.cmd b/src/frontend/src/pages/Chapters/Camel/ChapterFA12/solution.cmd
index 04e4c9e..90f196f 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA12/solution.cmd
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA12/solution.cmd
@@ -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
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA20/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterFA20/course.md
index cfb74b9..81810cf 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA20/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA20/course.md
@@ -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:
"*TOKEN\_UNDEFINED*" - One of the specified *token\_ids* is not defined within the FA2 contract
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Hook/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Hook/course.md
index 060f604..6dd31c1 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Hook/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Hook/course.md
@@ -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.
If the policy requires a owner hook then the token owner contract MUST implement an entry point "tokens\_received". Otherwise transfer is not allowed.
-If the policy optionnaly accepts a owner hook then the token owner contract MAY implement an entry point "tokens\_received". Otherwise transfer is allowed.
+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.
@@ -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 the transfer receiver is registered in a whitelist. This whitelisting is done via a tranfer hook.
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Operator/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Operator/course.md
index 5b6238d..0c31afb 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Operator/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Operator/course.md
@@ -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"
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Permission/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Permission/course.md
index 7555720..3619570 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterFA20Permission/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterFA20Permission/course.md
@@ -1,4 +1,4 @@
-# Chapter 24 : Financial Application 2.0 - Operators and Permissions
+# Chapter XX : Financial Application 2.0 - Operators and Permissions
@@ -91,7 +91,7 @@ FA2 defines :
#### permissions_descriptor
-FA2 specifies an interface permissions_descriptor allowing external contracts to discover an FA2 contract's permission policy and to configure it. _permissions_descriptor_ serves as a modular approach to define consistent and non-self-contradictory policies.
+FA2 specifies an interface permissions*descriptor allowing external contracts to discover an FA2 contract's permission policy and to configure it. \_permissions_descriptor* serves as a modular approach to define consistent and non-self-contradictory policies.
The _permission descriptor_ indicates which standard permission policies are implemented by the FA2 contract and can be used by off-chain and on-chain tools to discover the properties of the particular FA2 contract implementation.
@@ -108,12 +108,12 @@ type permissions_descriptor = {
#### operator_transfer_policy
-operator_transfer_policy - defines who can transfer tokens. Tokens can be
+operator*transfer_policy - defines who can transfer tokens. Tokens can be
transferred by the token owner or an operator (some address that is authorized to
transfer tokens on behalf of the token owner). A special case is when neither owner
nor operator can transfer tokens (can be used for non-transferable tokens). The
FA2 standard defines two entry points to manage and inspect operators associated
-with the token owner address (_update_operators_,
+with the token owner address (\_update_operators*,
_is_operator_). Once an operator is added, it can manage all of
its associated owner's tokens.
@@ -126,8 +126,8 @@ type operator_transfer_policy =
#### owner_hook_policy
-owner_hook_policy - defines if sender/receiver hooks should be called or
-not. Each token owner contract MAY implement either an _fa2_token_sender_ or
+owner*hook_policy - defines if sender/receiver hooks should be called or
+not. Each token owner contract MAY implement either an \_fa2_token_sender* or
_fa2_token_receiver_ hook interface. Those hooks MAY be called when a transfer sends
tokens from the owner account or the owner receives tokens. The hook can either
accept a transfer transaction or reject it by failing.
@@ -172,7 +172,7 @@ Operator(Owner_transfer) * Receiver(Owner_no_hook) * Sender(Owner_no_hook)
## Your mission
We are working on a non_fungible/multi-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.
1- First we have to set the right operator policy to authorize delegation when deploying the contract. We want you to prepare the initial state of storage. Write the _ligo compile-storage_ command for the *token* contract with following recommandations :
@@ -183,7 +183,7 @@ Our NFT "token" is almost ready but to allow a new rule. We need Bob to transfer
- operator transfer is authorized,
- Bob account has no token
- Vera account is owner of the token 1
-- Alice account has no token
+- alice's account has no token
- Jay is the administrator of the contract
- the token type transfered is 0 (token_id)
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/course.md
index 2c3e4f4..9ce4c3d 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/course.md
@@ -1,12 +1,12 @@
# Chapter 22 : Lambda (anonymous function)
-
+
## Versioning
Tezos as a public blockchain expects that contracts should have the same behaviour for all users. In theory, once a contract is deployed, it should not be changed.
-We call _antipattern_ when a smart contract has a special role (admin) or may be evolving (changing the rules of the smart contract).
+We call _antipattern_ a smart contract that has a special role (admin) or may be evolving (changing the rules of the smart contract).
The need to modify the behaviour of a smart contract emerges when for example the laws of a country have changed and you need to apply the same changes to the rules in your smart contract.
One could write a new smart contract (V2) and deploy it but it would imply that all existing information stored in the storage of the old smart contract (V1) would be lost. This problem can be solved by :
@@ -16,7 +16,6 @@ One could write a new smart contract (V2) and deploy it but it would imply that
In this chapter we will focus on the third solution.
-
### Versioning by re-emission
Versioning can be done by writing a new smart contract and emitting transactions from the old contract (V1) to migrate storage information to the new contract (V2). This may require a lot of transactions and thus spending a lot of fees (resulting in a significant price). This price could be paid by the smart contract that would emit transactions or by each user which would invoke a "migrate" entrypoint of V1 contract to send storage information to the new contract. Transaction emission has been seen in chapter 17 with the _Tezos.transaction_ predefined function.
@@ -34,6 +33,7 @@ Versioning can be done by writing a single smart contract that can change its pr
Changing the behavior of a smart contract can be done by customizing the implementation through lambda functions. The idea is to implement smart contract logic in a lambda funtion that can be modified after the contract deployment.
This pattern requires to:
+
- define an anonymous function in the storage which is called by an entrypoint
- write a new entrypoint that allows to change the implementation of this anonymous function.
@@ -118,7 +118,7 @@ ligo dry-run lambda.mligo main 'ChangeFunc(fun (c : coordinates) -> {x=c.x*100;y
## Your mission
We have a smart contract that registers planets of the Sol system. Since the beginning of the project, all celestial bodies were considered as planets.
-Since 2006, the IAU decided that celetial bodies with a mass under 100 are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
+Since 2006, the IAU decided that celetial bodies with a mass under 100 megatons are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
Take a look at the starmap contract in the editor tabs.
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/exercise.ligo b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/exercise.ligo
index c9f98d5..b1ca62e 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/exercise.ligo
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/exercise.ligo
@@ -15,7 +15,7 @@ ligo dry-run starmap.mligo main \
category=PLANET});
("sun", {
position={x=0;y=0;z=0};
- mass=1000000n;
+ mass=1,000,000n;
category=PLANET})
]
}'
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/solution.ligo b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/solution.ligo
index ac4d4de..435c94c 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterLambda/solution.ligo
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterLambda/solution.ligo
@@ -15,7 +15,7 @@ ligo dry-run starmap.mligo main \
category=PLANET});
("sun", {
position={x=0;y=0;z=0};
- mass=1000000n;
+ mass=1,000,000n;
category=PLANET})
]
}'
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterMultisig/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterMultisig/course.md
index abda54a..f58bed1 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterMultisig/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterMultisig/course.md
@@ -1,7 +1,6 @@
# Chapter 24 : Multi-signature pattern
-
-Before any nuke strike, the admiral and the president of Galatic Union must agree on nuclear usage. We need the approval of both for nuclear weapons usage.
+
In some case one may want to execute an action only if many users approve this action. This kind of pattern is called _multi-signature_.
@@ -21,25 +20,24 @@ The multi-signature pattern can be described with this set of rules :
- an action is automatically executed when it has been approved by enough users (a threshold of number of approvals must be defined)
- the smart contract must also handle a list of user in order to specify who is allowed to approve an action
-optionnaly
+Optionnaly
- the smart contract can also handle the number of approval per user and set maximum number of approvals.
- the smart contract can also handle an inner state. Everytime an action is executed the inner state of the multi-signature contract is updated for tracability purpose
More complex rules can be added these basic ones.
-### Implementation of multi-signature pattern
+### Implementation of multi-signature patterns
Let's consider this implementation of the multi-signature pattern. This implementation takes all previously mentionned rules into account.
-This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for _Counter_ contract.
+This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for the _Counter_ contract.
The _Counter_ contract (the example at https://ide.ligolang.org/p/-hNqhvMFDFdsTULXq4K-KQ) has been deployed at address : KT1CFBbdhRCNAzNkX56v361XZToHCAtjSsVS
The _Counter_ contract handle a simple integer counter which can be incemented or decremented.
-Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
-
-A user can invoke the entry point *Send* of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point *Withdraw* of the smart contract _MultisigProxy_ to reject a proposed modification.
+Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
+A user can invoke the entry point _Send_ of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point _Withdraw_ of the smart contract _MultisigProxy_ to reject a proposed modification.
```
// Counter contract types
diff --git a/src/frontend/src/pages/Chapters/Camel/ChapterPolymorphism/course.md b/src/frontend/src/pages/Chapters/Camel/ChapterPolymorphism/course.md
index 181e8b8..85be6c4 100644
--- a/src/frontend/src/pages/Chapters/Camel/ChapterPolymorphism/course.md
+++ b/src/frontend/src/pages/Chapters/Camel/ChapterPolymorphism/course.md
@@ -1,6 +1,6 @@
# Chapter 21 : Polymorphism
-
+
When sending transactions between contracts, each contract must know the target contract interface and the parameter type of the target contract. This is done basically by separating type definition and function implementation and by using code inclusion.
@@ -42,7 +42,6 @@ let : option(contract()) = Tez
Entry point names are written in the form of: _%myEntryPoint_ for the entry point _MyEntryPoint_.
-
## Your mission
Consider the following smart contracts : Squadron and Central (Exercice).
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterDeployContract/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterDeployContract/course.md
index 46c10d6..e0c3573 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterDeployContract/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterDeployContract/course.md
@@ -1,6 +1,6 @@
# Chapter 23 : Deploy contract
-
+
## Smart contract
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/course.md
index e6605c1..8743936 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/course.md
@@ -1,51 +1,51 @@
# Chapter 25 : Financial Application 1.2
-
+
## 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 transfer between accounts, etc).
+The rules of Financial Application describe how to create currencies (and transfer those between accounts, etc).
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 allow tokens to be approved so they can be spent by another on-chain third party.
+This Fungible token standard provides basic functionality to transfer tokens, as well as allowing 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 implementation in PascalLigo of a fungible token (FA1.2)
+Let's see an implementation in PascalLigo of a fungible token (FA1.2)
```
// This is an implimentation of the FA1.2 specification in PascaLIGO
@@ -198,35 +198,35 @@ function main (const p : action ; const s : contract_storage) :
## Your mission
-Let's assume the _TezosAcamedyToken_ has been deployed.
+Let's assume _TezosAcamedyToken_ has been deployed.
-Consider your account is _me_ (at address tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) which has been granted 1000000 token.
-Consider alice account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7)
+Consider your account is _me_ (at address tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ) which has been granted 1,000,000 token.
+Consider alice's account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7)
-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 of token and no allowances.
+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.
-2- Write a ligo command line for preparing invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
+2- Write a ligo command line for preparing the invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
-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).
+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).
-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:
+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))))
```
-5- Write a tezos command line that simulate your invocation.
+5- Write a Tezos command line that simulates your invocation.
-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*.
+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*.
-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).
+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).
-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).
+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).
-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:
+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))
```
-10- Write a tezos command line that simulate your *Transfer* invocation.
+10- Write a Tezos command line that simulates your *Transfer* invocation.
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/solution.cmd b/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/solution.cmd
index 32edec1..425221e 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/solution.cmd
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterFA12/solution.cmd
@@ -1,16 +1,16 @@
-ligo compile-storage fa12.ligo main 'record [ totalSupply=1000000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [ balance=1000000n; allowances=(map [] : map(address, amt)) ] ] ]'
+ligo compile-storage fa12.ligo main 'record [ totalSupply=1,000,000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [ balance=1,000,000n; allowances=(map [] : map(address, amt)) ] ] ]'
// Modify the code below
ligo compile-parameter fa12.ligo main 'Approve(("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)'
// Modify the code below
-ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.ligo main 'Approve(("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)' 'record [ totalSupply=1000000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [ balance=1000000n; allowances=(map [] : map(address, amt)) ] ] ]'
+ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.ligo main 'Approve(("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)' 'record [ totalSupply=1,000,000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [ balance=1,000,000n; allowances=(map [] : map(address, amt)) ] ] ]'
// 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.ligo main 'Transfer(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)'
// Modify the code below
-ligo compile-storage fa12.ligo main 'record [ totalSupply=1000000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [balance=1000000n; allowances=map [("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)->2n] ] ] ]'
+ligo compile-storage fa12.ligo main 'record [ totalSupply=1,000,000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [balance=1,000,000n; allowances=map [("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)->2n] ] ] ]'
// Modify the code below
-ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.ligo main 'Transfer(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)' 'record [ totalSupply=1000000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [balance=1000000n; allowances=map [("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)->2n] ] ] ]'
+ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.ligo main 'Transfer(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), 2n)' 'record [ totalSupply=1,000,000n; ledger=big_map [ ("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address)->record [balance=1,000,000n; allowances=map [("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)->2n] ] ] ]'
// Modify the code below
tezos-client transfer 0tz from me to TezosAcamedyToken --arg '(Right (Pair (Pair "tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ" "tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7") 2))' --dry-run
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20/course.md
index bc2793d..e4aaa56 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20/course.md
@@ -107,6 +107,7 @@ FA2 token contracts MUST implement the transfer logic defined by the following r
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
@@ -172,7 +173,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:
"*TOKEN\_UNDEFINED*" - One of the specified *token\_ids* is not defined within the FA2 contract
@@ -205,5 +206,3 @@ When error occurs, any FA2 contract entry point MUST fail with one of the follow
3- Create a constant *response* of type *balance\_of\_response\_* containing a record with the request and the retrieved balance.
4- The function *retreive\_balance* must return a type *balance\_of\_response*. You can use the *convert\_to\_right\_comb* function (seen in Chapter Interoperability) to convert constant *response* into the right format. Don't forget to cast *response* as type *balance\_of\_response\_*.
-
-
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Hook/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Hook/course.md
index 2de8ae8..3358c98 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Hook/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Hook/course.md
@@ -84,7 +84,7 @@ Some helper functions has been gathered in a hook library which help defining ho
The hook pattern depends on the permission policy. A transfer hook may be unwanted, optional or required.
If the policy requires a owner hook then the token owner contract MUST implement an entry point "tokens\_received". Otherwise transfer is not allowed.
-If the policy optionnaly accepts a owner hook then the token owner contract MAY implement an entry point "tokens\_received". Otherwise transfer is allowed.
+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.
@@ -195,6 +195,7 @@ const own_policy : permissions_descriptor = record [
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)
Rule 1 - We want to accept a transfer if the transfer receiver is registered in a whitelist. This whitelisting is done via a tranfer hook.
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Operator/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Operator/course.md
index 2faaf8a..17dd283 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Operator/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterFA20Operator/course.md
@@ -190,7 +190,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"
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/course.md
index 7e8cec3..a20bffd 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/course.md
@@ -1,12 +1,12 @@
# Chapter 22 : Lambda (anonymous function)
-
+
## Versioning
Tezos as a public blockchain expects that contracts should have the same behaviour for all users. In theory, once a contract is deployed, it should not be changed.
-We call _antipattern_ when a smart contract has a special role (admin) or may be evolving (changing the rules of the smart contract).
+We call _antipattern_ a smart contract that has a special role (admin) or may be evolving (changing the rules of the smart contract).
The need to modify the behaviour of a smart contract emerges when for example the laws of a country have changed and you need to apply the same changes to the rules in your smart contract.
One could write a new smart contract (V2) and deploy it but it would imply that all existing information stored in the storage of the old smart contract (V1) would be lost. This problem can be solved by :
@@ -16,7 +16,6 @@ One could write a new smart contract (V2) and deploy it but it would imply that
In this chapter we will focus on the third solution.
-
### Versioning by re-emission
Versioning can be done by writing a new smart contract and emitting transactions from the old contract (V1) to migrate storage information to the new contract (V2). This may require a lot of transactions and thus a lot of fees (resulting in a significant price). This price could be paid by the smart contract that would emit transactions or by each user which would invoke a "migrate" entrypoint of V1 contract to send storage information to the new contract. Transaction emission has been seen in chapter 17 with the _Tezos.transaction_ predefined function.
@@ -34,6 +33,7 @@ Versioning can be done by writing a single smart contract that can change its pr
Changing the behavior of a smart contract can be done by customizing the implementation through lambda functions. The idea is to implement smart contract logic in a lambda funtion that can be modified after the contract deployment.
This pattern requires to:
+
- define an anonymous function in the storage which is called by an entrypoint
- write a new entrypoint that allows to change the implementation of this anonymous function.
@@ -111,7 +111,7 @@ ligo dry-run lambda.ligo main 'ChangeFunc(function (const c : coordinates) : coo
## Your mission
We have a smart contract that registers planets of the Sol system. Since the beginning of the project, all celestial bodies were considered as planets.
-Since 2006, the IAU decided that celetial bodies with a mass under 100 are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
+Since 2006, the IAU decided that celetial bodies with a mass under 100 megatons are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
Take a look at the starmap contract in the editor tabs.
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/exercise.ligo b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/exercise.ligo
index b923e11..8801629 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/exercise.ligo
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/exercise.ligo
@@ -15,7 +15,7 @@ ligo dry-run starmap.ligo main \
category=PLANET];
"sun" -> record [
position=record [x=0;y=0;z=0];
- mass=1000000n;
+ mass=1,000,000n;
category=PLANET]
end
]'
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/solution.ligo b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/solution.ligo
index 3c10bcf..24a4b9f 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/solution.ligo
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterLambda/solution.ligo
@@ -20,7 +20,7 @@ ligo dry-run starmap.ligo main \
category=PLANET];
"sun" -> record [
position=record [x=0;y=0;z=0];
- mass=1000000n;
+ mass=1,000,000n;
category=PLANET]
end
]'
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterMultisig/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterMultisig/course.md
index 83c015d..22f0f57 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterMultisig/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterMultisig/course.md
@@ -1,7 +1,6 @@
# Chapter 24 : Multi-signature pattern
-
-Before any nuke strike, the admiral and the president of Galatic Union must agree on nuclear usage. We need the approval of both for nuclear weapons usage.
+
In some case one may want to execute an action only if many users approve this action. This kind of pattern is called _multi-signature_.
@@ -21,25 +20,24 @@ The multi-signature pattern can be described with this set of rules :
- an action is automatically executed when it has been approved by enough users (a threshold of number of approvals must be defined)
- the smart contract must also handle a list of user in order to specify who is allowed to approve an action
-optionnaly
+Optionnaly
- the smart contract can also handle the number of approval per user and set maximum number of approvals.
- the smart contract can also handle an inner state. Everytime an action is executed the inner state of the multi-signature contract is updated for tracability purpose
More complex rules can be added these basic ones.
-### Implementation of multi-signature pattern
+### Implementation of multi-signature patterns
Let's consider this implementation of the multi-signature pattern. This implementation takes all previously mentionned rules into account.
-This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for _Counter_ contract.
+This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for the _Counter_ contract.
The _Counter_ contract (the example at https://ide.ligolang.org/p/-hNqhvMFDFdsTULXq4K-KQ) has been deployed at address : KT1CFBbdhRCNAzNkX56v361XZToHCAtjSsVS
The _Counter_ contract handle a simple integer counter which can be incemented or decremented.
-Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
-
-A user can invoke the entry point *Send* of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point *Withdraw* of the smart contract _MultisigProxy_ to reject a proposed modification.
+Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
+A user can invoke the entry point _Send_ of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point _Withdraw_ of the smart contract _MultisigProxy_ to reject a proposed modification.
```
// Counter contract types
@@ -225,4 +223,4 @@ Notice in the _Withdraw_ function :
2- Modify the *increment* function to modify the reputation of a given *addr* address by granting one point of reputation. (use *count* as temporary variable for the _switch_ operator). If the voter is not registered yet in the *reputation* registry then add him. Otherwise update its reputation by incrementing by one its actual level. It is recommanded to use Map.add and Map.update when modifying a _map_.
- 3- Modify the *reputation_updated* variable (representing the new state of reputations) by iterating on voters with a _Set.fold_ operation and applying *increment* function on reputation.
\ No newline at end of file
+ 3- Modify the *reputation_updated* variable (representing the new state of reputations) by iterating on voters with a _Set.fold_ operation and applying *increment* function on reputation.
diff --git a/src/frontend/src/pages/Chapters/Pascal/ChapterPolymorphism/course.md b/src/frontend/src/pages/Chapters/Pascal/ChapterPolymorphism/course.md
index cbd7a5b..85be6c4 100644
--- a/src/frontend/src/pages/Chapters/Pascal/ChapterPolymorphism/course.md
+++ b/src/frontend/src/pages/Chapters/Pascal/ChapterPolymorphism/course.md
@@ -1,6 +1,6 @@
# Chapter 21 : Polymorphism
-
+
When sending transactions between contracts, each contract must know the target contract interface and the parameter type of the target contract. This is done basically by separating type definition and function implementation and by using code inclusion.
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterDeployContract/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterDeployContract/course.md
index 2749b53..88cc256 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterDeployContract/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterDeployContract/course.md
@@ -1,6 +1,6 @@
# Chapter 23 : Deploy contract
-
+
## Smart contract
@@ -28,7 +28,6 @@ Execution of an entry point produces a new state of the storage of the smart con
Operations are transactions (smart contract invocation) that will be sent to some other contracts. They will trigger an entry point of the targeted contract or a tez transfer (no invocation of entry point). If execution of an entry point produces operations (an ordered list of transactions) then they are sent and executed following the order of the list of operations.
-
## Deploy
A smart contract must be deployed on the blockchain in order to be invoked. When deploying a smart contract on the blockchain, one must specify the initial state of the storage.
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA12/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterFA12/course.md
index 779a5ea..a2348a3 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA12/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA12/course.md
@@ -1,51 +1,49 @@
# Chapter 25 : Financial Application 1.2
-
+
## 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. 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.
-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 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.
-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.
-
-### 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 transfer between accounts, etc).
+The rules of Financial Application describe how to create currencies (and transfer those between accounts, etc).
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 (FA20) are rules for non fungible token.
+- Financial Application 1.2 (FA1.2) is a set of rules for fungible tokens.
+- Financial Application 2.0 (FA20) 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 allow tokens to be approved so they can be spent by another on-chain third party.
+This Fungible token standard provides basic functionality to transfer tokens, as well as allowing 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 implementation in ReasonLigo of a fungible token (FA1.2)
+Let's see an implementation in ReasonLigo of a fungible token (FA1.2)
```
type tokens = big_map (address, nat)
@@ -168,35 +166,35 @@ let main = ((a,s): (action, storage)) =>
## Your mission
-Let's assume the _TezosAcamedyToken_ has been deployed.
+Let's assume _TezosAcamedyToken_ has been deployed.
Consider your account is _me_ (at address tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ).
-Consider alice account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7).
+Consider alice's account (at address tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7).
-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 of token and no allowances.
+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.
-2- Write a ligo command line for preparing invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
+2- Write a ligo command line for preparing the invocation of an *Approval* of 2 TAT (Tezos Academy Token) for *alice*.
-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).
+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).
-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:
+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))))
```
-5- Write a tezos command line that simulate your invocation.
+5- Write a Tezos command line that simulates your invocation.
-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*.
+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*.
-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).
+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).
-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).
+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).
-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:
+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))
```
-10- Write a tezos command line that simulate your *Transfer* invocation.
+10- Write a Tezos command line that simulates your *Transfer* invocation.
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA12/solution.cmd b/src/frontend/src/pages/Chapters/Reason/ChapterFA12/solution.cmd
index 593403b..58ce0c4 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA12/solution.cmd
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA12/solution.cmd
@@ -1,16 +1,16 @@
// Modify the code below
-ligo compile-storage fa12.religo main '{total_amount:1000000n, tokens:Big_map.literal([(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]), allowances:(Big_map.empty: big_map((address,address),nat))}'
+ligo compile-storage fa12.religo main '{total_amount:1,000,000n, tokens:Big_map.literal([(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1,000,000n)]), allowances:(Big_map.empty: big_map((address,address),nat))}'
// Modify the code below
ligo compile-parameter fa12.religo main 'Approve({spender:("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), value:2n})'
// Modify the code below
-ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.religo main 'Approve({spender:("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), value:2n})' '{total_amount:1000000n, tokens:Big_map.literal([(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]), allowances:(Big_map.empty: big_map((address,address),nat))}'
+ligo dry-run --sender=tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ fa12.religo 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: big_map((address,address),nat))}'
// 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.religo main 'Transfer({address_from:("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), address_to:("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address), value:2n})'
// Modify the code below
-ligo compile-storage fa12.religo main '{total_amount:1000000n, tokens:Big_map.literal([(("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), 1000000n)]), allowances:Big_map.literal([((("tz1SdT62G8tQp9fdHh4f2m4VtL8aGG6NUcmJ":address), ("tz1NiAGZgRV8F1E3qYFEPgajntzTRDYkU9h7":address)) ,2n)])}'
+ligo compile-storage fa12.religo 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.religo 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.religo 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
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/course.md
index cc71eec..dcf9162 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/course.md
@@ -128,6 +128,7 @@ FA2 token contracts MUST implement the transfer logic defined by the following r
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 tokenId = nat;
@@ -229,7 +230,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:
"*TOKEN\_UNDEFINED*" - One of the specified *token\_ids* is not defined within the FA2 contract
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/exercise.religo b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/exercise.religo
index efdcdb1..74adbea 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/exercise.religo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/exercise.religo
@@ -104,7 +104,7 @@ let balanceOfRequestsIterator =
let (balanceOfResponses, storage): balanceOfRequestsIteratorAccumulator = accumulator;
// Modify the code below
- let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson, ...balanceOfResponses];
+ let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson,...balanceOfResponses];
(balanceOfResponses, storage);
}
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/solution.religo b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/solution.religo
index 2fe73e7..5dc72a8 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA20/solution.religo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA20/solution.religo
@@ -111,7 +111,7 @@ let balanceOfRequestsIterator =
};
let balanceOfResponseMichelson: balanceOfResponseMichelson = Layout.convert_to_right_comb(balanceOfResponseAuxiliary);
- let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson, ...balanceOfResponses];
+ let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson,...balanceOfResponses];
(balanceOfResponses, storage);
}
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/course.md
index 6357eab..ee92110 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/course.md
@@ -212,7 +212,7 @@ type permissionsDescriptorParameter = contract(permissionsDescriptorMichelson);
## 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"
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/non_fungible_token.religo b/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/non_fungible_token.religo
index c37c79f..e671455 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/non_fungible_token.religo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterFA20Operator/non_fungible_token.religo
@@ -96,7 +96,7 @@ let balanceOfRequestsIterator =
};
let balanceOfResponseMichelson: balanceOfResponseMichelson = Layout.convert_to_right_comb(balanceOfResponseAuxiliary);
- let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson, ...balanceOfResponses];
+ let balanceOfResponses: list(balanceOfResponseMichelson) = [balanceOfResponseMichelson,...balanceOfResponses];
(balanceOfResponses, storage);
}
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.religo b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.religo
index 3d85cd3..4948d29 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.religo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterInterop/solution.religo
@@ -20,7 +20,7 @@ let addInventory = ((params,s) : (list(item), storage)) : return =>
{
let item_list : list(item) = params;
// Type your solution below
- let update_inventory = ((acc,i) : (list(item_michelson), item)) : list(item_michelson) => [Layout.convert_to_right_comb(i), ...acc];
+ let update_inventory = ((acc,i) : (list(item_michelson), item)) : list(item_michelson) => [Layout.convert_to_right_comb(i),...acc];
let new_inventory : list(item_michelson) = List.fold(update_inventory, item_list, s.inventory);
(([] : list(operation)), {...s, inventory:new_inventory})
};
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/course.md
index 6bb4165..2eaefd3 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/course.md
@@ -1,12 +1,12 @@
# Chapter 22 : Lambda (anonymous function)
-
+
## Versioning
Tezos as a public blockchain expects that contracts should have the same behaviour for all users. In theory, once a contract is deployed, it should not be changed.
-We call _antipattern_ when a smart contract has a special role (admin) or may be evolving (changing the rules of the smart contract).
+We call _antipattern_ a smart contract that has a special role (admin) or may be evolving (changing the rules of the smart contract).
The need to modify the behaviour of a smart contract emerges when for example the laws of a country have changed and you need to apply the same changes to the rules in your smart contract.
One could write a new smart contract (V2) and deploy it but it would imply that all existing information stored in the storage of the old smart contract (V1) would be lost. This problem can be solved by :
@@ -16,7 +16,6 @@ One could write a new smart contract (V2) and deploy it but it would imply that
In this chapter we will focus on the third solution.
-
### Versioning by re-emission
Versioning can be done by writing a new smart contract and emitting transactions from the old contract (V1) to migrate storage information to the new contract (V2). This may require a lot of transactions and thus a lot of fees (resulting in a significant price). This price could be paid by the smart contract that would emit transactions or by each user which would invoke a "migrate" entrypoint of V1 contract to send storage information to the new contract. Transaction emission has been seen in chapter 17 with the _Tezos.transaction_ predefined function.
@@ -34,6 +33,7 @@ Versioning can be done by writing a single smart contract that can change its pr
Changing the behavior of a smart contract can be done by customizing the implementation through lambda functions. The idea is to implement smart contract logic in a lambda funtion that can be modified after the contract deployment.
This pattern requires to:
+
- define an anonymous function in the storage which is called by an entrypoint
- write a new entrypoint that allows to change the implementation of this anonymous function.
@@ -111,7 +111,7 @@ ligo dry-run lambda.religo main 'ChangeFunc((c : coordinates) : coordinates => {
## Your mission
We have a smart contract that registers planets of the Sol system. Since the beginning of the project, all celestial bodies were considered as planets.
-Since 2006, the IAU decided that celetial bodies with a mass under 100 are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
+Since 2006, the IAU decided that celetial bodies with a mass under 100 megatons are not considered as a planet but as a dwarf-planet. Hopefully we forecasted this kind of change! A _DeduceCategoryChange_ entrypoint allows us to change the lambda which determines the category of a celestial body. All we have to do is define the new rule and all registered celestial bodies will be updated.
Take a look at the starmap contract in the editor tabs.
@@ -128,7 +128,7 @@ let applyDeduceCatg = ((name,p) : (string, planet)) : planet =>
{position:p.position, mass:p.mass, category:f(p)};
```
-⚠️ Notice that in the function _deduceCategoryChange_ the sub-function _applyDeduceCatg_ is used to update all entries of the _celestialbodies_ map with :
+⚠️ Notice that in the function _deduceCategoryChange_ the sub-function _applyDeduceCatg_ is used to update all entries of the _celestialbodies_ map with :
```
Map.map (applyDeduceCatg, store.celestialbodies);
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/exercise.ligo b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/exercise.ligo
index a25f5d2..905614a 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/exercise.ligo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/exercise.ligo
@@ -15,7 +15,7 @@ ligo dry-run lambda2.religo main \
category:PLANET}),
("sun", {
position:{x:0,y:0,z:0},
- mass:1000000n,
+ mass:1,000,000n,
category:PLANET})
])
}'
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/solution.ligo b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/solution.ligo
index 4fbb586..4612e73 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLambda/solution.ligo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLambda/solution.ligo
@@ -15,7 +15,7 @@ ligo dry-run lambda2.religo main \
category:PLANET}),
("sun", {
position:{x:0,y:0,z:0},
- mass:1000000n,
+ mass:1,000,000n,
category:PLANET})
])
}'
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLists/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterLists/course.md
index d1fe9b9..d415e4b 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLists/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLists/course.md
@@ -20,15 +20,15 @@ let my_list : list (int) = [1, 2, 2]; // The head is 1
Lists can be augmented by adding an element before the head (or, in terms of stack, by pushing an element on top). This operation is usually called consing in functional languages.
-In ReasonLIGO, the cons operator is infix and noted _, ..._. It is not symmetric: on the left lies the element to cons, and, on the right, a list on which to cons :
+In ReasonLIGO, the cons operator is infix and noted _,..._. It is not symmetric: on the left lies the element to cons, and, on the right, a list on which to cons :
```
-let larger_list : list (int) = [5, ...my_list]; // [5,1,2,2]
+let larger_list : list (int) = [5,...my_list]; // [5,1,2,2]
```
## Functional Iteration over Lists
-A functional iterator is a function that traverses a data structure and calls in turn a given function over the elements of that structure to compute some value. There are three kinds of functional iterations over LIGO lists: the *iterated operation*, the *map operation* (not to be confused with the map data structure) and the *fold operation*.
+A functional iterator is a function that traverses a data structure and calls in turn a given function over the elements of that structure to compute some value. There are three kinds of functional iterations over LIGO lists: the _iterated operation_, the _map operation_ (not to be confused with the map data structure) and the _fold operation_.
### Iterated Operation over Lists
@@ -44,7 +44,7 @@ let iter_op = (l : list (int)) : unit => {
### Mapped Operation over Lists
-We may want to change all the elements of a given list by applying to them a function. This is called a *map operation*, not to be confused with the map data structure. The predefined functional iterator implementing the mapped operation over lists is called _List.map_ and is used as follows.
+We may want to change all the elements of a given list by applying to them a function. This is called a _map operation_, not to be confused with the map data structure. The predefined functional iterator implementing the mapped operation over lists is called _List.map_ and is used as follows.
```
let increment = (i : int) : int => i + 1;
@@ -55,7 +55,7 @@ let plus_one : list (int) = List.map (increment, larger_list);
### Folded Operation over Lists
-A *folded operation* is the most general of iterations. The folded function takes two arguments: an accumulator and the structure element at hand, with which it then produces a new accumulator. This enables having a partial result that becomes complete when the traversal of the data structure is over. The predefined functional iterator implementing the folded operation over lists is called _List.fold_ and is used as follows.
+A _folded operation_ is the most general of iterations. The folded function takes two arguments: an accumulator and the structure element at hand, with which it then produces a new accumulator. This enables having a partial result that becomes complete when the traversal of the data structure is over. The predefined functional iterator implementing the folded operation over lists is called _List.fold_ and is used as follows.
```
let sum = ((result, i): (int, int)): int => result + i;
@@ -64,7 +64,7 @@ let sum_of_elements : int = List.fold (sum, my_list, 0);
## Sets
-Sets are unordered collections of values of the same type, like lists are ordered collections. Elements of sets in LIGO are unique, whereas they can be repeated in a list.
+Sets are unordered collections of values of the same type, like lists are ordered collections. Elements of sets in LIGO are unique, whereas they can be repeated in a list.
### Defining sets
@@ -110,7 +110,7 @@ let smaller_set : set (int) = Set.remove (3, my_set);
It is possible to iterate over elements of a set and apply a function to them (like functional iteratio over List).
-There are three kinds of functional iterations over LIGO sets: the *iterated operation* and the *folded operation*.
+There are three kinds of functional iterations over LIGO sets: the _iterated operation_ and the _folded operation_.
#### Iterated Operation
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLists/solution.ligo b/src/frontend/src/pages/Chapters/Reason/ChapterLists/solution.ligo
index 6a6ade1..5c5e994 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLists/solution.ligo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLists/solution.ligo
@@ -1,4 +1,4 @@
// Type your solution below
let itinary : list(string) = ["earth"];
-let longer_itinary : list(string) = ["sun", ...itinary];
-let far_itinary : list(string) = ["alpha-centauri", ...longer_itinary];
\ No newline at end of file
+let longer_itinary : list(string) = ["sun",...itinary];
+let far_itinary : list(string) = ["alpha-centauri",...longer_itinary];
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterLoops/solution.ligo b/src/frontend/src/pages/Chapters/Reason/ChapterLoops/solution.ligo
index 75c01e4..a6113e1 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterLoops/solution.ligo
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterLoops/solution.ligo
@@ -38,7 +38,7 @@ let star_map : list(planet) = [{
},
]
// Type your solution below
-let conditions = ((acc, p): (list(planet), planet)) : list(planet) => if ((p.density > 100n) && p.atmospheric_activity) { [p, ...acc] } else { acc };
+let conditions = ((acc, p): (list(planet), planet)) : list(planet) => if ((p.density > 100n) && p.atmospheric_activity) { [p,...acc] } else { acc };
let scan = (l : list(planet)) : list(planet) => List.fold (conditions, l, ([]: list(planet)));
let scan_results : list(planet) = scan (star_map);
\ No newline at end of file
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterMultisig/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterMultisig/course.md
index fb5c392..6305444 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterMultisig/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterMultisig/course.md
@@ -1,7 +1,6 @@
# Chapter 24 : Multi-signature pattern
-
-Before any nuke strike, the admiral and the president of Galatic Union must agree on nuclear usage. We need the approval of both for nuclear weapons usage.
+
In some case one may want to execute an action only if many users approve this action. This kind of pattern is called _multi-signature_.
@@ -21,25 +20,24 @@ The multi-signature pattern can be described with this set of rules :
- an action is automatically executed when it has been approved by enough users (a threshold of number of approvals must be defined)
- the smart contract must also handle a list of user in order to specify who is allowed to approve an action
-optionnaly
+Optionnaly
- the smart contract can also handle the number of approval per user and set maximum number of approvals.
- the smart contract can also handle an inner state. Everytime an action is executed the inner state of the multi-signature contract is updated for tracability purpose
More complex rules can be added these basic ones.
-### Implementation of multi-signature pattern
+### Implementation of multi-signature patterns
Let's consider this implementation of the multi-signature pattern. This implementation takes all previously mentionned rules into account.
-This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for _Counter_ contract.
+This smart contract _MultisigProxy_ intends to play the role of a proxy pattern for the _Counter_ contract.
The _Counter_ contract (the example at https://ide.ligolang.org/p/-hNqhvMFDFdsTULXq4K-KQ) has been deployed at address : KT1CFBbdhRCNAzNkX56v361XZToHCAtjSsVS
The _Counter_ contract handle a simple integer counter which can be incemented or decremented.
-Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
-
-A user can invoke the entry point *Send* of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point *Withdraw* of the smart contract _MultisigProxy_ to reject a proposed modification.
+Instead of invoking the _Counter_ contract, users propose a modification of the counter (e.g. Increment(5)) to the _MultisigProxy_ contract which will forward it to the _Counter_ contract (if approved by other users).
+A user can invoke the entry point _Send_ of the smart contract _MultisigProxy_ to propose or approve a modification of the counter. When the number of approvals is reached, the desired modification is sent to the contract _Counter_ via a transaction. A user can invoke the entry point _Withdraw_ of the smart contract _MultisigProxy_ to reject a proposed modification.
```
// Counter contract types
@@ -252,4 +250,4 @@ Notice in the _Withdraw_ function :
2- Modify the *increment* function to modify the reputation of a given *addr* address by granting one point of reputation. (use *count* as temporary variable for the _switch_ operator). If the voter is not registered yet in the *reputation* registry then add him. Otherwise update its reputation by incrementing by one its actual level. It is recommanded to use Map.add and Map.update when modifying a _map_.
- 3- Modify the *reputation_updated* variable (representing the new state of reputations) by iterating on voters with a _Set.fold_ operation and applying *increment* function on reputation.
\ No newline at end of file
+ 3- Modify the *reputation_updated* variable (representing the new state of reputations) by iterating on voters with a _Set.fold_ operation and applying *increment* function on reputation.
diff --git a/src/frontend/src/pages/Chapters/Reason/ChapterPolymorphism/course.md b/src/frontend/src/pages/Chapters/Reason/ChapterPolymorphism/course.md
index 475412d..80c5c52 100644
--- a/src/frontend/src/pages/Chapters/Reason/ChapterPolymorphism/course.md
+++ b/src/frontend/src/pages/Chapters/Reason/ChapterPolymorphism/course.md
@@ -1,6 +1,6 @@
# Chapter 21 : Polymorphism
-
+
When sending transactions between contracts, each contract must know the target contract interface and the parameter type of the target contract. This is done basically by separating type definition and function implementation and by using code inclusion.