Skip to content

Commit

Permalink
Improving section 1 text
Browse files Browse the repository at this point in the history
  • Loading branch information
viniblack authored and danicuki committed Jul 24, 2024
1 parent 59b98e9 commit 5cf10b0
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 162 deletions.
48 changes: 25 additions & 23 deletions Rust_State_Machine/pt-BR/Section_1/Lesson_1_Balances_Pallet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Como mencionado anteriormente, no coração de uma blockchain está uma máquina

Podemos criar uma máquina de estados muito ingênua usando abstrações simples de Rust, e através disso aprender sobre Rust no contexto de blockchains.

Queremos manter nosso código organizado, então não vamos realmente começar a construir no arquivo main.rs, mas sim em módulos Rust separados. Podemos pensar no arquivo main.rs como a cola que une tudo, e veremos isso ao longo deste projeto.
Queremos manter nosso código organizado, então não vamos realmente começar a construir no arquivo `main.rs`, mas sim em módulos Rust separados. Podemos pensar no arquivo `main.rs` como a cola que une tudo, e veremos isso ao longo deste projeto.

"Pallet" é um termo específico do Polkadot SDK, que se refere a módulos Rust que contêm lógica específica para o runtime da sua blockchain. Vamos começar a usar esse termo aqui porque o que construímos aqui se assemelhará muito ao que você verá com o Polkadot SDK.

Expand All @@ -34,51 +34,53 @@ Este é um ótimo ponto de partida, e o primeiro Pallet que vamos construir.

1. Crie um novo arquivo na pasta `src` chamado `balances.rs`

```bash
touch src/balances.rs
```
```bash
touch src/balances.rs
```

2. Neste arquivo, crie uma `struct`, que atuará como estado e ponto de entrada para este módulo:

```rust
pub struct Pallet {}
```
```rust
pub struct Pallet {}
```

3. Agora volte para `src/main.rs` e importe este novo módulo, que incluirá toda a lógica dentro dele:

```rust
mod balances;
```
```rust
mod balances;
```

4. Se executarmos seu programa agora, você verá que ele ainda é compilado e executado, mas poderá mostrar alguns avisos como:

```rust
warning: struct `Pallet` is never constructed
--> src/balances.rs:1:12
|
1 | pub struct Pallet { }
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default

warning: `pr` (bin "pr") generated 1 warning
```
```rust
warning: struct `Pallet` is never constructed
--> src/balances.rs:1:12
|
1 | pub struct Pallet { }
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default

warning: `pr` (bin "pr") generated 1 warning
```

Tudo bem! Ainda não começamos a usar nosso Pallet, mas você pode ver que o compilador Rust está detectando nosso novo código e trazendo essa lógica para nosso programa principal. Este é o início da construção do nosso primeiro módulo de máquina de estados.

## Exercícios:

Em `balances.rs`:

```rust
/* TODO: crie uma nova struct pública chamada `Pallet`. */
```

On `main.rs`:
Em `main.rs`:

```rust
/* TODO: use seu novo módulo `balances` */

fn main() {
println!("Hello, world!");
println!("Hello, world!");
}
```

Expand Down
57 changes: 28 additions & 29 deletions Rust_State_Machine/pt-BR/Section_1/Lesson_2_Add_State.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,34 @@ Para isso, usaremos um `BTreeMap`, que podemos importar da biblioteca `std` do R

1. Importe o objeto `BTreeMap`.

```rust
use std::collections::BTreeMap;
```
```rust
use std::collections::BTreeMap;
```

2. Crie um campo `balances` em `Pallet` usando o `BTreeMap`.
Para a `chave`, usaremos uma string estática simples por enquanto. Dessa forma, podemos acessar usuários como `"alice"`, `"bob"`, etc. Isso será alterado no futuro.

Para a `chave`, usaremos uma string estática simples por enquanto. Dessa forma, podemos acessar usuários como `"alice"`, `"bob"`, etc... Isso será alterado no futuro.
Para o `valor`, usaremos um `u128`, que é o maior tipo suportado nativamente no Rust. Isso permitirá que nossos usuários tenham saldos muito grandes se quisermos.

Para o `valor`, usaremos um `u128`, que é o maior tipo suportado nativamente no Rust. Isso permitirá que nossos usuários tenham saldos muito grandes se quisermos.
No final, isso ficará assim:

No final, isso ficará assim:

```rust
pub struct Pallet {
balances: BTreeMap<String, u128>,
}
```
```rust
pub struct Pallet {
balances: BTreeMap<String, u128>,
}
```

1. Finalmente, precisamos de uma maneira de inicializar este objeto e seu estado. Para isso, vamos implementar uma função na `Pallet` chamada `fn new()`:
3. Finalmente, precisamos de uma maneira de inicializar este objeto e seu estado. Para isso, vamos implementar uma função na `Pallet` chamada `fn new()`:

```rust
impl Pallet {
pub fn new() -> Self {
Self {
balances: BTreeMap::new()
}
}
}
```
```rust
impl Pallet {
pub fn new() -> Self {
Self {
balances: BTreeMap::new(),
}
}
}
```

## Exercício:

Expand All @@ -52,16 +51,16 @@ No `balances.rs`:
use std::collections::BTreeMap;

pub struct Pallet {
// Um armazenamento simples mapeando contas (`String`) para seus saldos (`u128`).
/* TODO: Adicionar um campo `balances` que é um `BTreeMap` de `String` para `u128`. */
// Um armazenamento simples mapeando contas (`String`) para seus saldos (`u128`).
/* TODO: Adicionar um campo `balances` que é um `BTreeMap` de `String` para `u128`. */
}

impl Pallet {
/// Cria uma nova instância do módulo de saldos.
pub fn new() -> Self {
/* TODO: Retornar uma nova instância da struct `Pallet`. */
unimplemented!() // Remova esta linha após implementar a função
}
/// Cria uma nova instância do módulo de saldos.
pub fn new() -> Self {
/* TODO: Retornar uma nova instância da struct `Pallet`. */
unimplemented!() // Remova esta linha após implementar a função
}
}
```

Expand Down
92 changes: 47 additions & 45 deletions Rust_State_Machine/pt-BR/Section_1/Lesson_3_Store_And_Read.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Você pode encontrar a [solução para a etapa anterior aqui](https://gist.githu

Agora que estabelecemos os conceitos básicos do nosso módulo de saldos, vamos adicionar maneiras de interagir com ele.

Para fazer isso, continuaremos a criar mais funções implementadas em `Pallet` que concedem acesso para ler, escrever e atualizar o `balances: BTreeMap` que criamos.
Para fazer isso, continuaremos a criar mais funções implementadas em `Pallet` que concedem acesso para ler, escrever e atualizar o `balances: BTreeMap` que criamos.

Finalmente, veremos como é realmente começar a interagir com nosso pallet de saldos a partir do arquivo `main.rs`.

Expand All @@ -18,7 +18,7 @@ Antes de continuarmos, vamos dedicar um momento para revisar alguns conceitos de

Um dos principais princípios de Rust é remover comportamento indefinido do seu código.

Uma maneira de ocorrer comportamento indefinido é permitindo que estados como `null` existam. Rust previne isso fazendo com que o usuário trate explicitamente todos os casos, e é aqui que entra a criação do tipo `Option` Dedique um momento para revisar [a seção sobre `Option`](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values) do livro de Rust, se necessário.
Uma maneira de ocorrer comportamento indefinido é permitindo que estados como `null` existam. Rust previne isso fazendo com que o usuário trate explicitamente todos os casos, e é aqui que entra a criação do tipo `Option`. Dedique um momento para revisar [a seção sobre `Option`](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html?highlight=option#the-option-enum-and-its-advantages-over-null-values) do livro de Rust, se necessário.

A API do `BTreeMap` usa um `Option` ao ler valores do mapa, já que pode ser que você peça para ler o valor de alguma chave que você não definiu. Por exemplo:

Expand All @@ -38,23 +38,22 @@ A maneira mais verbosa é usando uma declaração de `match`:
```rust
let maybe_value = map.get(&"alice");
match maybe_value {
Some(value) => {
// fazer algo com o `value`
},
None => {
// talvez retornar um erro já que não havia valor lá
}
Some(value) => {
// fazer algo com o `value`
},
None => {
// talvez retornar um erro já que não havia valor lá
}
}
```


> 🚨 **Alerta:** O que você **NÃO DEVE** fazer é usar `unwrap()` cegamente em opções. Isso resultará em um `panic` no seu código, o que é exatamente o tipo de coisa que Rust foi projetado para prevenir! Em vez disso, você deve sempre tratar explicitamente todos os seus diferentes casos lógicos, e se deixar que Rust faça seu trabalho, seu código será super seguro.
> 🚨 **Alerta:** O que você **NÃO DEVE** fazer é usar `unwrap()` cegamente em opções. Isso resultará em um `panic` no seu código, o que é exatamente o tipo de coisa que Rust foi projetado para prevenir! Em vez disso, você deve sempre tratar explicitamente todos os seus diferentes casos lógicos, e se deixar que Rust faça seu trabalho, seu código será super seguro.
No contexto do que estamos projetando para o módulo de saldos, temos um mapa que possui um número arbitrário de chaves de usuário e seus valores de saldo.

O que devemos fazer quando lemos o saldo de um usuário que não existe no nosso mapa?

Bem, o truque aqui é que no contexto das blockchains, um usuário ter None saldo e um usuário ter `0` saldo é a mesma coisa. Claro, há alguns detalhes mais finos a serem expressos entre um usuário que existe em nosso estado com valor 0 e um usuário que não existe de todo, mas para os propósitos de nossas APIs, podemos tratá-los da mesma forma.
Bem, o truque aqui é que no contexto das blockchains, um usuário ter `None` saldo e um usuário ter `0` saldo é a mesma coisa. Claro, há alguns detalhes mais finos a serem expressos entre um usuário que existe em nosso estado com valor 0 e um usuário que não existe de todo, mas para os propósitos de nossas APIs, podemos tratá-los da mesma forma.

Como isso se parece?

Expand All @@ -81,53 +80,56 @@ Para tornar nosso módulo útil, precisamos ter pelo menos algumas funções que

1. Crie uma nova função dentro de `impl Pallet` chamada `fn set_balance`:

```rust
impl Pallet {
pub fn set_balance(&mut self, who: &String, amount: u128) {
self.balances.insert(who, amount);
}
```rust
impl Pallet {
pub fn set_balance(&mut self, who: &String, amount: u128) {
self.balances.insert(who.clone(), amount);
}

// -- snip --
}
```
// -- snip --
}
```

Como você pode ver, esta função simplesmente recebe informações sobre qual usuário queremos definir o saldo e qual saldo queremos definir. Isso então empurra essa informação para nosso `BTreeMap`, e isso é tudo.
Como você pode ver, esta função simplesmente recebe informações sobre qual usuário queremos definir o saldo e qual saldo queremos definir. Isso então empurra essa informação para nosso `BTreeMap`, e isso é tudo.

2. Crie uma nova função dentro de `impl Pallet` chamada `fn balance`:

```rust
pub fn balance(&self, who: &String) -> u128 {
*self.balances.get(&who).unwrap_or(&0)
}
```
```rust
impl Pallet {
pub fn balance(&self, who: &String) -> u128 {
*self.balances.get(&who).unwrap_or(&0)
}
}
```

Como você pode ver, esta função nos permite ler o saldo dos usuários em nosso mapa. A função permite que você insira algum usuário e nós retornaremos o saldo dele.
Como você pode ver, esta função nos permite ler o saldo dos usuários em nosso mapa. A função permite que você insira algum usuário e nós retornaremos o saldo dele.

> 🚨 **Alerta:** Note que fazemos nosso pequeno truque aqui! Em vez de expor uma API que força o usuário a lidar com um `Option` somos capazes de fazer nossa API sempre retornar um `u128` convertendo qualquer usuário com valor `None` em `0`.
> 🚨 **Alerta:** Note que fazemos nosso pequeno truque aqui! Em vez de expor uma API que força o usuário a lidar com um `Option`, somos capazes de fazer nossa API sempre retornar um `u128` convertendo qualquer usuário com valor `None` em `0`.

## Exercício:

No `balances.rs`:

```rust
impl Pallet {
/// Cria uma nova instância do módulo de saldos.
pub fn new() -> Self {
Self { balances: BTreeMap::new() }
}

/// Define o saldo de uma conta `who` para algum `amount`.
pub fn set_balance(&mut self, who: &String, amount: u128) {
/* Insira `amount` no BTreeMap sob `who`. */
self.balances.insert(who.clone(), amount);
}

/// Obtém o saldo de uma conta `who`.
/// Se a conta não tiver saldo armazenado, retornamos zero.
pub fn balance(&self, who: &String) -> u128 {
/* Retorna o saldo de `who`, retornando zero se `None`. */
*self.balances.get(who).unwrap_or(&0)
}
/// Cria uma nova instância do módulo de saldos.
pub fn new() -> Self {
Self { balances: BTreeMap::new() }
}

/// Define o saldo de uma conta `who` para algum `amount`.
pub fn set_balance(&mut self, who: &String, amount: u128) {
/* Insira `amount` no BTreeMap sob `who`. */
unimplemented!()
}

/// Obtém o saldo de uma conta `who`.
/// Se a conta não tiver saldo armazenado, retornamos zero.
pub fn balance(&self, who: &String) -> u128 {
/* Retorna o saldo de `who`, retornando zero se `None`. */
unimplemented!()
}
}
```

A seguir, escreveremos nosso primeiro teste e realmente interagiremos com nosso módulo de saldos. Animado para a próxima etapa? Nós estamos!
A seguir, escreveremos nosso primeiro teste e realmente interagiremos com nosso módulo de saldos. Animado para a próxima etapa? Nós estamos!
Loading

0 comments on commit 5cf10b0

Please sign in to comment.