Skip to content

Commit

Permalink
Merge pull request #283 from buidl-labs/course-fixes
Browse files Browse the repository at this point in the history
Course fixes
  • Loading branch information
manangouhari authored Mar 18, 2021
2 parents a37abb3 + e2035a5 commit a50f79b
Show file tree
Hide file tree
Showing 41 changed files with 482 additions and 424 deletions.
15 changes: 8 additions & 7 deletions lessons/inter-contract-calling/01/01.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -122,28 +123,28 @@ 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`(<span class="string-highlight">1 million Mutez = 1 Tez(or XTZ)</span>)

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<Type>`. But when it's being called with a value - it's called with `sp.<type>`.
> 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)`.
Hence, when you're specifying a large number of tokens, it's better to use `sp.tez`. Like - `sp.tez(0.1)`.
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(
Expand Down
14 changes: 8 additions & 6 deletions lessons/inter-contract-calling/02/02.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,26 @@ 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`
- `public_key_hash`
- `public_key`
- `secret_key`

<br />

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(
Expand All @@ -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`.
23 changes: 12 additions & 11 deletions lessons/inter-contract-calling/03/03.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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!?

Expand All @@ -122,30 +122,30 @@ 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 []
)
```

Unlike lists in Python, a list in SmartPy can't hold data of differ data types. All the items in a SmartPy list should be of the same type.
```python=
```python
✅ [1, 2, 3]
❌ ["one", 2, 3.0]
```

> #### 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(
Expand All @@ -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
Expand All @@ -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`.
Expand Down
22 changes: 11 additions & 11 deletions lessons/inter-contract-calling/04/04.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand All @@ -151,7 +151,7 @@ Wondering why can't you use `sp.TMap` to do the same thing?
Because `sp.TMap` only allows the same type of data as values.

For example, the following `sp.TMap` is invalid and will throw an error -
```python=
```python
❌ ❌ ❌
money = {
"amount": 4000,
Expand All @@ -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(
Expand Down Expand Up @@ -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":
Expand All @@ -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 -


Expand Down
29 changes: 14 additions & 15 deletions lessons/inter-contract-calling/05/05.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand All @@ -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 :)
Expand All @@ -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):

Expand All @@ -237,7 +237,7 @@ def send(self):
The full example below will clear up things even more :dart:

### Show me an example
```python=
```python
class Sender(sp.Contract):

def __init__(self, target_address):
Expand Down Expand Up @@ -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.

<br />

> 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.
Loading

0 comments on commit a50f79b

Please sign in to comment.