-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmetaCoin-v2.sol
More file actions
109 lines (93 loc) · 5.05 KB
/
metaCoin-v2.sol
File metadata and controls
109 lines (93 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* Ce contrat est une version raffinée de MetacoinNAIF
Il s'inspire notamment du contrat Coin consultable ici
http://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html
*/
/* Pour cette version nous allons notamment:
- restreindre les droits d'émission de la monnaie à une seule personne
- créer des événéments afin que des personnes extérieures puissent suivre
les modificiations du contrat
- ajouter un peu de flexibilité*/
pragma solidity ^0.4.6;
/*'pragma' indique au compileur dans quelle version de Solidity ce code est écrit */
contract metaCoinv2 {
address public minter;
/* le droit d'émission de la monnaie revient au "minter", il est identifié
par son addresse et cette adresse est publique */
mapping (address => uint) public balances;
/* Comme précédemment on définit un mapping avec les adresses et les soldes
Pour rappel, un mapping est un dictionnaire associant les adresses "address"
à des soldes "uint". Par défaut les "mapping" sont publics, i.e quiconque
peut faire une requête de lecture. Le complément "public" est généralement
ajouté pour lever l'ambuguïté "mapping (address => uint) public balances;"
On peut bien sûr préciser "private" à la place pour qu'il soit impossible
de faire des requêtes sur le mapping sauf pour le contrat lui-même
Notez que ces données restent néanmoins "visibles" sur la blockchain
Avec private on aurait : mapping (address => uint) private balances;
*/
event Sent(address from, address to, uint amount);
event Create(address from, address to, uint amount);
/*On définit les events "Sent" et "Create". L'Event est un type de fonction
prenant jusqu'à 3 paramêtres en entrée et qui permet un usage pratique du
journal de la machine virtuelle d'Ethereum. Lorsqu'un event est appelé il
entraîne le stockage des arguments qu'il contient dans le journal des
transactions. Les events permettent donc de suivre ce qui se passe dans le
contrat depuis l'extérieure
*/
modifier minterOnly {
if (msg.sender != minter)
throw;
_;
}
/* le "modifier" permet de poser des conditions à l'exécution de certaines
fonctions. Ici, "minterOnly" sera ajouté à la syntaxe des fonctions que l'on
veut réserver au "minter". Le modifier teste la condion msg.sender != minter
si le requêteur de la fonction n'est pas le minter alors l'exécution
s'interrompt, c'est le sens du "throw". S'il s'agit bien du minter alors
la fonction s'exécute. Notez le "_" underscore après le teste, il signifie
à la fonction de continuer son exécution.*/
function metaCoinv2() {
minter = msg.sender;
}
/* Cette fonction est un "constructor" elle ne reçoit rien en argument et
elle ne s'exécute qu'une seule fois à la création du contrat. En l'espèce
la variable "minter" reçoit l'adresse "msg.sender" c'est à dire l'adresse
de celui qui a déployé le contrat
En l'absence de fonction spécifique pour modifier cette variable elle est
immuable*/
function changeMinter (address _newMinter)
minterOnly
{
minter = _newMinter;
}
/* Cette fonction répond au problème du changement de Minter, l'ancien
minter peut déléguer sa fonction à l'adresse (donc à la personne) de son choix.
Le modifier minterOnly assure que lui seule puisse appeler cette fonction.*/
function createCoin(address receiver, uint amount) minterOnly {
balances[receiver] += amount;
Create(msg.sender, receiver, amount);
}
/* par la fonction createCoin, le minter et seulement lui attribue un
montant "amount" à une adresse dans la mapping "balances". Notez que ce
montant ne pas peut être négatif. Cette opération est publiée dans le journal
(le log) des transaction par l'event "Create" qui indique à tout le monde
que msg.sender (ie le minter) a attribué un montant a l'adresse receiver.*/
function send(address receiver, uint amount) {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Sent(msg.sender, receiver, amount);
}
/* La fonction send peut être appelé par tout le monde. Le test initial est
strict pour gérer les adresses qui ne sont pas sur le mapping (0 en solde).
Cette opération est publiée dans le journal des transaction par l'event
"Sent" qui indique à tout le monde que msg.sender (ie le minter) a attribué
un montant a l'adresse receiver.*/
function kill() minterOnly {
selfdestruct(minter); }
}
/* Cette dernière fonction permet de "nettoyer" la blockchain en supprimant le
contrat. Il est important de la faire figurer pour libérer de l'espace sur
la blockchain mais aussi pour supprimer un contrat buggé. En précisant une
adresse selfdestruct(address), tous les ethers stockés par le contrat y sont
envoyés. Attention si une transaction envoie des ethers à un contrat qui s'est
"selfdestruct" ces ethers seront perdus*/