Skip to content

Commit

Permalink
Fix typos
Browse files Browse the repository at this point in the history
  • Loading branch information
AymericBethencourt committed May 11, 2020
1 parent 26668d7 commit 82ecd25
Show file tree
Hide file tree
Showing 30 changed files with 231 additions and 114 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<td width="255px"><img src="./public/readme.gif" alt="serverless mern" align="center" style="width: 255px" /></td>
<td>
Tezos Academy is a fun interactive tutorial develloped by <a href="https://octo.com/" target="_blank">OCTO Technology</a> on how to code smart contracts for <a href="https://tezos.com/" target="_blank">Tezos</a>. You are about to create a spaceship battle smart contract!<br /><br />
By default, Tezos smart contracts are written in <a href="https://tezos.gitlab.io/whitedoc/michelson.html" target="_blank">Michelson</a>, but it is an hard to learn low level formal language. That is why we decide for this tutorial to use <a href="https://ligolang.org/" target="_blank">PascaLIGO</a> instead. The syntax is high level, close to Pascal and tranpiles to Michelson.<br /><br />
By default, Tezos smart contracts are written in <a href="https://tezos.gitlab.io/whitedoc/michelson.html" target="_blank">Michelson</a>, but it is an hard to learn low level formal language. That is why we decide for this tutorial to use <a href="https://ligolang.org/" target="_blank">PascaLIGO</a> instead. The syntax is high level, close to Pascal and transpiles to Michelson.<br /><br />
In this tutorial, you are going to build a "Ship Factory" to build an army of spaceships, then we will add more and more functionalities as you progress through the tutorial, such as going into space battles!
</td>
</tr>
Expand Down
8 changes: 4 additions & 4 deletions src/Chapter/Chapter.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const MonacoEditor = ({ proposedSolution, proposedSolutionCallback }: any) => {
return (
<div>
<ControlledEditor
height="440px"
height="500px"
value={proposedSolution}
language="pascaligo"
theme="myCustomTheme"
Expand All @@ -62,9 +62,9 @@ const MonacoDiff = ({ solution, proposedSolution }: any) => {
return (
<div>
<DiffEditor
height="440px"
original={solution}
modified={proposedSolution}
height="500px"
original={proposedSolution}
modified={solution}
language="pascaligo"
// @ts-ignore
theme="myCustomTheme"
Expand Down
2 changes: 1 addition & 1 deletion src/Chapters/ChapterAbout/ChapterAbout.data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const data = `#Chapter 1 : Tezos Academy
Tezos Academy is a fun interactive tutorial develloped by <a href="https://octo.com/" target="_blank">OCTO Technology</a> on how to code smart contracts for <a href="https://tezos.com/" target="_blank">Tezos</a>. You are about to create spaceship battles smart contracts!
By default, Tezos smart contracts are written in <a href="https://tezos.gitlab.io/whitedoc/michelson.html" target="_blank">Michelson</a>, but it is an hard to learn low level formal language. For this tutorial, we will use <a href="https://ligolang.org/" target="_blank">PascaLIGO</a> instead. The syntax is high level, close to Pascal and tranpiles to Michelson.
By default, Tezos smart contracts are written in <a href="https://tezos.gitlab.io/whitedoc/michelson.html" target="_blank">Michelson</a>, but it is an hard to learn low level formal language. For this tutorial, we will use <a href="https://ligolang.org/" target="_blank">PascaLIGO</a> instead. The syntax is high level, close to Pascal and transpiles to Michelson.
## Objectives
Expand Down
4 changes: 2 additions & 2 deletions src/Chapters/ChapterAbout/ChapterAbout.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const ChapterStyled = styled.div`

export const ChapterGrid = styled.div`
display: grid;
grid-template-rows: 440px auto;
grid-template-rows: 500px auto;
grid-gap: 20px;
overflow-y: scroll;
Expand Down Expand Up @@ -102,7 +102,7 @@ export const Button = styled.div`
position: relative;
display: inline-block;
cursor: pointer;
margin: 20px auto;
margin: 20px auto 10px auto;
`;

export const ButtonBorder = styled.div`
Expand Down
8 changes: 6 additions & 2 deletions src/Chapters/ChapterConditionals/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const b : tez = 10mutez
const c : bool = (a = b) // false
```

⚠️ Notice that equality is checked with a single _=_ and not two like many languages.

⚠️ Also notice the use of _=/=_ for the inequality operator.

## Conditionals

Conditional logic enables forking the control flow depending on the state.
Expand All @@ -55,10 +59,10 @@ else skip;

## Your mission

We want to add contional so that we change the engine attribute to 1 only if it is equal to 0.
We want to conditionally change the engine attribute (third number) to 1 only if it is equal to 0.

<!-- prettier-ignore -->1- Refactor *modified\_ship* as a variable equal to *my\_ship*

<!-- prettier-ignore -->2- Then define a condition _if_ the engine attribute equal 0. Don't forget the attribates are defined as strings.
<!-- prettier-ignore -->2- Then define a condition _if_ the engine attribute equal 0. Don't forget the attributes are defined as strings.

<!-- prettier-ignore -->3- If the condition is met, change *modified\_ship* to it new value. Otherwise, _skip_ the instructions.
2 changes: 1 addition & 1 deletion src/Chapters/ChapterFunctions/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<dialog character="mechanics">Captain, why are you trying to change the part yourself? Just write a function on the terminal and send it to a droid.</dialog>

LIGO functions are the basic building block of contracts. Each entrypoint of a contract is a function and each smart contract must have at least one function named _main_ that dispatches controls to the other functions.
LIGO functions are the basic building block of contracts. Each entrypoint of a contract is a function and each smart contract must have at least one function named _main_ that dispatches the control flow to other functions.

When calling a function, LIGO makes a copy of the arguments but also the environment variables. Therefore any modification to these will not be reflected outside the scope of the function and will be lost if not explicitly returned by the function.

Expand Down
85 changes: 36 additions & 49 deletions src/Chapters/ChapterInteractions/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,32 @@

A contract can invoke another by emiting a transaction operation at the end of an entrypoint.

## Syntax
## Transactions

The keyword _operation_ is a predefined type which model transaction (contract invocation).

The keyword _transaction_ is predefined function which generates an _operation_ from following parameters:

- target contract parameter (entrypoint call to execute on the target contract)
- amount to transfer
- the target contract interface (which describes possible entrypoints of targeted contract)

_transaction_ function follows the syntax:
We have already seen the _Tezos.transaction_ in chapter 17 in order to send money to an address. It is also possible to use _Tezos.transaction_ to call an entrypoint from another contract. In that case, we store the transaction in a type _operation_ which is a predefined type representing a contract invocation.

```
const <operation_name> : operation = Tezos.transaction(<target_contract_parameter>, <amount_tez_transfer>, <target_contract_interface>);
const <operation_name> : operation = Tezos.transaction (<parameter>, <mutez>, <contract>);
```

<!-- prettier-ignore -->The contract interface of an already deployed contract can be retrieved with the *get\_contract* function. It takes the address of the target contract and returns a contract interface. The _contract_ type is a template type which dpends on a the type of target contract parameter.
where :

- _parameter_ is the entrypoint to call on the target contract,
- _mutez_ is the amount to transfer,
- _contract_ is the contract we want to interact with.

To get the contract we want to call and its entry points, we can use :

```
const <variable_name> : contract(<type_of_target_contract_parameter>) = Tezos.get_contract_opt(<target_contract_address>);
Tezos.get_contract_opt(<address>)
```

<!-- prettier-ignore -->Since a contract might be destroyed, the call to *Tezos.get\_contract\_opt* may not find the target contract. For a safer purpose, the function *get\_contract\_opt* is also available to retrieve a contract interface and work as *get\_contract* but returns an option of _contract(parameter)_
The function take an address and return an optional _contract_ (remember to use _option_). When no contract is found or the contract doesn't match the type, _None_ is returned.

## Example

The following example shows how a contract can invoke another by emiting a transaction operation at the end of an entrypoint.
In our case, we have a counter.ligo contract that accepts an action of type parameter, and we have a proxy.ligo contract that accepts the same parameter type, and forwards the call to the deployed counter contract.
In our case, we have a _counter.ligo_ contract that accepts an action of type _parameter_, and we have a _proxy.ligo_ contract that accepts the same parameter type, and forwards the call to the deployed counter contract.

```
// counter.ligo
Expand All @@ -59,28 +57,27 @@ function main (const action : parameter; const store : storage) : return is
```
// proxy.ligo
type storage is unit
type parameter is
Increment of nat
| Decrement of nat
| Reset
type storage is unit
type return is list (operation) * storage
const dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address)
const dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address) // Deployment address of counter.ligo
function proxy (const action : parameter; const store : storage): return is
block {
const counter : contract (parameter) =
case (Tezos.get_contract_opt (dest) : option (contract (parameter))) of
case (Tezos.get_contract_opt(dest) : option (contract (parameter))) of
Some (contract) -> contract
| None -> (failwith ("Contract not found.") : contract (parameter))
end;
const mock_param : parameter = Increment (5n);
const op : operation = Tezos.transaction (action, 0tez, counter);
const ops : list (operation) = list [op]
} with (ops, store)
const op : operation = Tezos.transaction (action, 0tez, counter); // E.g. with action = Increment (5n)
const operations : list (operation) = list [op]
} with (operations, store)
```

Notice that :
Expand All @@ -89,38 +86,28 @@ Notice that :
- the _proxy_ function returns a list of operation containing the newly created transaction.
- the _parameter_ type (counter parameter) has also been defined in proxy contract. The calling contract must know the parameter type of called contract.

## 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 basicaly by separating type definition and function implementation and by using inclusion. But a problem arises when creating a new contract which must communicate way and back (two-way communication) with an already deployed contract. The deployed contract cannot know the signature of a contract not yet created!

<!-- prettier-ignore -->Hopefully a solution exists to this problem of polymorphism, it is *Tezos.get\_entrypoint\_opt* function.

Let's consider two contracts _A_ and _B_. Contract _A_ ask some information from contract _B_ and they communicate between each other with transactions.
A sends a request to B, (it means _A_ calls an entrypoint of _B_, so contract _A_ includes type definition of _B_)
B receives the request, process the request and sends an response back to _A_ (it means _B_ calls an entrypoint of _A_, , so contract _B_ includes type definition of _A_)
Once they are deployed, we cannot change their includes.

Now let's consider a third smart contract _C_ which will communicate with _B_. (Like _A_)
Since we can't change _B_ (already deployed) , then _C_ must have same definition of _A_ to be able to receive transactions from _B_.

The problem is coming from the fact that _B_ must know the whole definition of _A_ parameter but it actually only needs one entrypoint used for the transaction. If _C_ implements the same entrypoint than _A_ (for receiving a message from _B_) then transaction will match the entrypoint and problems solved !

<!-- prettier-ignore -->For this purpose, the predefined function *Tezos.get\_entrypoint\_opt* can be used to retrieve the definition of a single entrypoint (from the whole variant).
## Your mission

<!-- prettier-ignore -->The predefined function *Tezos.get\_entrypoint\_opt* can be used in replacement of the *Tezos.get\_contract\_opt* function to retrieve contract interface but for only one entrypoint. It takes the requested entrypoint as parameter (with a special michelson syntax) and the address of the contract.
<!-- prettier-ignore -->1- Consider each of our weapons is managed by a smart contract :

```
const <variable_name>: contract(<type_of_target_contract_parameter>) = Tezos.get_entrypoint_opt(<entrypoint_name>, <target_contract_address>);
```

<!-- prettier-ignore --> *entrypoint\_name* is a double-quoted string with first character is % followed by the name of the entrypoint (and its first letter must not be capitalized) exemple: for an entrypoint FooBar the corresponding *entrypoint\_name* is "%fooBar"
// weapon.ligo
type storage is int
## Your mission
type parameter is
Fire of int
| Stop
<!-- prettier-ignore -->1- Consider the following smart contract :
type return is list (operation) * storage
function main (const action : parameter; const store : storage) : return is
((nil : list (operation)),
case action of
Fire (n) -> n
| Stop -> 0
end)
```

```
<!-- prettier-ignore -->2- Consider the contract in the editor. Notice the addresses of each weapon, and that the _orders_ function fetch the corresponding contracts. Your job is now to define the list of operations to send to the weapons. For this, start by creating _operations_ a list of type _operation_.

<!-- prettier-ignore -->2-
<!-- prettier-ignore -->3- Send a _Fire(5)_ transaction to the *right\_laser* contract, then _Stop_. Send a _Fire(5)_ transaction to the *left\_laser* contract, then _Stop_.
28 changes: 27 additions & 1 deletion src/Chapters/ChapterInteractions/exercise.ligo
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
// Type your solution below
type storage is unit

type parameter is
Fire of int
| Stop

type return is list (operation) * storage

const right_laser_address : address = ("tz1fND4ejogxWN7HB5JKdz119A48Cp2eYKj9" : address)
const left_laser_address : address = ("tz1PVWEWDcuow9R6y5EFwcHbFNoZBZ9RjxaB" : address)

function orders (const action : parameter; const store : storage): return is
block {
const right_laser : contract (action) =
case (Tezos.get_contract_opt(main_laser_address) : option (contract (parameter))) of
Some (contract) -> contract
| None -> (failwith ("Contract not found.") : contract (parameter))
end;
const left_laser : contract (action) =
case (Tezos.get_contract_opt(main_laser_address) : option (contract (parameter))) of
Some (contract) -> contract
| None -> (failwith ("Contract not found.") : contract (parameter))
end;

// Type your solution below

} with (operations, store)
33 changes: 32 additions & 1 deletion src/Chapters/ChapterInteractions/solution.ligo
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
// Type your solution below
type storage is unit

type parameter is
Fire of int
| Stop

type return is list (operation) * storage

const right_laser_address : address = ("tz1fND4ejogxWN7HB5JKdz119A48Cp2eYKj9" : address)
const left_laser_address : address = ("tz1PVWEWDcuow9R6y5EFwcHbFNoZBZ9RjxaB" : address)

function orders (const action : parameter; const store : storage): return is
block {
const right_laser : contract (action) =
case (Tezos.get_contract_opt(main_laser_address) : option (contract (parameter))) of
Some (contract) -> contract
| None -> (failwith ("Contract not found.") : contract (parameter))
end;
const left_laser : contract (action) =
case (Tezos.get_contract_opt(main_laser_address) : option (contract (parameter))) of
Some (contract) -> contract
| None -> (failwith ("Contract not found.") : contract (parameter))
end;

// Type your solution below
const operations : list (operation) = list [
Tezos.transaction (Fire(5), 0tez, right_laser);
Tezos.transaction (Stop, 0tez, right_laser);
Tezos.transaction (Fire(5), 0tez, left_laser);
Tezos.transaction (Stop, 0tez, left_laser);
]
} with (operations, store)
4 changes: 3 additions & 1 deletion src/Chapters/ChapterLoops/course.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ while <condition> block {
}
```

⚠️ If the while condition is never met, the block will will repeatedly be evaluated until the contract run out of gas or fails.
⚠️ If the while condition is never met, the block will repeatedly be evaluated until the contract run out of gas or fails.

ℹ️ About gas : The smart contracts interpreter uses the concept of gas. Each low-level instruction evaluation burns an amount of gas which is crafted to be proportional to the actual execution time and if an execution exceeds its allowed gas consumption, it is stopped immediately and the effects of the execution are rolled back. The transaction is still included in the block and the fees are taken, to prevent the nodes from being spammed with failing transactions. In Tezos, the economic protocol sets the gas limit per block and for each transaction, and the emitter of the transaction also set an upper bound to the gas consumption for its transaction. The economic protocol does not require the transaction fee to be proportional to the gas upper bound, however the default strategy of the baking software (that forges blocks) provided with Tezos current implementation does require it.

## For Loops

Expand Down
Loading

0 comments on commit 82ecd25

Please sign in to comment.