QX ERC20 Science Token /** *Eingereicht zur Überprüfung bei Ethercan.io am 2020-12-24 * /
Pragma Solidität ^0,6,0;
/**
@dev Wrapper über die arithmetischen Operationen von Solidity mit zusätzlichem Überlauf
Überprüfungen.
Arithmetische Operationen in Soliditätswrap am Überlauf. Dies kann leicht entstehen
In Bugs gehen Programmierer normalerweise an, dass ein Überlauf einen erhöht
Fehler, das das Standardverhalten in Programmiersprachen auf hoher Ebene ist.
SafeMath stellt diese Intuition wieder her, indem es die Transaktion zurückkehrt, wenn a
Operation überläuft.
Die Verwendung dieser Bibliothek anstelle der nicht überprüften Operationen beseitigt eine Ganze
Fehlerklasse, daher wird empfohlen, es immer zu verwenden. / Bibliothek Safemath { / *
@dev gibt die Hinzufügung von zwei nicht signierten Ganzzahlen zurück, die auf zurückkehren
Überlauf.
Gegenstück zum + Operator von Solidity.
Anforderungen:
Rückkehr C; }
/**
- ./**
@dev gibt die Subtraktion von zwei nicht signierten Ganzzahlen zurück, wobei die benutzerdefinierte Nachricht auf zurückkehrt
Überlauf (wenn das Ergebnis negativ ist).
Gegenstück zum - .
Anforderungen:
Rückkehr C; }
/**
@Dev gibt die Multiplikation von zwei nicht signierten Ganzzahlen zurück und kehrt auf
Überlauf.
Gegenstück zum * Operator von Solidity.
Anforderungen:
uint256 c = a * b; erfordern (c / a == b, "Safemath: Multiplikationsüberlauf");
Rückkehr C; }
/**
/ Operator. Hinweis: Diese Funktion verwendet arevert/**
@dev gibt die Ganzzahlabteilung von zwei nicht signierten Ganzzahlen zurück. Kehrt mit einer benutzerdefinierten Nachricht auf zurück auf
Division von Null. Das Ergebnis ist auf Null abgerundet.
Gegenstück zur Solidität / Operator. Hinweis: Diese Funktion verwendet a
Opcode (wodurch das verbleibende Gas unberührt bleibt) während der Solidität revert
Verwendet ein ungültiges Opcode, um zurückzukehren (Verbrauch aller verbleibenden Gas).
Anforderungen:
Rückkehr C; }
/**
% Operator. Diese Funktion verwendet einen revert/**
% Operator. Diese Funktion verwendet einen revert// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@dev Standard Math -Dienstprogramme fehlen in der Soliditätssprache. / Library Math { / *
/**
/**
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@dev sucht ein sortiertes array und gibt den ersten Index zurück, der enthält
ein Wert größer oder gleich element . Wenn kein solcher Index existiert (dh alle
Die Werte im Array sind streng geringer als element ), die Arraylänge ist
zurückgekehrt. Zeitkomplexität O (log n).
Es wird erwartet, dass array in aufsteigender Reihenfolge sortiert wird und keine enthalten
wiederholte Elemente. */ Funktion findupperBound (uint256 [] Speicherarray, Uint256 -Element) Interne Ansicht returns (uint256) {if (array.length == 0) {return 0; }
uint256 niedrig = 0; Uint256 High = Array.length;
while (niedrig <hoch) {uint256 Mid = Math. Durchschnitt (niedrig, hoch);
// 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;
}
}
// zu diesem Zeitpunkt low ist die exklusive Obergrenze. Wir werden die inklusive Obergrenze zurückgeben. if (niedrig> 0 && array [niedrig - 1] == element) {return niedrig - 1; } else {return low; }}}
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@title conters
@Author Matt Condon (@Shrugs)
@DEV stellt Zähler bereit, die nur durch eins inkrementiert oder verringert werden können. Dies kann verwendet werden, um die Nummer zu verfolgen
von Elementen in einer Zuordnung, der Ausgabe von ERC721 -IDs oder Zählen von Anforderungs -IDs.
Mit using Counters for Counters.Counter;
Da es nicht möglich ist, eine 256 -Bit -Ganzzahl mit Schritten von einem zu überfließen, kann increment die {Safemath} überspringen
Überlaufprüfung und dadurch Gas sparen. Dies geht davon _value
direkt aufgerufen. */ Bibliothekszähler {Verwenden von Safemath für uint256;
Struct counter {// Auf diese Variable sollte niemals von Benutzern der Bibliothek direkt zugegriffen werden: Interaktionen müssen auf // der Funktion der Bibliothek beschränkt werden. Nach Solidität V0.5.2 kann dies nicht erzwungen werden, obwohl ein Vorschlag hinzugefügt wird // diese Funktion: Siehe Ethereum/Solidity#4637 UINT256 _VALUE; // Standard: 0}
Funktionsstrom (Zählerspeicherzähler) Interne Ansicht Rücksende (uint256) {return counter._Value; }
Funktionsinkrement (Zählerspeicherschalter) interne {// Die Überlaufprüfung {Safemath} kann hier übersprungen werden. Siehe Kommentar am oberen Zähler._Value += 1; }
Funktionsdekrement (Zählerspeicher Zähler) interne {counter._value = counter._value.sub (1); }}
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/*
@dev liefert Informationen zum aktuellen Ausführungskontext, einschließlich der
Absender der Transaktion und ihrer Daten. Während diese im Allgemeinen verfügbar sind
Über MSG.Sender und msg.data sollten sie nicht in einem so direkten Zugriff auf sie zugreifen
Art, da im Umgang mit GSN-Meta-Übersetzungen das Konto sendet und
Die Bezahlung für die Ausführung ist möglicherweise nicht der tatsächliche Absender (bis zu einer Bewerbung
ist besorgt).
Dieser Vertrag ist nur für mittlere, bibliotheksähnliche Verträge erforderlich. */ Abstract Contract Context {function _msgSender () interne Ansicht virtuelle Rückgaben (Adresse zu zahlen) {return msg.sender; }
Funktion _msgdata () interne Ansicht Virtuelle Rückgabe (Bytes -Speicher) {this; // Schweigenstaat Mutability Warning ohne Bytecode - siehe Ethereum/Solidity#2691 Return msg.data; }}
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@Dev Schnittstelle des ERC20 -Standards gemäß dem im EIP definierten EIP. / Schnittstelle ierc20 { / *
/**
account sind. */ Funktionsaldo (Adresskonto) externe Ansicht Rückgaben (uint256);/**
amount Token aus dem Konto des Anrufers zum recipient ./**
spender sein wirdowner über {Transfer von} ausgeben. Das ist/**
amount als Zulage des spender über die Token des Anrufers./**
amount Token vom sender zum recipient mit dem Empfängeramount wird dann vom Anrufer abgezogen/**
value -Token von einem Konto ( from ) auf verschoben werdento ).value Null sein kann. */ Ereignistransfer (Adresse indexiert, Adresse in indiziertem Uint256 -Wert);/**
spender für einen owner durch eingestellt istvalue ist die neue Zulage. */ Ereignisgenehmigung (Adressindefinierte Eigentümer, Adressspender, Uint256 -Wert); }// Teillizenz: MIT
Pragma -Solidität ^0,6,2;
/**
@Dev Sammlung von Funktionen, die sich auf die Adresstyp / Bibliotheksadresse beziehen { / *
@dev gibt true zurück, wenn account ein Vertrag ist.
[WICHTIG]
====
Es ist nicht sicher anzunehmen, dass eine Adresse, für die diese Funktion zurückgibt
False ist ein externes Konto (EOA) und kein Vertrag.
Unter anderem wird isContract für Folgendes falsch zurückkehren
Arten von Adressen:
===== */ function isContract (Adresskonto) Interne Ansicht rendite (bool) {// Diese Methode stützt sich in Extcodesize, das 0 für Verträge in // Konstruktion zurückgibt, da der Code nur am Ende der Ausführung // Konstruktorausführung gespeichert ist.
Uint256 Größe; // Solhint-disable-Next-Line No-Inline-Assembly-Assembly {Größe: = extcodesize (Konto)} Rückgabegröße> 0; }
/**
@Dev Ersatz für transfer von Solidität: Sendet amount Wei an an
recipient , alle verfügbaren Gas weiterleiten und Fehler zurückkehren.
https://eips.ethereum.org/eips/EIP-1884..EP1884] Erhöht die Gaskosten
von bestimmten Opcodes, die möglicherweise Verträge über das Gasgrenze von 2300 betreiben
durch transfer auferlegt, wodurch sie keine Gelder über die Empfangszahlung übertragen werden
transfer . {sendValue} entfernt diese Einschränkung.
https://diligence.consensys.net/posts/2019/09/stop-using-solidss-transfer-now/[learn mehr].
Wichtig: Da die Kontrolle an recipient übertragen wird, muss die Pflege sein
genommen, um keine Schwachstellen für Wiederherstellungen zu schaffen. Erwägen Sie zu verwenden
{Re -Uneranzguard} oder der
https://Solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-ects-interactions-pattern-pattern-pattern-Muster-/Effects-Muster]. */ Funktion SENDVALUE (Adresse zu zahlbarem Empfänger uint256) Internal {fordert (Adresse (this) .Balance> = Betrag, "Adresse: unzureichender Saldo");
// Solhint-disable-Next-Line-Line vermeiden, Level-Level-Calls, vermeiden Sie Call-value (bool Erfolg,) = Empfänger.Call {Wert: Betrag} (""); erfordern (Erfolg, "Adresse: Wert nicht in der Lage, Wert zu senden, kann der Empfänger möglicherweise zurückgekehrt sein"); }
/**
call mit niedriger Ebene durch. Acall ist ein unsicherer Ersatz für einen Funktionsaufruf: Verwenden Sie diestarget mit einem Rückkehrgrund zurückkehrt, wird dies dadurch aufgeblasentarget muss ein Vertrag sein.target mit data darf nicht zurückkehren./**
functionCall ], aber miterrorMessage als Fallback kehrt den Grund zurück, wenn target zurückkehrt./**
functionCall ],value wei auf target übertragen.value haben.payable sein./**
functionCallWithValue ], abererrorMessage als Fallback kehren Grund zurück, wenn sich target zurückversetzt.Funktion _functionCallWithValue (Adressziel, Bytes-Speicherdaten, Uint256 weivalue, String Memory ErrorMessage) private Returns (Bytes Memory) {fordert (iscontract (Ziel), "Adresse: Anrufen: Nicht-Vertragsabschluss");
// 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);
}
}
}}
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@Dev Implementierung der {ierc20} -Rinterface.
Diese Implementierung ist agnostisch für die Art und Weise, wie Token erstellt werden. Das heisst
dass ein Versorgungsmechanismus in einem abgeleiteten Vertrag mit {_mint} hinzugefügt werden muss.
Für einen generischen Mechanismus siehe {ERC20PresetMinterpause}.
Tipp: Für eine detaillierte Erstellung finden Sie in unserem Leitfaden
https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanismen
Versorgungsmechanismen implementieren].
Wir haben den allgemeinen Openzeppelin -Richtlinien gefolgt
beim Misserfolg false zurückkehren. Dieses Verhalten ist dennoch konventionell
und widerspricht nicht den Erwartungen von ERC20 -Anwendungen.
Zusätzlich wird ein Ereignis {Genehmigung} auf Anrufe an {TransferFrom} emittiert.
Auf diese Weise können Anwendungen die Zulage für alle Konten gerade rekonstruieren
durch Hören dieser Ereignisse. Andere Implementierungen des EIP werden möglicherweise nicht emittiert
Diese Ereignisse, wie dies nicht von der Spezifikation erforderlich ist.
Schließlich der Nicht-Standard {DecreasAllowance} und {ERHALTEALLOWANCE}
Funktionen wurden hinzugefügt, um die bekannten Probleme bei der Einstellung zu mildern
Zulagen. Siehe {IERC20-Arevrove}. */ Contract ERC20 ist Kontext, IERC20 {Verwenden von Safemath für uint256; Verwendung von Adresse für die Adresse;
Mapping (Adresse => uint256) private _balances;
Mapping (Adresse => Mapping (Adresse => uint256)) private _allowances;
uint256 privat _totalsupply;
String privat _name; String privat _symbol; Uint8 private _Decimals;
/**
/**
/**
/**
decimals gleich 2 sind, sollte ein Gleichgewicht von 505 Tokens5,05 ( 505 / 10 ** 2 ) angezeigt werden./**
/**
/**
recipient kann nicht die Null -Adresse sein.amount haben. */ Funktionsübertragung (Adressempfänger, uint256 Betrag) öffentliche virtuelle Überschreibungen (bool) {_transfer (_msgSender (), Empfänger, Betrag); zurückkehren; }/**
/**
spender kann nicht die Nulladresse sein. */ Funktion genehmigen (Adressspender, uint256 Betrag) öffentliche virtuelle Überschreibungen (bool) {_ Approve (_msgSender (), Spender, Betrag); zurückkehren; }/**
sender und recipient können nicht die Null -Adresse sein.sender muss einen Restbetrag von mindestens amount haben.sender berücksichtigenamount . */ function Transferfrom (Adressabsender, Adressempfänger, Uint256) öffentliche virtuelle Überschreibungen (bool) {_transfer (Absender, Empfänger, Betrag); _ APPROVE (Absender, _msgSender (), _lowances [Sender] [_ msgSender ()]. Sub (Betrag, "ERC20: Übertragungsbetrag überschreitet die Zulassung"); zurückkehren; }/**
spender gewährte Zulage.spender kann nicht die Nulladresse sein. */ Funktionserhöhung (Adressspender, Uint256 AddValue) öffentliche virtuelle Rückgaben (bool) {_ Approve (_msgsender (), Spender, _lowances [_msgSender ()] [Spender] .Add (hinzugefügt Value)); zurückkehren; }/**
spender gewährte Zulage.spender kann nicht die Nulladresse sein.spender muss den Anrufer von mindestenssubtractedValue . */ Funktionsabnahme (Adressspender, uint256 subtractedValue) öffentliche virtuelle Renditen (bool) {_ Approve (_msgSender (), Spender, _lowances [_msgSender ()] [Spender] .Sub (subtractedValue, "Erc20: Verringerte Zulassung unter Null"); zurückkehren; }/**
@dev verschiebt die amount vom sender zum recipient .
Diese interne Funktion entspricht {Transfer} und kann verwendet werden
zB implementieren automatische Token -Gebühren, Slashing -Mechanismen usw.
Emittiert ein Ereignis {Transfer}.
Anforderungen:
sender kann nicht die Null -Adresse sein.recipient kann nicht die Null -Adresse sein.sender muss einen Restbetrag von mindestens amount haben. */ function _transfer (Adressabsender, Adressempfänger, Uint256) Internal Virtual {fordert (Sender! = Adresse (0), "ERC20: Übertragung von der Nulladresse"); erfordern (Empfänger! = Adresse (0), "ERC20: Übertragung an die Nulladresse");_BeforeTokentransfer (Absender, Empfänger, Betrag);
_Balances [Sender] = _Balances [Sender] .Sub (Betrag, "ERC20: Übertragungsbetrag überschreitet den Saldo"); _Balances [Empfänger] = _Balances [Empfänger] .Add (Menge); Übertragung ausgeben (Absender, Empfänger, Betrag); }
/** @dev erstellt amount -Token und weist sie account , wobei sie erhöht werden
die Gesamtversorgung.
Emittiert ein {Transfer} -Ergnalon mit from Set bis zur Nulladresse.
Anforderungen
to die Nulladresse sein. */ function _mint (Adresskonto, Uint256) Internal Virtual {fordert (Konto! = Adresse (0), "ERC20: Mint an die Nulladresse");_BeforeTokentransfer (Adresse (0), Konto, Betrag);
_totalsupply = _totalsupply.add (Menge); _Balances [Konto] = _Balances [Konto] .Add (Betrag); Übertragung (Adresse (0), Konto, Betrag) ausgeben; }
/**
@Dev zerstört amount -Token aus account und reduziert die
Gesamtversorgung.
Emittiert ein {Transfer} -Ergstand mit to auf die Nulladresse festzulegen.
Anforderungen
account kann nicht die Nulladresse sein.account muss amount Token haben. */ function _burn (Adresskonto, Uint256) Internal Virtual {fordert (Konto! = Adresse (0), "ERC20: Burn aus der Nulladresse");_BeforeTokentransfer (Konto, Adresse (0), Betrag);
_Balances [Konto] = _Balances [Konto] .Sub (Betrag, "ERC20: Verbrennungsbetrag überschreitet den Restbetrag"); _totalsupply = _totalsupply.sub (Menge); Übertragung (Konto, Adresse (0), Betrag); }
/**
@dev setzt amount als Zulage des spender über die Token des owner .
Diese interne Funktion entspricht der approve und kann verwendet werden
zB automatische Zulagen für bestimmte Subsysteme usw.
Emittiert ein Ereignis {Genehmigung}.
Anforderungen:
owner kann nicht die Null -Adresse sein.spender kann nicht die Nulladresse sein. */ function approve (Adressbesitzer, Adressspender, Uint256) Internal Virtual {fordert (Eigentümer! = Adresse (0), "ERC20: von der Nulladresse genehmigen"); erfordern (Spender! = Adresse (0), "ERC20: Genehmigen Sie es zur Nulladresse");_lowances [Eigentümer] [Spender] = Betrag; Genehmigung (Eigentümer, Spender, Betrag) abgeben; }
/**
/**
from und von to beide ungleich Null, amount from Tokens sindto .from Null ist, werden amount Token to .to Null ist, wird amount von from 's Tokens verbrannt.from und to sind nie beide Null.// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@dev Dieser Vertrag erweitert ein ERC20 -Token mit einem Snapshot -Mechanismus. Wenn ein Schnappschuss erzeugt wird, die Balances und
Die Gesamtversorgung zu dieser Zeit wird für einen späteren Zugang erfasst.
Dies kann verwendet werden, um sichere Mechanismen zu erstellen, die auf Token -Guthaben wie vertrauenslosen Dividenden oder gewichteten Abstimmungen basieren.
In naiven Implementierungen ist es möglich, einen "doppelten Ausgaben" -Angriff auszuführen, indem das gleiche Gleichgewicht von verschiedenen wiederverwendet wird
Konten. Durch die Verwendung von Snapshots zur Berechnung von Dividenden oder Stimmleistung gelten diese Angriffe nicht mehr. Es kann auch sein
Wird verwendet, um einen effizienten ERC20 -Gabelmechanismus zu erstellen.
Snapshots werden von der internen Funktion {_snapshot} erstellt, die das Ereignis {Snapshot} ausgibt und a zurückgibt
Snapshot -ID. Um die Gesamtversorgung zum Zeitpunkt eines Snapshots zu erhalten
Ausweis. Um den Restbetrag eines Kontos zum Zeitpunkt eines Snapshots zu erhalten
und die Kontoadresse.
==== Gaskosten
Schnappschüsse sind effizient. Snapshot -Erstellung ist o (1) . Abrufen von Balances oder Gesamtversorgung aus einem Schnappschuss ist _O (Protokoll
n) _ in der Anzahl der erstellten Schnappschüsse, obwohl n für ein bestimmtes Konto im Allgemeinen viel sein wird
kleiner, da identische Ausgleiche in nachfolgenden Schnappschüssen als einzelne Eintrag gespeichert werden.
Aufgrund der zusätzlichen Snapshot -Buchhaltung gibt es einen konstanten Overhead für normale ERC20 -Transfers. Dieser Overhead ist
Nur für die erste Übertragung, die unmittelbar einem Schnappschuss für ein bestimmtes Konto folgt. Nachfolgend
Transfers haben normale Kosten bis zum nächsten Schnappschuss und so weiter. */Abstract Contract ERC20Snapshot ist ERC20 {// inspiriert von Jordi Baylinas Minimum, um historische Balances aufzunehmen: // https://github.com/giveth/minimd/blob/ea04d950eea153a04c51fa510b0688b0688b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b068b 0
Verwenden von Safemath für uint256; Verwenden von Arrays für uint256 []; Verwenden von Zählern für Zähler.Counter;
// Snapshotted -Werte haben Arrays von IDs und den Wert, der dieser ID entspricht. Dies könnte eine Reihe von A // Snapshot -Strukturen sein, aber das würde die Verwendung von Funktionen beeinträchtigen, die auf einem Array funktionieren. struct snapshots {uint256 [] ids; uint256 [] Werte; }
Mapping (Adresse => Snapshots) private _accountBalancesNapshots; Snapshots private _totalsupplySnapshots;
// Snapshot -IDs erhöhen monoton, wobei der erste Wert 1 ist. Eine ID von 0 ist ungültig. Counters.Counter private _currentsnapshotid;
/**
id identifizierte Snapshot erstellt wird. */ Event Snapshot (uint256 id);/**
@dev erstellt einen neuen Schnappschuss und gibt seine Snapshot -ID zurück.
Emittiert ein {snapshot} -Ergument, das dieselbe ID enthält.
{_snapshot} ist internal und Sie müssen entscheiden, wie Sie es extern aufdecken können. Die Verwendung kann auf a beschränkt sein
SETTE ANTWORTEN, z. B. mit {AccessControl}, oder es kann für die Öffentlichkeit zugänglich sein.
[WARNUNG]
====
Während ein offener Weg zum Aufrufen von {_snapshot} für bestimmte Vertrauensminimierungsmechanismen wie Gabeln erforderlich ist, ist
Sie müssen bedenken, dass es möglicherweise von Angreifern auf zwei Arten verwendet werden kann.
Erstens kann es verwendet werden, um die Kosten für das Abrufen von Werten von Schnappschüssen zu erhöhen, obwohl es wachsen wird
logarithmisch so diesen Angriff langfristig unwirksam. Zweitens kann es zum Ziel verwendet werden
Spezifische Konten und erhöhen die Kosten von ERC20 -Übertragungen für sie auf die Art und Weise, wie in den Gaskosten angegeben ist
Abschnitt oben.
Wir haben die tatsächlichen Zahlen nicht gemessen. Wenn Sie dies interessieren, wenden Sie sich bitte an uns.
===== */ function _snapshot () interne virtuelle Rückgaben (uint256) {_currentsnapShotid.increment ();
uint256 currentId = _currentsnapshotid.current (); Snapshot (CurrentID) emittieren; Return CurrentID; }
/**
@dev ruft den account zum Erstellen von snapshotId ab. */ Funktions -Balance (Adresskonto, Uint256 Snapshotid) öffentliche Ansicht returns (uint256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _accountBalancesNapshots [Konto]);
Return Snapshotted? Wert: Saldo (Konto); }
/**
@dev holt das Gesamtangebot zum Zeitpunkt der Erstellung snapshotId ab. */ function Totalsupplyat (uint256 snapshotid) öffentliche Ansicht returns (uint256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _totalsupplySnapShots);
Return Snapshotted? Wert: sotalsupply (); }
// Aktualisieren Sie den Saldo und/oder die Gesamtversorgungs -Schnappschüsse, bevor die Werte geändert werden. Dies wird im _BeforeTokentransfer -Hook implementiert, der für _Mint-, _burn- und _transfer -Operationen ausgeführt wird. Funktion _BeforeTokentransfer (Adresse von, Adresse zu, uint256) interne virtuelle Überschreibung {Super._Beforetokentansfer (von, bis, Menge);
if (from == address (0)) {// mint _UpDateAccountsnapshot (to); _UPDATETOTALSUPPLYSNAPSHOT (); } else if (to == address (0)) {// Burn _UpDateAccountsnapshot (von); _UPDATETOTALSUPPLYSNAPSHOT (); } else {// übertragen _UpDateACCountSnapshot (von); _UpDateAccountSnapshot (an); }}
Funktion _valueat (UINT256 Snapshotid, Snapshots Speicher -Snapshots) private Ansicht retektiert (bool, uint256) {fordert (snapshotid> 0, "ERC20SNAPSHOT: ID IS 0"); // Solhint-disable-NEXT-Line Max-Line-Leng-Anforderung (Snapshotid <= _currentsnapshotid.current (), "ERC20Snapshot: nicht existent id");
// 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]);
}
}
Funktion _UpDateAccountSnapShot (Adresskonto) privat {_updatesnapShot (_accountBalancesNapShots [Konto], Saldo (Konto)); }
function _UpDATETOTALSUPPLYSNAPSHOT () private {_updatesnapShot (_totalsupplySnapShots, Totalsupply ()); }
Funktion _UPDATESSNAPSHOT (Snapshots -Speicher -Snapshots, Uint256 CurrentValue) privat {uint256 currentId = _currentsnapshotid.current (); if (_lastsnapshotid (snapshots.ids) <currentId) {snapshots.ids.push (currentId); snapshots.values.push (currentValue); }}
Funktion _lastsnapShotID (uint256 [] Speicher -IDs) private Ansicht returns (uint256) {if (ids.length == 0) {return 0; } else {return ids [ids.length - 1]; }}}
// Teillizenz: MIT
Pragma Solidität ^0,6,0;
/**
@Dev Library für die Verwaltung
https://en.wikipedia.org/wiki/set_(abstract_data_type) -Asets] von Primitive
Typen.
Sets haben die folgenden Eigenschaften:
(O (1)).
Vertragsbeispiel {
// Add the library methods
using EnumerableSet for EnumerableSet.AddressSet;
// Declare a set state variable
EnumerableSet.AddressSet private mySet;
}
Ab V3.0.0 sind nur Sätze der address ( AddressSet ) und uint256
( UintSet ) werden unterstützt. */ Bibliothek enumerableSet {// Um diese Bibliothek für mehrere Typen mit so wenig Code // Wiederholung wie möglich zu implementieren, schreiben wir sie in Bezug auf einen generischen Set -Typ mit // Bytes32 -Werten. // In der SET-Implementierung werden private Funktionen verwendet, und von Benutzer ausgerichtet // Implementierungen (z. B. Adresse) sind nur Wrapper rund um den zugrunde liegenden Satz. // Dies bedeutet, dass wir nur neue EnumerableSets für Typen erstellen können, die in Bytes32 passen.
struct set {// Speicherung von Set -Werten 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 entfernt einen Wert aus einem Satz. O (1).
Gibt true zurück, wenn der Wert aus dem Satz entfernt wurde, das heißt, wenn er war
gegenwärtig. */ function _remove (Set Speicherset, Byte32 Wert) private Returns (bool) {// Wir lesen und speichern den Wert des Werts, um mehrere Lesevorgänge aus demselben Speicherplatz uint256 valueIndex = set._indexes [value] zu verhindern.
if (valueIndex! // Dies ändert die Reihenfolge des Arrays, wie in {at} angegeben.
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 im Set gespeichert ist. 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 . Kann verwendet werden/**
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}
Ereignis.
Anforderungen:
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.
Anforderungen:
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}
Ereignis.
Anforderungen:
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();
}
}