Token scientifique QX ERC20 / ** * Soumis pour vérification sur Etherscan.io le 2020-12-24 * /
Pragma Solidity ^ 0.6.0;
/ **
@Dev Wrappers sur les opérations arithmétiques de Solidity avec un débordement supplémentaire
Contrôles.
Les opérations arithmétiques dans la solidité enveloppent sur débordement. Cela peut facilement en résulter
dans les bogues, car les programmeurs supposent généralement qu'un débordement soulève un
Erreur, qui est le comportement standard dans les langages de programmation de haut niveau.
SafeMath restaure cette intuition en renvoyant la transaction lorsqu'un
Opération déborde.
L'utilisation de cette bibliothèque au lieu des opérations non contrôlées élimine un tout
Classe de bugs, il est donc recommandé de l'utiliser toujours. / bibliothèque Safemath {/ *
@DEV renvoie l'ajout de deux entiers non signés, en retournant sur
débordement.
Homologue de l'opérateur + de Solidity.
Exigences:
Retour C; }
/ **
- Operator./ **
@DEV renvoie la soustraction de deux entiers non signés, revenant avec un message personnalisé sur
débordement (lorsque le résultat est négatif).
Opérateur de Solidity's - Operator.
Exigences:
Retour C; }
/ **
@DEV renvoie la multiplication de deux entiers non signés, en retournant sur
débordement.
Operator de Solidity de * .
Exigences:
uint256 c = a * b; require (c / a == b, "Safemath: multiplication de multiplication");
Retour C; }
/ **
/ Operator. Remarque: cette fonction utilise unrevert Opcode (qui laisse le gaz restant intact) pendant la solidité/ **
@DEV renvoie la division entier de deux entiers non signés. Retour avec un message personnalisé sur
Division par Zero. Le résultat est arrondi vers zéro.
Homologue de Solidity's / Operator. Remarque: cette fonction utilise un
revert Opcode (qui laisse le gaz restant intact) pendant la solidité
Utilise un opcode invalide pour revenir (consommer tous les gaz restants).
Exigences:
Retour C; }
/ **
% de Solidity. Cette fonction utilise un revert/ **
% de Solidity. Cette fonction utilise un revert// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
@DEV Utilitaires mathématiques standard manquants dans le langage de solidité. / bibliothèque math {/ *
/ **
/ **
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
@DEV recherche un array trié et renvoie le premier index qui contient
une valeur supérieure ou égale à element . Si aucun indice de ce type n'existe (c'est-à-dire tous
Les valeurs dans le tableau sont strictement inférieures à element ), la longueur du tableau est
retourné. Complexité du temps O (log n).
array devrait être trié par ordre croissant et ne contenir pas
éléments répétés. * / fonction findupperbound (Uint256 [] Array de stockage, élément Uint256) Returns de vue interne (uint256) {if (array.length == 0) {return 0; }
uint256 Low = 0; uint256 high = array.length;
tandis que (faible <high) {uint256 mid = math.Every (bas, haut);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// À ce stade, low est la limite supérieure exclusive. Nous retournerons la limite supérieure inclusive. if (Low> 0 && array [Low - 1] == élément) {return Low - 1; } else {return low; }}}
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
@Title Compters
@author Matt Condon (@shrugs)
@DEV fournit des compteurs qui ne peuvent être incrémentés ou décrémentés de l'un. Cela peut être utilisé, par exemple pour suivre le numéro
d'éléments dans une cartographie, émettant des ID ERC721 ou comptant les identifiants de demande.
Inclure avec using Counters for Counters.Counter;
Puisqu'il n'est pas possible de déborder un entier de 256 bits avec des incréments de l'un, increment peut ignorer le {SafeMath}
chèque de débordement, économisant ainsi le gaz. Cela suppose cependant une utilisation correcte, en ce que la _value sous-jacente n'est jamais
directement accessible. * / Compteurs de la bibliothèque {Utilisation de Safemath pour uint256;
struct compter {// Cette variable ne doit jamais être directement accessible par les utilisateurs de la bibliothèque: les interactions doivent être limitées à // la fonction de la bibliothèque. En ce qui concerne Solidity V0.5.2, cela ne peut pas être appliqué, bien qu'il existe une proposition d'ajouter // cette fonctionnalité: voir Ethereum / Solidity # 4637 Uint256 _value; // par défaut: 0}
Fonction Current (Counter Storage Counter) View Interne Returns (UInt256) {return compter._value; }
Fonction Incrément (compteur de stockage Counter) interne {// Le chèque de débordement {SafeMath} peut être ignoré ici, voir le commentaire au compteur supérieur._value + = 1; }
fonction décrémente (compteur de stockage Counter) interne {compter._value = compter._value.sub (1); }}
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ *
@DEV fournit des informations sur le contexte d'exécution actuel, y compris le
expéditeur de la transaction et de ses données. Bien que ceux-ci soient généralement disponibles
via msg.sender et msg.data, ils ne devraient pas être accessibles dans un tel
manière, depuis lorsque vous traitez avec les méta-transactions GSN, l'envoi du compte et
Le paiement de l'exécution peut ne pas être l'expéditeur réel (en ce qui concerne une demande
est concerné).
Ce contrat n'est requis que pour les contrats intermédiaires de type bibliothèque. * / Résumé Contexte du contrat {fonction _msgSender () View interne Retours virtuels (adresse à payer) {return msg.Sender; }
fonction _msgData () visual interne returns virtuel (mémoire bytes) {this; // Avertissement de mutabilité de l'état de silence sans générer de bytecode - voir Ethereum / Solidity # 2691 RETOUR MSG.DATA; }}
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
Interface @DEV de la norme ERC20 telle que définie dans l'EIP. / interface ierc20 {/ *
/ **
account . * / Fonction Balance (compte d'adresse) Renvoie de la vue externe (Uint256);/ **
amount du compte de l'appelant au recipient ./ **
spender seraowner par le biais de {transfrom}. C'est/ **
amount comme allocation de spender sur les jetons de l'appelant./ **
amount de sender vers recipient à l'aide duamount est ensuite déduit de l'appelant/ **
value sont déplacés d'un compte ( from ) àto ).value peut être nulle. * / Transfert d'événements (adresse indexée à partir de l'adresse indexée sur, valeur uint256);/ **
spender pour un owner est définie parvalue est la nouvelle allocation. * / approbation de l'événement (propriétaire indexé sur l'adresse, SPENDER INDEPTÉ ADRESSE, valeur UInt256); }// Licence partielle: MIT
Pragma Solidity ^ 0.6.2;
/ **
@dev Collection de fonctions liées à l'adresse d'adresse / adresse de la bibliothèque {/ *
@DEV renvoie True si account est un contrat.
[IMPORTANT]
====
Il est dangereux de supposer qu'une adresse pour laquelle cette fonction revient
False est un compte appartenant à l'extérieur (EOA) et non un contrat.
Entre autres, isContract reviendra faux pour ce qui suit
Types d'adresses:
==== * / Fonction isContract (compte d'adresse) Returns de vue interne (bool) {// Cette méthode repose dans Extcodesize, qui renvoie 0 pour les contrats dans // construction, car le code n'est stocké qu'à la fin de l'exécution // du constructeur.
Taille Uint256; // solhint-disable-next-line no inline-assembly assembly {size: = extcodeesize (compte)} return size> 0; }
/ **
Remplacement de @DEV pour transfer de Solidity: envoie amount de wei à
recipient , transférer tous les gaz disponibles et revenir sur les erreurs.
https://eips.ethereum.org/eips/eip-1884@eip1884] augmente le coût du gaz
de certains opcodes, éventuellement des contrats dépassent la limite de gaz 2300
imposé par transfer , ce qui les rend incapables de recevoir des fonds via
transfer . {SendValue} supprime cette limitation.
https://dilience.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/orthylet plus].
Important: parce que le contrôle est transféré au recipient , les soins doivent être
pris pour ne pas créer de vulnérabilités de réentrance. Envisager d'utiliser
{Reentricancyguard} ou le
https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern fichiers-effets-interactions modèle]. * / fonction SendValue (Adresse bénéficiaire payable, montant UInt256) interne {require (adresse (this) .Balance> = montant, "Adresse: équilibre insuffisant");
// solhint-disable-next-line éviter-low-level-calls, éviter-call-valeur (bool succès,) = destinataire.Call {value: montant} (""); exiger (succès, "adresse: incapable d'envoyer de la valeur, le destinataire peut être revenu"); }
/ **
call de faible niveau. UNcall simple est un remplacement dangereux pour un appel de fonction: utilisez-letarget revient avec une raison de retour, il est bouillonnant par cetarget doit être un contrat.target avec data ne doit pas revenir./ **
functionCall ], mais avecerrorMessage en tant que secours reverser la raison lorsque target revient./ **
functionCall ],value WEI à target .value .payable ./ **
functionCallWithValue ], maiserrorMessage en tant que repli, réintégrant la raison lorsque target revient.Fonction _FunctionCallWithValue (cible d'adresse, données de mémoire des octets, Uint256 Weivale, String Memory ErrorMessage) Renvoie privé (mémoire Bytes) {require (isContract (cible), "Address: Call to Non-Contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}}
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
@DEV Implémentation de l'interface {IERC20}.
Cette implémentation est agnostique à la façon dont les jetons sont créés. Cela signifie
qu'un mécanisme d'approvisionnement doit être ajouté dans un contrat dérivé en utilisant {_mint}.
Pour un mécanisme générique, voir {ERC20PresetMinterpauser}.
Astuce: pour un article détaillé, voir notre guide
https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226 n'importe comment
pour mettre en œuvre des mécanismes d'approvisionnement].
Nous avons suivi les directives générales d'Openzeppelin: les fonctions reviennent à la place
de retourner false en échec. Ce comportement est néanmoins conventionnel
et n'entre pas en conflit avec les attentes des demandes ERC20.
De plus, un événement {approbation} est émis sur les appels à {transferfrom}.
Cela permet aux applications de reconstruire l'allocation pour tous les comptes
en écoutant lesdits événements. D'autres implémentations de l'EIP peuvent ne pas émettre
Ces événements, car il n'est pas nécessaire par la spécification.
Enfin, le {de diminution} et le {augmentation} et {augmentation}
Des fonctions ont été ajoutées pour atténuer les problèmes bien connus autour du réglage
allocations. Voir {iERC20-Approve}. * / Contrat ERC20 est un contexte, iERC20 {Utilisation de Safemath pour uint256; Utilisation d'adresse pour l'adresse;
mappage (adresse => uint256) _balances privées;
mappage (adresse => mappage (adresse => uint256)) privé _allowances;
uint256 privé _TotalSupply;
String privé _name; chaîne privée _Symbol; uint8 privé _decimals;
/ **
/ **
/ **
/ **
decimals sont égales 2 , un équilibre de 505 jetons devrait5,05 ( 505 / 10 ** 2 )./ **
/ **
/ **
recipient ne peut pas être l'adresse zéro.amount . * / Transfert de fonction (destinataire de l'adresse, montant uint256) Returns de remplacement virtuel public (bool) {_transfer (_msgSender (), destinataire, montant); Retour Vrai; }/ **
/ **
spender ne peut pas être l'adresse zéro. * / Fonction Approuve (Address Spender, Uint256 montant) Returns de remplacement virtuel public (bool) {_approve (_msgSender (), Spender, Montant); Retour Vrai; }/ **
sender et recipient ne peuvent pas être l'adresse zéro.sender doit avoir un solde d'au moins amount .sender d'au moinsamount . * / Fonction TransferFrom (expéditeur d'adresse, destinataire d'adresse, montant uint256) return de remplacement virtuel public (bool) {_transfer (expéditeur, destinataire, montant); _Approve (expéditeur, _msgSender (), _allowances [Sender] [_ msgSender ()]. sub (montant, "ERC20: le montant de transfert dépasse l'allocation")); Retour Vrai; }/ **
spender par l'appelant.spender ne peut pas être l'adresse zéro. * / fonction augmentallowance (adresse Spender, uint256 ajoutévalue) Returns virtuels publics (bool) {_approve (_msgSender (), Spender, _allowances [_msgSender ()] [Spender] .Add (ajouterValue)); Retour Vrai; }/ **
spender par l'appelant.spender ne peut pas être l'adresse zéro.spender doit avoir une allocation pour l'appelant d'au moinssubtractedValue . * / Fonction DimingEAllowance (Address Spender, Uint256 SoustratedValue) Returns virtuels publics (bool) {_approve (_msGsender (), Spender, _allowances [_MSGSender ()] [Spender] .Sub (soustraire Retour Vrai; }/ **
@Dev déplace amount des jetons de sender au recipient .
Cette fonction interne est équivalente à {transfert} et peut être utilisée pour
Par exemple, mettre en œuvre des frais de jeton automatique, des mécanismes de frappe, etc.
Émet un événement {transfert}.
Exigences:
sender ne peut pas être l'adresse zéro.recipient ne peut pas être l'adresse zéro.sender doit avoir un solde d'au moins amount . * / Fonction _Transfer (Sender d'adresse, destinataire d'adresse, montant Uint256) virtuel interne {require (Sender! = Adresse (0), "ERC20: transfert de l'adresse zéro"); requis (destinataire! = adresse (0), "ERC20: transfert vers l'adresse zéro");_BeforEtOrKentransfer (expéditeur, destinataire, montant);
_Balances [Sender] = _Balances [Sender] .Sub (montant, "ERC20: le montant du transfert dépasse le solde"); _Balances [receveur] = _Balances [receveur] .add (montant); EMIT Transfer (expéditeur, destinataire, montant); }
/ ** @dev crée des tokens amount et les attribue à account , en augmentant
l'offre totale.
Émet un événement {transfert} avec from définition à l'adresse zéro.
Exigences
to ne peut pas être l'adresse zéro. * / fonction _mint (compte d'adresse, montant uint256) virtuel interne {require (compte! = adresse (0), "ERC20: menthe à l'adresse zéro");_BeForEtOrSOntRanSfer (adresse (0), compte, montant);
_TotalSupply = _TotalSupply.add (montant); _Balances [compte] = _Balances [compte] .add (montant); émettez le transfert (adresse (0), compte, montant); }
/ **
@DEV détruit amount des jetons du account , réduisant le
Approvisionnement total.
Émet un événement {transfert} avec to régler à l'adresse zéro.
Exigences
account ne peut pas être l'adresse zéro.account doit avoir au moins amount de jetons. * / fonction _burn (compte d'adresse, montant uint256) virtuel interne {require (compte! = adresse (0), "ERC20: brûler à partir de l'adresse zéro");_BeForEtOrSentRansfer (compte, adresse (0), montant);
_Balances [Compte] = _Balances [compte] .sub (montant, "ERC20: le montant de la brûlure dépasse le solde"); _TotalSupply = _TotalSupply.sub (montant); émettez le transfert (compte, adresse (0), montant); }
/ **
@DEV fixe amount comme allocation de spender sur les jetons du owner .
Cette fonction interne est équivalente à approve et peut être utilisée pour
Par exemple, définir des allocations automatiques pour certains sous-systèmes, etc.
Émet un événement {approbation}.
Exigences:
owner ne peut pas être l'adresse zéro.spender ne peut pas être l'adresse zéro. * / Fonction _Approve (propriétaire d'adresse, Spender de l'adresse, montant Uint256) Virtual interne {require (propriétaire! = adresse (0), "ERC20: Approuver de l'adresse zéro"); require (SPENDER! = Adresse (0), "ERC20: Approuver à l'adresse zéro");_allowances [propriétaire] [SPENDER] = Montant; émettre l'approbation (propriétaire, dépensier, montant); }
/ **
/ **
from et to être tous les deux non nuls, amount de fromto .from zéro, les tokens amount seront frappés to .to zéro, amount de jetons from «s sera brûlée.from et to ne jamais être à la fois zéro.// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
@DEV Ce contrat étend un jeton ERC20 avec un mécanisme instantané. Lorsqu'un instantané est créé, les soldes et
L'approvisionnement total à l'époque est enregistré pour un accès ultérieur.
Cela peut être utilisé pour créer des mécanismes en toute sécurité basés sur des soldes de jetons tels que des dividendes sans confiance ou un vote pondéré.
Dans les implémentations naïves, il est possible d'effectuer une attaque de "double dépense" en réutilisant le même équilibre de différent
comptes. En utilisant des instantanés pour calculer les dividendes ou le pouvoir de vote, ces attaques ne s'appliquent plus. Il peut aussi être
Utilisé pour créer un mécanisme de fourniture ERC20 efficace.
Les instantanés sont créés par la fonction interne {_snapshot}, qui émettra l'événement {snapshot} et renverra un
ID instantané. Pour obtenir l'alimentation totale au moment d'un instantané, appelez la fonction {totalSupplyat} avec l'instantané
identifiant. Pour obtenir le solde d'un compte au moment d'un instantané, appelez la fonction {BalanceOfat} avec l'ID instantané
et l'adresse du compte.
==== Coûts de gaz
Les instantanés sont efficaces. La création d'instantané est O (1) . La récupération des soldes ou de l'approvisionnement total d'un instantané est _O (journal
n) _ dans le nombre d'instantanés qui ont été créés, bien que n pour un compte spécifique sera généralement beaucoup
Plus petit car les soldes identiques dans les instantanés suivants sont stockés en une seule entrée.
Il y a une surcharge constante pour les transferts ERC20 normaux en raison de la comptabilité supplémentaire. Ce frais généraux est
Seulement significatif pour le premier transfert qui suit immédiatement un instantané pour un compte particulier. Ultérieur
Les transferts auront un coût normal jusqu'au prochain instantané, etc. * / Résumé Contrat ERC20SNAPSHOT est ERC20 {// inspiré par MinmeMetoken de Jordi Baylina pour enregistrer les soldes historiques: // https://github.com/giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/CONRTST
Utilisation de Safemath pour UInt256; Utilisation des tableaux pour Uint256 []; Utilisation de compteurs pour compteurs.Counter;
// Les valeurs instantanées ont des tableaux d'ID et la valeur correspondant à cet ID. Celles-ci pourraient être un tableau de structure A // Snapshot, mais cela entraverait l'utilisation de fonctions qui fonctionnent sur un tableau. struct snapshots {uint256 [] ids; uint256 [] valeurs; }
mappage (adresse => instantanés) privé _AccountBalancesNapshots; Instantanés privé _TOTALSUPPLYSNAPSHOTS;
// Les ID d'instantané augmentent de façon monotone, la première valeur étant 1. Un ID de 0 n'est pas valide. Compteurs.counter privé _currentSnapShotid;
/ **
id est créé. * / instantané de l'événement (UInt256 ID);/ **
@Dev crée un nouveau instantané et renvoie son ID de instantané.
Émet un événement {snapshot} qui contient le même ID.
{_snapshot} est internal et vous devez décider comment l'exposer à l'extérieur. Son utilisation peut être limitée à un
Ensemble de comptes, par exemple en utilisant {AccessControl}, ou il peut être ouvert au public.
[AVERTISSEMENT]
====
Tandis qu'un moyen ouvert d'appeler {_snapshot} est requis pour certains mécanismes de minimisation de la confiance tels que la forking,
Vous devez considérer qu'il peut potentiellement être utilisé par les attaquants de deux manières.
Premièrement, il peut être utilisé pour augmenter le coût de la récupération des valeurs des instantanés, bien qu'il augmentera
logarithmiquement rendant ainsi cette attaque inefficace à long terme. Deuxièmement, il peut être utilisé pour cibler
comptes spécifiques et augmenter le coût des transferts ERC20 pour eux, de la manière spécifiée des coûts de gaz
Section ci-dessus.
Nous n'avons pas mesuré les nombres réels; Si c'est quelque chose qui vous intéresse, veuillez nous contacter.
==== * / fonction _snapshot () Renvoie virtuel interne (uint256) {_currentSnapshotid.increment ();
uint256 currentId = _currentNapshotid.current (); émettre un instantané (currentId); return currentId; }
/ **
@Dev récupère le solde du account au moment où snapshotId ont été créés. * / Fonction BalanceOfat (compte d'adresse, Uint256 Snapshotid) View Public Returns (UInt256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _AccountBalancesNapshots [compte]);
retourner instantanément? Valeur: Balance (compte); }
/ **
@Dev récupère l'alimentation totale au moment où snapshotId ont été créés. * / fonction totalSUpplyat (uint256 snapshotid) public View returns (uint256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _totalSupplySnapshots);
retourner instantanément? Valeur: totalSupply (); }
// Mettre à jour le solde et / ou les instantanés d'alimentation totale avant que les valeurs ne soient modifiées. Ceci est implémenté // dans le crochet _BeforEtOlTransfer, qui est exécuté pour les opérations _mint, _burn et _transfer. fonction _BeforEtOrSentRansfer (adresse de, adresse à, uint256 montant) Override virtuel interne {super._beforEtOrtRansfer (de, à, montant);
if (de == adresse (0)) {// menthe _upDateAccountsNapshot (to); _upDateTotalSupplySnapShot (); } else if (to == adresse (0)) {// burn _upDateAccountsNapShot (from); _upDateTotalSupplySnapShot (); } else {// transfert _upDateAccountSnapShot (from); _upDateAccountsNapshot (à); }}
fonction _valueat (uint256 snapshotid, instantanés instantanés) return de vue privée (bool, uint256) {require (snapshotid> 0, "eRC20Snapshot: id est 0"); // solhint-disable-next-line max-line-longueur require (snapshotid <= _currentNapshotid.current (), "eRC20Snapshot: ID non existant");
// When a valid snapshot is queried, there are three possibilities:
// a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
// created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
// to this id is the current one.
// b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
// requested id, and its value is the one to return.
// c) More snapshots were created after the requested one, and the queried value was later modified. There will be
// no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
// larger than the requested one.
//
// In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
// it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
// exactly this.
uint256 index = snapshots.ids.findUpperBound(snapshotId);
if (index == snapshots.ids.length) {
return (false, 0);
} else {
return (true, snapshots.values[index]);
}
}
fonction _upDateAccountsNapShot (Adresse compte) private {_updatesNapshot (_AccountBalancesNapshots [compte], Balance (compte)); }
fonction _upDateTotalSupplySnapShot () private {_updatesNapshot (_TotalSupplySnapshots, totalSupply ()); }
fonction _updatesNapshot (instantanés instantanés, uint256 currentValue) private {uint256 currentId = _currentNapshotid.current (); if (_lastsnapshotid (snapshots.ids) <curvedId) {snapshots.ids.push (currentId); snapshots.values.push (currentValue); }}
fonction _LastSnapShotid (uint256 [] IDS de stockage) Returns de vue privée (uint256) {if (ids.length == 0) {return 0; } else {return ids [ids.length - 1]; }}}
// Licence partielle: MIT
Pragma Solidity ^ 0.6.0;
/ **
bibliothèque @dev pour gérer
https://en.wikipedia.org/wiki/Set_(ABSTRATT_DATA_TYPE)FETS] de primitif
types.
Les ensembles ont les propriétés suivantes:
(O (1)).
Exemple de contrat {
// Add the library methods
using EnumerableSet for EnumerableSet.AddressSet;
// Declare a set state variable
EnumerableSet.AddressSet private mySet;
}
À partir de la v3.0.0, uniquement des ensembles d' address de type ( AddressSet ) et uint256
( UintSet ) sont pris en charge. * / bibliothèque enummerableSet {// Pour implémenter cette bibliothèque pour plusieurs types avec le plus petit code // possible que possible, nous l'écrivons en termes de type de jeu générique avec // valeurs Bytes32. // L'implémentation SET utilise des fonctions privées, et les implémentations orientées utilisateur (telles que AddressSet) ne sont que des emballages autour de l'ensemble // sous-jacent. // Cela signifie que nous ne pouvons créer de nouveaux Enumerablesset pour les types qui s'adaptent // dans Bytes32.
struct set {// stockage des valeurs set bytes32 [] _Values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/ **
/ **
@DEV supprime une valeur d'un ensemble. O (1).
Renvoie vrai si la valeur était supprimée de l'ensemble, c'est-à-dire si elle était
présent. * / Fonction _Remove (set Storage Set, bytes32 Value) private returns (bool) {// nous lisons et stockons l'index de la valeur pour empêcher plusieurs lectures de la même machine de stockage uint256 valueIndex = set._indexes [valeur];
if (valueIndex! = 0) {// équivalent à contient (set, value) // Pour supprimer un élément du tableau _values dans o (1), nous échangeons l'élément pour supprimer avec le dernier dans // le tableau, puis supprimons le dernier élément (parfois appelé `` échanger et pop ''). // Cela modifie l'ordre du tableau, comme indiqué dans {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {return false; }}
/ **
/ **
/ **
index de position dans l'ensemble. O (1).index must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; }// AddressSet
struct AddressSet { Set _inner; }
/**
/**
/**
/**
/**
index in the set. O(1).index must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); }// UintSet
struct UintSet { Set _inner; }
/**
/**
/**
/**
/**
index in the set. O(1).index must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); }}// Partial License: MIT
pragma solidity ^0.6.0;
/**
@dev Contract module that allows children to implement role-based access
control mechanisms.
Roles are referred to by their bytes32 identifier. These should be exposed
in the external API and be unique. The best way to achieve this is by
using public constant hash digests:
bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
Roles can be used to represent a set of permissions. To restrict access to a
function call, use {hasRole}:
function foo() public {
require(hasRole(MY_ROLE, msg.sender));
...
}
Roles can be granted and revoked dynamically via the {grantRole} and
{revokeRole} functions. Each role has an associated admin role, and only
accounts that have a role's admin role can call {grantRole} and {revokeRole}.
By default, the admin role for all roles is DEFAULT_ADMIN_ROLE , which means
that only accounts with this role will be able to grant or revoke other
roles. More complex role relationships can be created by using
{_setRoleAdmin}.
WARNING: The DEFAULT_ADMIN_ROLE is also its own admin: it has permission to
grant and revoke this role. Extra precautions should be taken to secure
accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address;
struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; }
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
newAdminRole is set as role 's admin role, replacing previousAdminRoleDEFAULT_ADMIN_ROLE is the starting admin for all roles, despite/**
account is granted role .sender is the account that originated the contract call, an admin role/**
account is revoked role .sender is the account that originated the contract call:revokeRole , it is the admin role bearerrenounceRole , it is the role bearer (ie account ) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);/**
true if account has been granted role . */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); }/**
role . Peut être utilisé/**
role . index must be a/**
role . See {grantRole} and/**
@dev Grants role to account .
If account had not been already granted role , emits a {RoleGranted}
événement.
Exigences:
role 's admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");_grantRole(role, account); }
/**
@dev Revokes role from account .
If account had been granted role , emits a {RoleRevoked} event.
Exigences:
role 's admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");_revokeRole(role, account); }
/**
@dev Revokes role from the calling account.
Roles are often managed via {grantRole} and {revokeRole}: this function's
purpose is to provide a mechanism for accounts to lose their privileges
if they are compromised (such as when a trusted device is misplaced).
If the calling account had been granted role , emits a {RoleRevoked}
événement.
Exigences:
account . */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self");_revokeRole(role, account); }
/**
role to account .account had not been already granted role , emits a {RoleGranted}/**
adminRole as role 's admin role.function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); }}
function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); }}}
pragma solidity 0.6.8;
contract QXToken is Context, AccessControl, ERC20Snapshot { bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");
constructor(uint256 amount, uint8 decimals) ERC20("QX ERC20", "QX") public {
_setupDecimals(decimals);
_mint(msg.sender, amount);
// set up required roles
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(SNAPSHOT_ROLE, _msgSender());
}
/**
* @dev Creates a new snapshot and returns its snapshot id.
* Emits a {Snapshot} event that contains the same id.
*/
function snapshot() public {
require(hasRole(SNAPSHOT_ROLE, _msgSender()), "Must have snapshot role to create a snapshot");
_snapshot();
}
}