diff --git a/lessons/inter-contract-calling/01/01.mdx b/lessons/inter-contract-calling/01/01.mdx
index 596cbd85..8909019c 100644
--- a/lessons/inter-contract-calling/01/01.mdx
+++ b/lessons/inter-contract-calling/01/01.mdx
@@ -112,8 +112,9 @@ editor:
scenario.verify(test_bot.data.mutez_points == sp.mutez(5000))
---
-### Intro
-Awesome work defeating those nasty aliens :rocket:
+## Intro
+Awesome work defeating those nasty aliens 🚀
+
But, beware that was only the **first wave**, there's a greater challenge that lies ahead of you.
At least one good thing came out of the first battle, you managed to collect some **mutez** 💵 when you defeated the first wave.
@@ -122,20 +123,20 @@ It's a **smaller unit of XTZ**.
Simply a way to represent smaller amounts of Tezos.
This will come in handy to defeat the new challenge coming your way.
-You'll can use these `mutez_points` to buy power-ups from the `Market`(we'll implement the market in the coming chapters).
+You'll use these `mutez_points` to buy power-ups from the `Market`(we'll implement the market in the coming chapters).
-### Study time
+## Study time
Mutez is to XTZ(Currency of Tezos) what a cent is to dollar or what gram is to kg.
To be more accurate -
-`1,000,000 mutez = 1 XTZ`(1 million Mutez = 1 Tez(or XTZ))
+`1,000,000 mutez = 1 XTZ`(1 million Mutez = 1 Tez(or XTZ))
Similar to all other data types in SmartPy(sp.TNat, sp.TMap, etc) there are Tezos specific data types as well and one of them is [`sp.TMutez`](https://smartpy.io/dev/reference.html#_mutez).
> #### Note -
> In SmartPy, when a type is being specified - it's referened with `sp.T`. But when it's being called with a value - it's called with `sp.`.
> Example - `sp.TNat` and `sp.nat(5)`, `sp.TMutez` and `sp.mutez(500)`
-> If you're not familiar with data types, go through this [chapter](https://cryptocodeschool.in/lesson/chapter-08)
+> If you're not familiar with data types, go through this [chapter](/tezos/academy/module-01/chapter-08)
#### Difference between sp.mutez and sp.tez -
When you write `sp.mutez(100000)` it's equated to `0.1 Tez(XTZ)`.
@@ -143,7 +144,7 @@ Hence, when you're specifying a large number of tokens, it's better to use `sp.t
Whereas, `sp.mutez` helps you express smaller quantities with much better accuracy.
### Show me an example
-```python=
+```python
class Wallet(sp.Contract):
def __init__(self, initial_amount):
self.init(
diff --git a/lessons/inter-contract-calling/02/02.mdx b/lessons/inter-contract-calling/02/02.mdx
index dfc63f57..ea6b2be2 100644
--- a/lessons/inter-contract-calling/02/02.mdx
+++ b/lessons/inter-contract-calling/02/02.mdx
@@ -107,13 +107,13 @@ editor:
scenario += test_bot
---
-### Intro
+## Intro
Calibrating our plasma cannons for the next wave of aliens - what better way than to make your script a teeny bit better?
Right now, we're using `sp.address` to give a `bot_manager` address to our `Cryptobot`.
But, SmartPy has a special function called `sp.test_account(seed)` which we'll use to improve upon this.
-### Study time
+## Study time
`sp.test_account(seed)` takes a random string as an argument and generates several properties based on this `seed` value.
A test accounts has the following fields -
- `address`
@@ -121,10 +121,12 @@ A test accounts has the following fields -
- `public_key`
- `secret_key`
+
+
Don't worry about what all the fields mean. We only need the `address` for our purpose :D
### Show me an example
-```python=
+```python
class Wallet(sp.Contract):
def __init__(self, initial_amount, owner_address):
self.init(
@@ -142,11 +144,11 @@ def test():
Building on our example from the previous chapter, here a new field has been added in contract storage, `owner`.
Inside the test, we generated a test account using `sp.test_account("Wallet Example Account")` and passed in the address to wallet using `account_owner.address`.
-### #buidl-ing time
+## #buidl-ing time
-#### Let's refactor!
+### Let's refactor!
Now you know about `sp.test_account`, use it instead of `sp.address` in our `Cryptobot`.
-#### Step by step walkthrough
+### Step by step walkthrough
1. Replace `my_address` variable with `my_account` and assign and invoke it with `sp.test_account` with the `seed` of `"Cryptobot Owner"`.
2. Replace `my_address` in the Contract initialization with `my_account.address`.
\ No newline at end of file
diff --git a/lessons/inter-contract-calling/03/03.mdx b/lessons/inter-contract-calling/03/03.mdx
index ca60e612..9bab6ed1 100644
--- a/lessons/inter-contract-calling/03/03.mdx
+++ b/lessons/inter-contract-calling/03/03.mdx
@@ -113,7 +113,7 @@ editor:
scenario += market
---
-### Intro
+## Intro
In battle, lists are important!
How else would you keep track of all the powerups you can buy!?
@@ -122,11 +122,11 @@ In this one, let's learn how to use the **list** data type in SmartPy.
Later in this chapter you'll also start working on a new smart contract, `Market`, which will allow you to get powerups in your final battle 🚀
Let's go!
-### Study time
+## Study time
List type in SmartPy is represented by `sp.TList`.
It can be initialized by using either `[]` or `sp.list()`.
-```python=
+```python
self.init(
history = sp.list() # or []
)
@@ -140,12 +140,12 @@ Unlike lists in Python, a list in SmartPy can't hold data of differ data types.
> #### Note
> Not all python lists functions are available for lists in SmartPy.
-> Check the reference [here:scroll:](https://smartpy.io/dev/reference.html#_lists) to see a detailed list of functions available.
+> Check the reference [here 📜](https://smartpy.io/dev/reference.html#_lists) to see a detailed list of functions available.
### Show me an example
We're going to build on top of the `Wallet` example from the previous chapter.
-```python=
+```python
class Wallet(sp.Contract):
def __init__(self, initial_amount, owner_address):
self.init(
@@ -163,9 +163,10 @@ def test():
scenario.verify(w.data.amount == sp.mutez(1000))
```
+
Notice a new `transaction` state variable? It's a list.
Now, we're going to add a new `entry_point` to this smart contract.
-```python=
+```python
@sp.entry_point
def add_transaction(self, amount):
self.data.amount += amount
@@ -174,20 +175,20 @@ def add_transaction(self, amount):
Take a look at the `entry_point` right above, it uses `.push` which is a method you can use to add items to the top of the list.
**Now to test this code(coz you know, testing is a thing) -**
-```python=
+```python
scenario += w.add_transaction(sp.mutez(500))
scenario += w.add_transaction(sp.mutez(300))
scenario.verify(w.data.amount == sp.mutez(1800))
```
-### #buidl-ing time
+## #buidl-ing time
-#### New feature request!
+### New feature request!
You're the smart contract expert in town.
The Cryptoverse `Market` has tasked you with writing the smart contract, `Market`, for it to interact with your `Cryptobot`.
-#### Step by step walkthrough
+### Step by step walkthrough
1. Create a new smart contract, `Market`.
2. Market will have a contract storage variable - `powerups` which will be equal to `["time_freeze", "one_shot_kill"]`.
3. Inside test function, initialize an instance of the `Market` contract and store it inside `market`.
diff --git a/lessons/inter-contract-calling/04/04.mdx b/lessons/inter-contract-calling/04/04.mdx
index e4d1d7ed..645e315d 100644
--- a/lessons/inter-contract-calling/04/04.mdx
+++ b/lessons/inter-contract-calling/04/04.mdx
@@ -122,27 +122,27 @@ editor:
scenario += market
---
-### Intro
+## Intro
Right now, the system is broken.
You can't afford broken systems, you've got the threat of aliens looming over your head in case you forgot!
You've stored `powerups` in the `Market`, but we've no idea how long a `powerup` lasts.
Let's fix this with data type provided by SmartPy - [record](https://smartpy.io/dev/reference.html#_records)
-### Study time
+## Study time
Records are the kind of structures that seem not of much use at first but turn out to be extremely crucial on taking a closer look, it's the underdog of types 🐶
A record can hold multiple variales of different(or same) types under one namespace and it's represented by the type `sp.TRecord` in SmartPy.
Confused?
Take a look at the snippet below ⬇️
-```python=
+```python
money = sp.record(amount = 1000, currency = "$")
```
As I told you before, a record is just multiple variables gathered under one.
You can access `amount` and `currency` through the following -
-```python=
+```python
money.amount
money.currency
```
@@ -165,7 +165,7 @@ This won't be a problem with records because they're designed to hold multiples
### Show me an example
Following the lead from previous chapters, this example is also building on top of our `Wallet` smart contract.
-```python=
+```python
class Wallet(sp.Contract):
def __init__(self, initial_amount, owner_address):
self.init(
@@ -194,7 +194,7 @@ def test():
```
Using records we've revamped the `add_transaction` entry point.
Let's take a closer look.
-```python=
+```python
@sp.entry_point
def add_transaction(self, transaction):
sp.if transaction.action == "sent":
@@ -209,19 +209,19 @@ If the `action` is `sent` we deduct the `amount`.
But, how do we call this entry point?
Look at the snippet below.
-```python=
+```python
scenario += w.add_transaction(sp.record(amount = sp.mutez(500), action = "sent"))
```
Passing `sp.record` with the fields inside it to `add_transaction`.
Records seem simple now, don't they!?
-### #buidl-ing time
+## #buidl-ing time
-#### New feature request!
+### New feature request!
In the last chapter, we successfuly defined the smart contract for `Market` but we forgot that powerups don't last forever! We listed out the `powerups` in the list but didn't mention the `duration` for them.
It's time to fix it 🔧
-#### Step by step walkthrough
+### Step by step walkthrough
1. Edit the `powerups` list inside the `Market` contract to hold two records, both of them will have a `power` field and a `duration` field -
diff --git a/lessons/inter-contract-calling/05/05.mdx b/lessons/inter-contract-calling/05/05.mdx
index d38f8fdb..9abc1fb6 100644
--- a/lessons/inter-contract-calling/05/05.mdx
+++ b/lessons/inter-contract-calling/05/05.mdx
@@ -183,13 +183,13 @@ editor:
scenario.verify(test_bot.data.mutez_points == sp.mutez(2000))
---
-### Intro
+## Intro
How do you plan on winning the war if you can't order `powerups` from the Market?
**Inter-contract calling** is here to save us.
It can make your smart contracts go *super saiyan* 🔥.
-### Study time
+## Study time
Inter-contract calling is simply the method of invoking the entry point of a contract, from another smart contract.
This means, your `Cryptobot` will be able to call an entry point that exists in `Market`.
@@ -198,12 +198,12 @@ Inter-contract calling not only **helps two contracts talk to each other** but a
> Note - You can learn about oracles through this [article](https://academy.binance.com/en/articles/blockchain-oracles-explained).
To implement inter-contract calling, you need to understand `sp.transfer` first. As the name suggests it transfers some data and amount to a destination contract(this is what calls the desired entry point).
-```python=
+```python
sp.transfer(data_to_be_sent, amount_of_tezos, destination_contract)
```
It calls the destination contract with `data_to_be_sent` as a parameter while sending the specified `amount_of_tezos` to it.
`destination_contract` needs to be of type, `sp.TContract` created with `sp.contract`.
-```python=
+```python
sp.contract(t, address, entry_point = "")
```
Don't worry if it looks overwhelming at first glance, we're going to break it down :)
@@ -215,7 +215,7 @@ Don't worry if it looks overwhelming at first glance, we're going to break it do
The result of `sp.contract` is passed to `destination_contract` in `sp.transfer`.
-```python=
+```python
@sp.entry_point
def send(self):
@@ -277,30 +277,29 @@ This is a bare-bones example, we covered the `send` function in the section abov
3. `recieve` entry point simply assigns `msg` the value it's being sent as the `payload`.
-### #buidl-ing time
+## #buidl-ing time
-#### New feature request!
+### New feature request!
It's time to build the functionality of buying a powerup from the `Market` finally 🚀
Let's give our `Cryptobot` the ability to buy a `powerup`.
-#### Step by step walkthrough
+### Step by step walkthrough
1. Accept `market_address` as an arugment for `Cryptobot` and initialize the `Cryptobot` with `market_address` equal to `market.address`.(Look at the example above to see how we store `target_address` inside the `Sender` contract.)
2. Add `active_powerup` to `Cryptobot`'s contract storage and initialize it to be a record which holds -
- 1. power which is an empty string
- 2. duration which is equal to 0
-
-
-5. Implement `buy_powerup` inside `Cryptobot`
+ * power which is an empty string
+ * duration which is equal to 0
+3. Implement `buy_powerup` inside `Cryptobot`
- Define `data_type` as a record which holds a variable called `powerup` of type string.
- Define the `market_contract` using `Market's` address that is pointed at the entry point `send_powerup` and accepts a data type of string. Don't forget about `.open_some()`
- Reduce 3000 mutez from `mutez_points` in `Cryptobot` as each `powerup` costs 3000 mutez.
- Define `data_to_be_sent` which is a record inside which a variable `powerup` is to be set equal to the parameter accepted through the function.
- Finally, send the `data_to_be_sent` to the Market(`market_contract`) using `sp.transfer` along with 0 Mutez.
+
> In the coming chapters we'll implement `send_powerup` in `Market` and `recieve_powerup` in `Cryptobot`.
-#### Testing our code
+### Testing our code
- Invoke `buy_powerup` with `"time_freeze"` as the argument and add it to the scenario.
- Use `scenario.verify` to confirm whether `mutez_points` in `Cryptobot` are equal to 2000 mutez.
\ No newline at end of file
diff --git a/lessons/inter-contract-calling/06/06.mdx b/lessons/inter-contract-calling/06/06.mdx
index b519d52d..21a8f164 100644
--- a/lessons/inter-contract-calling/06/06.mdx
+++ b/lessons/inter-contract-calling/06/06.mdx
@@ -210,20 +210,22 @@ editor:
scenario += test_bot
---
-### Intro
+## Intro
We'll take a short detour from inter-contract calling to learn and explore a few other topics that will help you build the `Cryptobot` of your dream to absolutely dominate the war against the aliens 🤩
In this one we'll cover a slew of different topics including `sub_entry_point` and `sp.for`.
-### Study time
-#### 1. Sub entry point
-Sub entry points allow you to define functions in a smart contract that can **ONLY** be called from other entry points of the same contract.
+## Study time
+### 1. Sub entry point
+Sub entry points allow you to define functions in a smart contract that can **ONLY** be called from other entry points of the same contract.
But why would you even need something like this?
1. **Modularization** - Break down your code into different pieces to keep the code in your entry points clean and to the point. Makes the code easier to maintain and more readable.
2. **Re-usability** - Once implemented, you can use them where ever needed. I think of them as **utility functions** that play a role in the success of other functions but aren't of much use indepedently.
+
+
Here's how you define a sub entry point -
-```python=
+```python
@sp.sub_entry_point
def double(self, x):
sp.result(x * 2)
@@ -231,7 +233,7 @@ def double(self, x):
Notice, **`sp.result`** is used to return from a sub entry point instead of `return`.
And it can be invoked like this -
-```python=
+```python
@sp.entry_point
def update_result(self, num):
# Assume double is a sub entry point already implemented in the smart contract.
@@ -239,19 +241,25 @@ def update_result(self, num):
```
Sub entry points can access the contract storage - if your function doesn't need to access the contract storage, you should use [`sp.global_lamba` ](https://smartpy.io/dev/reference.html#_lambdas).
-**2. Looping with `sp.for`**
+### 2. Looping with `sp.for`
+
+
+
Remember how we needed to use `sp.if` instead of `if` in SmartPy?
Similarly, `for` and `while` have their SmartPy counter-parts as `sp.for` and `sp.while`.
-```python=
+```python
transfers = [-12, 15, -10, 20, 30]
sp.for transfer in transfers:
self.data.total += transfer
```
You need to use `sp.range` instead of `range`.
-**3. Local variables using `sp.local`**
+### 3. Local variables using `sp.local`
+
+
+
You can define local variables in SmartPy using `sp.local` -
-```python=
+```python
total = sp.local("total", 0)
```
But why not just define a normal python variable like - `total = 0`?
@@ -259,8 +267,10 @@ Because normal python variables can't be updated during execution of a smart con
- First argument to `sp.local` is the name which will be used to refer to the variable in error message.
- Second argument is the initial value.
+
+
**Value of a local variable is accessed through `.value`** -
-```python=
+```python
x = sp.local("x", 0)
# now to access or modify the value of x, you need to use `x.value`
x.value = 2
@@ -272,7 +282,7 @@ This is mostly helpful with loops wherever you need to keep track of something.
Don't worry, we'll use this in our `Market` smart contract. That'll bring more clarity.
### Show me an example
-```python=
+```python
@sp.sub_entry_point
def add_to_total_received(self, amount):
self.data.total_received += amount
@@ -287,14 +297,14 @@ def calculate_received(self):
Imagine this as a part of a `Ledger` smart contract.
We've got an entry point `calculate_received` that loops over the transactions, if the transaction was received - it adds the amount to the total through the sub entry point `add_to_total_received`.
-### #buidl-ing time
+## #buidl-ing time
-#### New feature request!
+### New feature request!
We'll have to help the `Market` peeps find which `powerup` we want before they can send it over to your `Cryptobot`.
Let's put our knowledge of sub entry point and loops to use 🚀
-#### Step by step walkthrough
+### Step by step walkthrough
- Implement the sub entry point `find_powerup` in the `Market` contract.
1. Define a local variable called `powerup_to_send` which should be a record which holds a variable called power(equal to an empty string) and another variable called duration(equal to 0).
2. Loop through the `powerups` in the contract storage.
diff --git a/lessons/inter-contract-calling/07/07.mdx b/lessons/inter-contract-calling/07/07.mdx
index 5c954187..3e86d76f 100644
--- a/lessons/inter-contract-calling/07/07.mdx
+++ b/lessons/inter-contract-calling/07/07.mdx
@@ -117,9 +117,7 @@ editor:
# test our code over here.
-
-
- answer: |
+ answer: |
import smartpy as sp
class Cryptobot(sp.Contract):
@@ -235,31 +233,35 @@ editor:
scenario += test_bot.buy_powerup('time_freeze')
scenario.verify(test_bot.data.mutez_points == sp.mutez(2000))
scenario.verify(test_bot.data.active_powerup.power == 'time_freeze')
-
---
-### Intro
+## Intro
+
You've told `Market` which `powerup` you want, but don't you want to get the `powerup` back!?
After all, `powerups` will help you destroy the aliens.
-### Study time
+## Study time
+
So far, we've implemented only one inter-contract call.
But to complete the whole process of buying a powerup, we're going to need one more from `Market` to `Cryptobot` to send the real `powerup`.
![inter-contract call](https://i.imgur.com/JjgArPu.png)
This in loose terms is called **cyclic inter-contract calls**.
-- First contract calls the Second contract and then the Second contract calls the First contract.
+- First contract calls the Second contract and then the Second contract calls the First contract.
+
There's a last piece in the puzzle that you need to understand to implement the full functionality - `sp.to_address`.
`sp.to_address` accepts a contract(`sp.TContract`) and returns the address(`sp.TAddress`) of that contract.
It can be used in combination with `sp.self` to generate the address of the currenty smart contract inside an entry point.
+
> Note - `sp.self` refers to the contract it's being used inside.
-```python=
+
+```python
sp.to_address(sp.self)
```
@@ -267,29 +269,30 @@ Super useful for our case because the `Cryptobot` needs to send its own address
Puzzle clicking together now? 🔥
-### #buidl-ing time
-
-#### New feature request!
+## #buidl-ing time
+
+### New feature request!
+
We're going to have to **buidl** a lot of stuff in this one.
Let's go and complete our whole system so that you can finally use the powerups to blow the nasty alien to pieces
+### Step by step walkthrough
-#### Step by step walkthrough
1. Modify `buy_powerup` in `Cryptobot`
- 1. Modify `data_type` to also include `cryptobot_address` which is of type `sp.TContract` that accepts a record of string `power` and nat `duration`.
- 2. Define `self_contract` - it's the contract that holds the details to `receive_powerup` entry point in `Cryptobot`.
- - accepts a record of same shape as `active_powerup`.
- - address points to `Cryptobot`( use `sp.to_address`)
- - points to `recieve_powerup` entry point.
- 3. Modify `data_to_be_sent` to hold `cryptobot_contract` as well, which is equal to `self_contract`.
-
+ * Modify `data_type` to also include `cryptobot_address` which is of type `sp.TContract` that accepts a record of string `power` and nat `duration`.
+ * Define `self_contract` - it's the contract that holds the details to `receive_powerup` entry point in `Cryptobot`.
+ * accepts a record of same shape as `active_powerup`.
+ * address points to `Cryptobot`( use `sp.to_address`)
+ * points to `recieve_powerup` entry point.
+ * Modify `data_to_be_sent` to hold `cryptobot_contract` as well, which is equal to `self_contract`.
2. Implement `send_powerup` in `Market`
- 1. Define `powerup_to_send` as the result of `find_powerup`.
- 2. Make an inter-contract call to `cryptobot_contract` and send to it the `powerup_to_send`.
+ * Define `powerup_to_send` as the result of `find_powerup`.
+ * Make an inter-contract call to `cryptobot_contract` and send to it the `powerup_to_send`.
3. Implement `receive_powerup` in `Cryptobot`.
- - Set `active_powerup` equal to the `poweup` being received as the parameter.
+ - Set `active_powerup` equal to the `poweup` being received as the parameter.
+
+### Testing our code
-#### Testing our code
1. Invoke `Cryptobot.buy_powerup` inside `test` function with the parameter `time_freeze`.
2. Use `scenario.verify` to check whether `mutez_points` held by `Cryptobot` is equal to 2000 mutez.
-3. Use `scenario.verify` to check wether the `active_power.power` of `Cryptobot` is `"time_freeze"` or not.
\ No newline at end of file
+3. Use `scenario.verify` to check wether the `active_power.power` of `Cryptobot` is `"time_freeze"` or not.