Comment calcule-t-on un solde à partir de transactions ?
Un registre garde la liste des opérations, pas les soldes. Pour connaître le solde de chacun, on rejoue les opérations depuis le début, dans l’ordre.
Cette méthode permet de refuser un paiement plus grand que ce que l’on possède. C’est la parade contre la double dépense.
À la fin de cette leçon
Remarque
Je peux calculer des soldes à partir d’une liste de transactions et refuser un paiement trop grand.
Mots-clés
| Mot | Ce que ça veut dire |
|---|---|
| Registre | la liste, dans l’ordre, de toutes les opérations enregistrées |
| Transaction | un paiement : qui paie, qui reçoit, quel montant |
| Solde | ce que possède quelqu’un à un moment donné, calculé et non stocké |
| Double dépense | dépenser deux fois la même somme |
| Refusée | une transaction que le registre n’accepte pas, car le solde est trop bas |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un solde se calcule en rejouant les transactions
Pensez à un relevé de compte : chaque ligne est un mouvement. Le solde est la somme des lignes depuis l’ouverture.
Dans un registre, personne ne note « Camille possède 8 € ». On note les paiements. Pour connaître le solde, on part des montants de départ et on applique chaque paiement, un par un.
Exemple travaillé : un paiement refusé
| Ordre | Paiement | Camille | Hugo | Léa | Décision |
|---|---|---|---|---|---|
| Départ | 20 | 5 | 0 | ||
| 1 | Camille paie Hugo 12 | 8 | 17 | 0 | Acceptée |
| 2 | Camille paie Léa 9 | 8 | 17 | 0 | Refusée : Camille n’a que 8 |
| 3 | Hugo paie Léa 10 | 8 | 7 | 10 | Acceptée |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La double dépense : deux fois la même somme
Camille a 20. Elle tente de payer 12 à Hugo et 9 à Léa dans la même minute. Si le registre acceptait les deux, elle aurait dépensé 21 avec 20.
Le registre les range dans un ordre et applique la règle : un paiement plus grand que le solde est refusé. Le deuxième saute.
Rejouer des paiements, sans le contrôle
depart = {"Camille": 20, "Hugo": 5}
paiements = [
{"de": "Camille", "vers": "Hugo", "montant": 12},
{"de": "Camille", "vers": "Lea", "montant": 9},
]
soldes = {}
for nom in depart:
soldes[nom] = depart[nom]
for p in paiements:
# Ici rien ne vérifie le solde : ajoutez un if pour refuser un paiement trop grand
soldes[p["de"]] = soldes[p["de"]] - p["montant"]
if p["vers"] not in soldes:
soldes[p["vers"]] = 0
soldes[p["vers"]] = soldes[p["vers"]] + p["montant"]
print(soldes)
Sans contrôle, un solde devient négatif
Le programme affiche {'Camille': -1, 'Hugo': 17, 'Lea': 9}. Camille a dépensé 21 avec 20 : son solde est négatif, ce qui est impossible.
Ajoutez un if avant la ligne qui retire le montant. Si le solde est trop petit, mettez le paiement de côté et passez au suivant.
L’ordre décide de la transaction refusée
Si l’ordre est inversé, c’est l’autre paiement qui passe. Camille paie d’abord 9 à Léa : accepté, il lui reste 11. Puis 12 à Hugo : refusé.
Le résultat dépend donc de l’ordre. Tous les participants doivent s’accorder sur le même ordre : c’est tout le sujet du consensus, dans deux leçons.
Le labo rejoue quatre paiements
Le script balances.py du labo part de trois soldes et rejoue quatre paiements. Attention : il écrit des mots anglais, comme « balances » (les soldes) et « refused » (refusé).
Observez les soldes à la fin et le paiement qui a sauté. Ses chiffres sont ceux du labo, pas ceux de notre tableau.
Rejouer les paiements du labo
docker exec jupyter python3 steps/balances.pyAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Erreur fréquente
Attention
On croit qu’une chaîne valide ne contient que des paiements permis. C’est faux : la chaîne dit seulement que rien n’a été modifié depuis. Savoir si un paiement est permis demande un autre contrôle, celui du registre : le solde est-il suffisant ?