Skip to content

Commit

Permalink
safemath part1
Browse files Browse the repository at this point in the history
  • Loading branch information
antododo committed Mar 9, 2018
1 parent 949c871 commit aabd3fe
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 70 deletions.
2 changes: 1 addition & 1 deletion fr/5/08-erc721-8.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "ERC721: takeOwnership"
title: "ERC721 : takeOwnership"
actions: ['vérifierLaRéponse', 'indice']
requireLogin: true
material:
Expand Down
52 changes: 26 additions & 26 deletions fr/5/09-safemath-1.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Preventing Overflows
title: Prévenir les débordements
actions: ['vérifierLaRéponse', 'indice']
requireLogin: true
material:
Expand All @@ -10,11 +10,11 @@ material:
pragma solidity ^0.4.19;
import "./ownable.sol";
// 1. Import here
// 1. Importez ici
contract ZombieFactory is Ownable {
// 2. Declare using safemath here
// 2. Declarez que l'on utilise safemath ici
event NewZombie(uint zombieId, string name, uint dna);
Expand Down Expand Up @@ -384,44 +384,44 @@ material:
}
---

Congratulations, that completes our ERC721 implementation!
Félicitations, cela complète notre implémentation ERC721 !

That wasn't so tough, was it? A lot of this Ethereum stuff sounds really complicated when you hear people talking about it, so the best way to understand it is to actually go through an implementation of it yourself.
Ce n'était pas si dur que ça, n'est-ce pas ? Beaucoup de chose en Ethereum paraisse compliquées quand on en entend parler, et la meilleure façon de le comprendre et de faire une implémentation soi-même.

Keep in mind that this is only a minimal implementation. There are extra features we may want to add to our implementation, such as some extra checks to make sure users don't accidentally transfer their zombies to address `0` (which is called "burning" a token — basically it's sent to an address that no one has the private key of, essentially making it unrecoverable). Or to put some basic auction logic in the DApp itself. (Can you think of some ways we could implement that?)
Garder en tête que c'était une implémentation minimale. Ils y a d'autres fonctionnalités que nous voudrions ajouter à notre implémentation, comme s'assurer que que les utilisateurs ne transfèrent pas accidentellement leurs zombies à l'adresse `0` (on appelle ça brûler un token - l'envoyer à une adresse dont personne n'a la clé privée, le rendant irrécupérable). Ou rajouter une logique d'enchère sur notre DApp. (Est-ce que vous voyez une façon de faire ça ?)

But we wanted to keep this lesson manageable, so we went with the most basic implementation. If you want to see an example of a more in-depth implementation, you can take a look at the OpenZeppelin ERC721 contract after this tutorial.
Mais nous voulons garder cette leçon simple, nous avons opté pour l'implémentation la plus basique. Si vous voulez voir un exemple d'une implémentation plus détaillée, vous pouvez regarder le contrat ERC721 d'OpenZeppelin après ce tutoriel.

### Contract security enhancements: Overflows and Underflows
### Améliorations de la sécurité des contrats : débordements par le haut et par le bas

We're going to look at one major security feature you should be aware of when writing smart contracts: Preventing overflows and underflows.
Nous allons voir une fonctionnalité de sécurité majeure à prendre en compte quand vous écrivez des smart contracts : Prévenir les débordements.

What's an **_overflow_**?
C'est quoi un **_débordement_** ?

Let's say we have a `uint8`, which can only have 8 bits. That means the largest number we can store is binary `11111111` (or in decimal, 2^8 - 1 = 255).
Imaginez un `uint8`, qui peut seulement avoir 8 bits. Ce qui veut dire que le binaire du plus nombre que l'on peut stocker est `11111111` (ou en décimal, 2^8 -1 = 255).

Take a look at the following code. What is `number` equal to at the end?
Regardez le code suivant. A quoi est égal `number` à la fin ?

```
uint8 number = 255;
number++;
```

In this case, we've caused it to overflow — so `number` is counterintuitively now equal to `0` even though we increased it. (If you add 1 to binary `11111111`, it resets back to `00000000`, like a clock going from `23:59` to `00:00`).
Dans ce cas, nous avonz causé un débordement par le haut - `number` est contre-intuitivement égal à `0` maintenant même si on l'a augmenté. (Si vous ajouter 1 au binaire `1111111`, il repart à `00000000`, comme une horloge qui passe de `23:59` à `00:00`).

An underflow is similar, where if you subtract `1` from a `uint8` that equals `0`, it will now equal `255` (because `uint`s are unsigned, and cannot be negative).
Un débordement par le bas est similaire, si vous soustrayez `1` d'un `uint8` égal `0`, le résultat se `255` (car les `uint` sont non signés et ne peuvent pas être négatifs).

While we're not using `uint8` here, and it seems unlikely that a `uint256` will overflow when incrementing by `1` each time (2^256 is a really big number), it's still good to put protections in our contract so that our DApp never has unexpected behavior in the future.
Nous n'utilisons pas de `uint8` ici, et il paraît peut probable qu'un `uint256` débordera avec des incrémentations de `1` par `1` (2^256 est vraiment un nombre immense), c'est toujours bon de mettre de protéger notre contrat afin que notre DApp n'est pas des comportements inattendus dans le futur.

### Using SafeMath
### Utiliser SafeMath

To prevent this, OpenZeppelin has created a **_library_** called SafeMath that prevents these issues by default.
Pour prévenir cela, OpenZeppelin a créé une **_bibliothèque_** appelée SafeMath qui empêche ces problèmes.

But before we get into that... What's a library?
Mais d'abord, c'est quoi une bibliothèque ?

A **_library_** is a special type of contract in Solidity. One of the things it is useful for is to attach functions to native data types.
Une **_bibliothèque_** est un type de contrat spécial en Solidity. Une de leur fonctionnalités et que cela permet de rajouter des fonctions à un type de données natives.

For example, with the SafeMath library, we'll use the syntax `using SafeMath for uint256`. The SafeMath library has 4 functions`add`, `sub`, `mul`, and `div`. And now we can access these functions from `uint256` as follows:
Par exemple. avec la bibliothèque SafeMath, nous allons utiliser la syntaxe `using SafeMath for uint256`. La bibliothèque SafeMath à 4 fonctions`add`, `sub`, `mul`, et `div`. Et maintenant nous ponvons utiliser ses fonctions à partir d'un `uint256` en faisant :

```
using SafeMath for uint256;
Expand All @@ -431,14 +431,14 @@ uint256 b = a.add(3); // 5 + 3 = 8
uint256 c = a.mul(2); // 5 * 2 = 10
```

We'll look at what these functions do in the next chapter, but for now let's add the SafeMath library to our contract.
Nous verons ce que font ces fonctions dans le prochain chapitre, pour l'instant, nous allons ajouter la bibliothèque SafeMath à notre contrat.

## Putting it to the Test
## A votre tour

We've already included OpenZeppelin's `SafeMath` library for you in `safemath.sol`. You can take a quick peek at the code now if you want to, but we'll be looking at it in depth in the next chapter.
Nous avons déjà rajouté la bibliothèque `SafeMath` d'OpenZeppelin pour vous dans `safemath.sol`. Vous pouvez regarder le code si vous voulez, mais nous allons l'étudier en détails dans le prochain chapitre.

First let's tell our contract to use SafeMath. We'll do this in ZombieFactory, our very base contract — that way we can use it in any of the sub-contracts that inherit from this one.
Pour l'instant, nous allons faire que notre contrat utilise SafeMath. Nous allons le faire dans ZombieFactory, nous contrat de base - de cette manière nous pourrons l'utiliser dans tous les sous-contrats qui en hérite.

1. Import `safemath.sol` into `zombiefactory.sol`.
1. Importez `safemath.sol` dans `zombiefactory.sol`.

2. Add the declaration `using SafeMath for uint256;`.
2. Ajoutez la declaration `using SafeMath for uint256;`.
43 changes: 22 additions & 21 deletions fr/5/10-safemath-2.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: SafeMath Part 2
title: SafeMath partie 2
actions: ['vérifierLaRéponse', 'indice']
requireLogin: true
material:
Expand Down Expand Up @@ -28,9 +28,9 @@ material:
}
function _transfer(address _from, address _to, uint256 _tokenId) private {
// 1. Replace with SafeMath's `add`
// 1. Remplacez par `add` de SafeMath
ownerZombieCount[_to]++;
// 2. Replace with SafeMath's `sub`
// 2. Remplacez par `sub` de SafeMath
ownerZombieCount[_from]--;
zombieToOwner[_tokenId] = _to;
Transfer(_from, _to, _tokenId);
Expand Down Expand Up @@ -382,7 +382,7 @@ material:
}
---

Let's take a look at the code behind SafeMath:
Regardons le code de SafeMath :

```
library SafeMath {
Expand Down Expand Up @@ -416,19 +416,19 @@ library SafeMath {
}
```

First we have the `library` keyword — libraries are similar to `contract`s but with a few differences. For our purposes, libraries allow us to use the `using` keyword, which automatically tacks on all of the library's methods to another data type:
Tout d'abord, nous avons le mot-clé `library` (bibliothèque) - les bibliothèques sont similaires aux contrats avec quelques différences. Dans ce cas là, les bibliothèques nous permettent d'utiliser le mot-clé `using` (utiliser), qui va automatiquement rajouter toutes les méthodes de cette bibliothèque à un autre type de donnée :

```
using SafeMath for uint;
// now we can use these methods on any uint
// Nous pouvons maintenant utiliser ces méthodes pour n'importe quel uint
uint test = 2;
test = test.mul(3); // test now equals 6
test = test.add(5); // test now equals 11
test = test.mul(3); // test est maintenant égal à 6
test = test.add(5); // test est maintenant égal à 11
```

Note that the `mul` and `add` functions each require 2 arguments, but when we declare `using SafeMath for uint`, the `uint` we call the function on (`test`) is automatically passed in as the first argument.
Vous remarquerez que `mul` et `add` ont chacunes besoin de 2 arguments, mais quand on déclare `using SafeMath for uint`, le `uint` qui appelle la fonction (`test`) est automatiquement passé comme premier argument.

Let's look at the code behind `add` to see what SafeMath does:
Regardons le code de `add` pour voir ce que fait SafeMath :

```
function add(uint256 a, uint256 b) internal pure returns (uint256) {
Expand All @@ -438,32 +438,33 @@ function add(uint256 a, uint256 b) internal pure returns (uint256) {
}
```

Basically `add` just adds 2 `uint`s like `+`, but it also contains an `assert` statement to make sure the sum is greater than `a`. This protects us from overflows.
`add` ajoute simplement 2 `uint` comme `+`, mais elle contient aussi une déclaration `assert` (affirme) pour vérifier que la somme est plus grande que `a`. Cela protège nous d'un débordement.

`assert` is similar to `require`, where it will throw an error if false. The difference between `assert` and `require` is that `require` will refund the user the rest of their gas when a function fails, whereas `assert` will not. So most of the time you want to use `require` in your code; `assert` is typically used when something has gone horribly wrong with the code (like a `uint` overflow).
`assert` est pareil que `require`, et va renvoyer une erreur si ce n'est pas vérifier. La différence entre `assert` et `require` c'est que `require` va rembourser l'utilisateur du gas restant quand la fonction échoue, alors que `assert` non. La plupart du temps vous allez vouloir utiliser `require` dans votre code, `assert` est plutôt utiliser quand quelque chose a vraiment mal tourné avec le code (comme un débordement d'`uint`).

So, simply put, SafeMath's `add`, `sub`, `mul`, and `div` are functions that do the basic 4 math operations, but throw an error if an overflow or underflow occurs.
Pour résumer, `add`, `sub`, `mul`, et `div` de SafeMath sont des fonctions qui font les 4 opérateurs mathématiques basiques, et qui renvoient une erreur en cas de débordement

### Using SafeMath in our code.
### Utiliser SafeMath dans notre code

To prevent overflows and underflows, we can look for places in our code where we use `+`, `-`, `*`, or `/`, and replace them with `add`, `sub`, `mul`, `div`.
Pour prévenir les débordements, nous pouvons voir les endroits dans notre code où nous utilisons `+`, `-`, `*`, ou `/`,
et les remplacer par `add`, `sub`, `mul`, `div`.

Ex. Instead of doing:
Ex. A lieu d'écrire :

```
myUint++;
```

We would do:
On va écrire :

```
myUint = myUint.add(1);
```

## Putting it to the Test
## A votre tour

We have 2 places in `ZombieOwnership` where we used math operations. Let's swap them out with SafeMath methods.
Il y a 2 endroits dans `ZombieOwnership` où nous utilisons des opérateurs mathématiques. Nous allons les changer avec des méthodes SafeMath.

1. Replace `++` with a SafeMath method.
1. Remplacez `++` par une méthode SafeMath.

2. Replace `--` with a SafeMath method.
2. Remplacez `--` par une méthode SafeMath.
45 changes: 23 additions & 22 deletions fr/5/11-safemath-3.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: SafeMath Part 3
title: SafeMath partie 3
actions: ['vérifierLaRéponse', 'indice']
requireLogin: true
material:
Expand All @@ -15,8 +15,8 @@ material:
contract ZombieFactory is Ownable {
using SafeMath for uint256;
// 1. Declare using SafeMath32 for uint32
// 2. Declare using SafeMath16 for uint16
// 1. Déclarez using SafeMath32 for uint32
// 2. Déclarez using SafeMath16 for uint16
event NewZombie(uint zombieId, string name, uint dna);
Expand All @@ -39,11 +39,12 @@ material:
mapping (address => uint) ownerZombieCount;
function _createZombie(string _name, uint _dna) internal {
// Note: We chose not to prevent the year 2038 problem... So don't need
// worry about overflows on readyTime. Our app is screwed in 2038 anyway ;)
// Remarque : Nous avons choisi de ne pas prendre en compte le problème année 2038...
// Donc pas la peine de s’inquiéter d'un débordement de readyTime.
// Notre app est foutue en 2038 dans tous les cas ;)
uint id = zombies.push(Zombie(_name, _dna, 1, uint32(now + cooldownTime), 0, 0)) - 1;
zombieToOwner[id] = msg.sender;
// 3. Let's use SafeMath's `add` here:
// 3. Utilisons `add` de SafeMath ici :
ownerZombieCount[msg.sender]++;
NewZombie(id, _name, _dna);
}
Expand Down Expand Up @@ -462,21 +463,21 @@ material:
}
---

Great, now our ERC721 implementation is safe from overflows & underflows!
Bien, maintenant notre implémentation ERC721 est protégée des débordements !

Going back through the code we wrote in previous lessons, there's a few other places in our code that could be vulnerable to overflows or underflows.
Si nous regardons le code que nous avons déjà écrit dans les leçons précédentes, il y a d'autres endroits dans notre code qui pourrait être vulnérables de débordements.

For example, in ZombieAttack we have:
Par exemple, dans ZombieAttack nous avons :

```
myZombie.winCount++;
myZombie.level++;
enemyZombie.lossCount++;
```

We should prevent overflows here as well just to be safe. (It's a good idea in general to just use SafeMath instead of the basic math operations. Maybe in a future version of Solidity these will be implemented by default, but for now we have to take extra security precautions in our code).
Nous devrions empêcher les débordements ici par précaution. (C'est une bonne idée en général de simplement utiliser SafeMath à la place des opérateurs mathématiques de base. Peut-être que dans une future version de Solidity cela sera implémenter par défaut, mais pour l'instant nous devons nous prendre des précautions supplémentaires dans notre code.)

However we have a slight problem — `winCount` and `lossCount` are `uint16`s, and `level` is a `uint32`. So if we use SafeMath's `add` method with these as arguments, it won't actually protect us from overflow since it will convert these types to `uint256`:
Dans tous les cas, nous avons un petit problème — `winCount` et `lossCount` sont des `uint16`s, et `level` est un `uint32`. Si nous voulions utiliser la méthode `add` de SafeMath's `add` avec ces arguements, cela ne les protégerait pas d'un débordement vu qu'ils seraient converti en `uint256` :

```
function add(uint256 a, uint256 b) internal pure returns (uint256) {
Expand All @@ -485,24 +486,24 @@ function add(uint256 a, uint256 b) internal pure returns (uint256) {
return c;
}
// If we call `.add` on a `uint8`, it gets converted to a `uint256`.
// So then it won't overflow at 2^8, since 256 is a valid `uint256`.
// Si nous appelons `.add` sur un `uint8`, il est converti en `uint256`.
// Il ne débordera pas à 2^8, car 256 est un `uint256` valide.
```

This means we're going to need to implement 2 more libraries to prevent overflow/underflows with our `uint16`s and `uint32`s. We can call them `SafeMath16` and `SafeMath32`.
Cela veut dire que nous allons devoir implémenter 2 bibliothèques de plus pour empêcher les débordements de nos `uint16`s et `uint32`s. Nous pouvons les appeler `SafeMath16` et `SafeMath32`.

The code will be exactly the same as SafeMath, except all instances of `uint256` will be replaced with `uint32` or `uint16`.
Le code sera exactement le même que SafeMath, à l'exception des instances `uint256` qui seront remplacées par `uint32` ou `uint16`.

We've gone ahead and implemented that code for you — go ahead and look at `safemath.sol` to see the code.
Nous avons pris de l'avant et avons implémenté ce code pour vous — vous pouvez voir le code dans `safemath.sol`.

Now we need to implement it in ZombieFactory.
Maintenant nous devons l'implémenter dans ZombieFactory.

## Putting it to the Test
## A votre tour

Assignment:
Mission :

1. Declare that we're using `SafeMath32` for `uint32`.
1. Déclarez que nous utilisons `SafeMath32` pour les `uint32`.

2. Declare that we're using `SafeMath16` for `uint16`.
2. Déclarez que nous utilisons `SafeMath16` pour les `uint16`.

3. There's one more line of code in ZombieFactory where we should use a SafeMath method. We've left a comment to indicate where.
3. Il y a une ligne de plus dans ZombieFactory où nous devrions utiliser une méthode SafeMath. Nous avons laissé un commentaire pour indiquer où.

0 comments on commit aabd3fe

Please sign in to comment.