QX ERC20 Science Token /** *تم تقديمه للتحقق في Etherscan.io في 2020-12-24 * /
Pragma Slidity ^0.6.0 ؛
/**
أغلفة dev على العمليات الحسابية للصلابة مع زيادة في التدفق
الشيكات.
العمليات الحسابية في التفاف الصلابة على الفائض. هذا يمكن أن يؤدي بسهولة
في الأخطاء ، لأن المبرمجين عادة ما يفترضون أن الفائض يرفع
خطأ ، وهو السلوك القياسي في لغات البرمجة عالية المستوى.
يستعيد SafeMath هذا الحدس من خلال عودة المعاملة عند
تفيض العملية.
إن استخدام هذه المكتبة بدلاً من العمليات غير المحددة يلغي كاملًا
فئة من الأخطاء ، لذلك يوصى باستخدامه دائمًا. / مكتبة Safemath { / *
@dev يعيد إضافة اثنين من الأعداد الصحيحة غير الموقعة ، والعودة على
الفائض.
نظير لمشغل SLIEDIDA + .
متطلبات:
العودة ج. }
/**
- المشغل./**
@dev إرجاع الطرح من اثنين من الأعداد الصحيحة غير موقعة ، والعودة مع رسالة مخصصة في
الفائض (عندما تكون النتيجة سلبية).
نظير إلى المشغل - المشغل.
متطلبات:
العودة ج. }
/**
@DEV يعيد تكاثر اثنين من الأعداد الصحيحة غير الموقعة ، والعودة على
الفائض.
نظير لمشغل * صلابة *.
متطلبات:
uint256 c = a * b ؛ تتطلب (c / a == b ، "safemath: verflow الضرب") ؛
العودة ج. }
/**
/ مشغل. ملاحظة: تستخدم هذه الوظيفة أrevert opcode (الذي يترك الغاز المتبقي دون أن يمس) أثناء الصلابة/**
@Dev يعيد تقسيم عدد صحيح من اثنين من الأعداد الصحيحة غير موقعة. يعود مع رسالة مخصصة على
قسم من الصفر. يتم تقريب النتيجة نحو الصفر.
نظير إلى صلابة / مشغل. ملاحظة: تستخدم هذه الوظيفة أ
revert opcode (الذي يترك الغاز المتبقي دون أن يمس) أثناء الصلابة
يستخدم رمز opcon غير صالح للعودة (استهلاك جميع الغاز المتبقي).
متطلبات:
العودة ج. }
/**
% صلابة. تستخدم هذه الوظيفة revert/**
% صلابة. تستخدم هذه الوظيفة revert// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
@DEV Standard Math Utilities مفقودة في لغة الصلابة. / مكتبة الرياضيات { / *
/**
/**
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
يبحث dev عن array مصنفة ويعيد الفهرس الأول الذي يحتوي
قيمة أكبر أو تساوي element . إذا لم يكن هناك مثل هذا الفهرس (أي الكل
القيم الموجودة في الصفيف أقل تمامًا من element ) ، طول الصفيف هو
عاد. تعقيد الوقت o (سجل n).
من المتوقع فرز array بالترتيب الصاعد ، ولا يحتوي على لا
العناصر المتكررة. */ function findupperBound (uint256 [] صفيف التخزين ، عنصر uint256) إرجاع العرض الداخلي (uint256) {if (array.length == 0) {return 0 ؛ }
uint256 low = 0 ؛ UINT256 HIGH = ARRAY.Length ؛
بينما (low <High) {uint256 mid = math.average (low ، high) ؛
// 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;
}
}
// في هذه المرحلة low هو الحد العلوي الحصري. سنعيد الحد العلوي الشامل. if (low> 0 && array [low - 1] == element) {return low - 1 ؛ } آخر {return low ؛ }}}
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
عدادات title
Author Matt Condon (@shrugs)
يوفر DEV عدادات لا يمكن زيادة أو تناقصها إلا. يمكن استخدام هذا على سبيل المثال لتتبع الرقم
عناصر في رسم الخرائط ، أو إصدار معرفات ERC721 ، أو معرفات طلب العد.
تشمل مع using Counters for Counters.Counter;
نظرًا لأنه من غير الممكن أن تتفوق على عدد صحيح 256 بت مع زيادات واحدة ، يمكن increment تخطي {Safemath}
فحص الفائض ، وبالتالي توفير الغاز. هذا يفترض الاستخدام الصحيح ، حيث أن _value الأساسية هي أبدا
تم الوصول إليها مباشرة. */ عدادات المكتبة {باستخدام safemath for uint256 ؛
struct struct {// يجب ألا يتم الوصول إلى هذا المتغير مباشرة من قبل مستخدمي المكتبة: يجب أن تقتصر التفاعلات على // وظيفة المكتبة. اعتبارًا من الصلابة V0.5.2 ، لا يمكن تطبيق هذا ، على الرغم من وجود اقتراح لإضافة // هذه الميزة: انظر Ethereum/Slidity#4637 UINT256 _value ؛ // الافتراضي: 0}
الوظيفة الحالية (عداد تخزين العداد) إرجاع العرض الداخلي (UINT256) {return Counter._value ؛ }
زيادة الوظيفة (عداد تخزين العداد) الداخلية {// يمكن تخطي فحص الفائض {safemath} هنا ، انظر التعليق في العداد الأعلى ._value += 1 ؛ }
انخفاض الوظيفة (عداد تخزين العداد) {counter._value = counter._value.sub (1) ؛ }}
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/*
يوفر Dev معلومات حول سياق التنفيذ الحالي ، بما في ذلك
مرسل المعاملة وبياناتها. في حين أنها متوفرة بشكل عام
عبر msg.sender و msg.data ، لا ينبغي الوصول إليها في مثل هذا المباشر
بطريقة ، لأنه عند التعامل مع المعاملات الوصفية GSN ، فإن الحساب الذي يرسل و
قد لا يكون دفع مقابل التنفيذ المرسل الفعلي (بقدر ما أحد التطبيقات
قلق).
هذا العقد مطلوب فقط للعقود المتوسطة التي تشبه المكتبة. */ مجردة العقد سياق {function _msgsender () عرض داخلي العوائد الافتراضية (العنوان المستحق) {return msg.sender ؛ }
الدالة _msgdata () العرض الداخلي العوائد الظاهرية (ذاكرة البايت) {this ؛ // SILENCE SILENCE DOTALION TOPNING DORNING دون توليد رمز BYTECODE - انظر Ethereum/SLIEDITY#2691 return msg.data ؛ }}
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
@DEV واجهة معيار ERC20 كما هو محدد في EIP. / واجهة IERC20 { / *
/**
account . */ توازن الدالة (حساب العنوان) إرجاع العرض الخارجي (UINT256) ؛/**
amount من حساب المتصل إلى recipient ./**
spenderowner من خلال {transferfrom}. هذا هو/**
amount كبدل spender على الرموز المميزة للمتصل./**
amount من sender إلى recipient باستخدامamount من المتصل/**
value من حساب واحد ( from ) إلىto ).value قد تكون صفر. */ نقل الأحداث (العنوان المفهرس من ، العنوان المفهرس إلى ، uint256 قيمة) ؛/**
spender ownervalue هي البدل الجديد. */ موافقة الحدث (المالك المفهرس العنوان ، العنوان المفهرس SPENDER ، UINT256 قيمة) ؛ }// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Sality ^0.6.2 ؛
/**
@dev مجموعة الوظائف المتعلقة بنوع العنوان / عنوان المكتبة { / *
@DEV إرجاع صحيح إذا كان account عقدًا.
[مهم]
====
من غير الآمن افتراض أن العنوان الذي تعود إليه هذه الوظيفة
خطأ هو حساب مملوك خارجيا (EOA) وليس عقدًا.
من بين أمور أخرى ، سيعود isContract False لما يلي
أنواع العناوين:
==== */ وظيفة ISContract (حساب العنوان) إرجاع العرض الداخلي (BOOL) {// تعتمد هذه الطريقة في ExtCodesize ، والتي تُرجع 0 للعقود في // البناء ، حيث يتم تخزين الرمز فقط في نهاية تنفيذ // مُنشئ.
uint256 حجم ؛ . }
/**
@DEV استبدال transfer الصلابة: يرسل amount WEI إلى
recipient ، وإعادة توجيه جميع الغاز المتاح والعودة على الأخطاء.
https://eips.ethereum.org/eips/EIP-1884 Budapeip1884] يزيد من تكلفة الغاز
لبعض الرموز المفردات ، ربما تتراوح عقود في الحد الأدنى من الغاز 2300
فرضها transfer ، مما يجعلهم غير قادرين على تلقي الأموال عبر
transfer . {sendvalue} يزيل هذا القيد.
https://diligence.consensys.net/posts/2019/09/stop-using-solidals-transfer-now/ budaplearn أكثر].
هام: لأنه يتم نقل التحكم إلى recipient ، يجب أن تكون الرعاية
اتخذت لعدم إنشاء نقاط الضعف. النظر في استخدام
{reentrancyguard} أو
https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern budapchecks-Effects-interactions نمط]. */ وظيفة sendvalue (العناوين ذات الدفع المستحقة ، uint256 المبلغ) {require (address (this).
. يتطلب (النجاح ، "العنوان: غير قادر على إرسال القيمة ، قد يكون المستلم قد عاد") ؛ }
/**
call منخفضة المستوى. أcall العادية هي بديل غير آمن لمكالمة دالة: استخدم هذاtarget يعود إلى سبب العودة ، فسيتم هذا الأمرtarget عقدًا.target مع data لا يعود./**
functionCall ] ، ولكن معerrorMessage كإرجاع يعود إلى سبب عندما يعود target ./**
functionCall ] ،value واي إلى target .value على الأقل.payable ./**
functionCallWithValue مثل {xref-address-functionCallwithValue-Address-Bytes-Uint256-}errorMessage كأعلى يعود إلى سبب عودة عندما يعود target .الدالة _functionCallWithValue (هدف العنوان ، بيانات الذاكرة ، uint256 weivalue ، string memory errormessage) إرجاع خاص (ذاكرة البايت) {require (isContract (target) ، "العنوان: الاتصال إلى غير العقد") ؛
// 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);
}
}
}}
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
DEV تنفيذ واجهة {ierc20}.
هذا التنفيذ لادرس في طريقة إنشاء الرموز. هذا يعنى
يجب إضافة آلية العرض في عقد مشتق باستخدام {_mint}.
للاطلاع على آلية عامة ، انظر {ERC20PRESETMINTERPAUSER}.
نصيحة: للحصول على كتابة مفصلة ، انظر دليلنا
https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-michisms/226 Budaphow
لتنفيذ آليات العرض].
لقد تابعنا إرشادات General Openzeppelin: تعود الوظائف بدلاً من ذلك
من العودة false على الفشل. هذا السلوك مع ذلك تقليدي
ولا تتعارض مع توقعات تطبيقات ERC20.
بالإضافة إلى ذلك ، ينبعث حدث {موافقة} على المكالمات إلى {transferfrom}.
يتيح ذلك للتطبيقات إعادة بناء بدل جميع الحسابات فقط
من خلال الاستماع إلى الأحداث المذكورة. قد لا تنبعث تطبيقات أخرى من EIP
هذه الأحداث ، لأنه غير مطلوب من خلال المواصفات.
أخيرًا ، فإن {decreaseallowance} و {regreaseallowance}
تمت إضافة وظائف لتخفيف القضايا المعروفة حول الإعداد
البدلات. انظر {ierc20-approve}. */ العقد ERC20 هو السياق ، IERC20 {باستخدام Safemath لـ UINT256 ؛ باستخدام عنوان العنوان ؛
رسم الخرائط (العنوان => uint256) private _bolances ؛
رسم الخرائط (العنوان => رسم الخرائط (العنوان => uint256)) خاص _allowances ؛
uint256 private _totalsupply ؛
سلسلة خاصة _name ؛ سلسلة خاصة _symbol ؛ uint8 private _decimals ؛
/**
/**
/**
/**
decimals يساوي 2 ، فيجب أن يكون توازن 505 رمزًا5,05 ( 505 / 10 ** 2 )./**
/**
/**
recipient لا يمكن أن يكون عنوان الصفر.amount . */ نقل الوظائف (مستلم العنوان ، مبلغ UINT256) العوائد الافتراضية العامة (BOOL) {_transfer (_msgsender () ، المستلم ، المبلغ) ؛ العودة صحيح. }/**
/**
spender الصفر. */ الوظيفة الموافقة على (العنوان المنحدر ، المبلغ UINT256) إرجاع الافتراضية العامة (bool) {_approve (_msgsender () ، spender ، المبلغ) ؛ العودة صحيح. }/**
sender recipient لا يمكن أن يكونا عنوان الصفر.sender amount على الأقل.sender على الأقلamount . */ انتقاد الوظيفة (مرسل العنوان ، مستلم العنوان ، مبلغ UINT256) العوائد الافتراضية العامة (bool) {_transfer (المرسل ، المستلم ، المبلغ) ؛ _approve (المرسل ، _msgsender () ، _allowances [sender] [_ msgsender ()]. sub (المبلغ ، "ERC20: يتجاوز مبلغ النقل بدل")) ؛ العودة صحيح. }/**
spender من قبل المتصل.spender الصفر. */ الوظيفة styreaseallowance (العنوان المنحدر ، uint256 المضافة Value) العوائد الافتراضية العامة (bool) {_approve (_msgsender () ، spender ، _allows [_msgsender ()] [spender] .add (addvalue)) ؛ العودة صحيح. }/**
spender من قبل المتصل.spender الصفر.spender بدل للمتصل على الأقلsubtractedValue . */ الوظيفة DEMEREASEALWONANCE (العنوان SPENDER ، UINT256 PUSSITEDVALUE) العوائد الافتراضية العامة (BOOL) {_approve (_msgsender () ، spender ، _allowances [_msgsender ()] العودة صحيح. }/**
@Dev ينقل amount الرموز من sender إلى recipient .
هذه الوظيفة الداخلية تعادل {transfer} ، ويمكن استخدامها ل
على سبيل المثال ، قم بتنفيذ رسوم الرمز المميز التلقائي ، وآليات التخفيض ، إلخ.
ينبعث من حدث {transfer}.
متطلبات:
sender هو عنوان الصفر.recipient لا يمكن أن يكون عنوان الصفر.sender amount على الأقل. */ function _transfer (مرسل العنوان ، مستلم العنوان ، مبلغ uint256) الافتراضية الداخلية {require (sender! = العنوان (0) ، "ERC20: نقل من العنوان الصفر") ؛ تتطلب (المستلم! = العنوان (0) ، "ERC20: نقل إلى عنوان الصفر") ؛_beforetokentransfer (المرسل ، المستلم ، المبلغ) ؛
_ بصيصات [المرسل] = _Bolances [Sender] .Sub (المبلغ ، "ERC20: مبلغ النقل يتجاوز الرصيد") ؛ _Calances [المستلم] = _bolances [المستلم] .add (المبلغ) ؛ نقل الانبعاث (المرسل ، المستلم ، المبلغ) ؛ }
/** dev يخلق الرموز amount ويعينها في account ، والزيادة
إجمالي العرض.
ينبعث من حدث {transfer} مع from تعيين إلى عنوان الصفر.
متطلبات
to يكون عنوان الصفر. */ function _mint (حساب العنوان ، المبلغ uint256) الافتراضية الداخلية {require (حساب! = العنوان (0) ، "ERC20: Mint to the Zero Address") ؛_beforetokentransfer (العنوان (0) ، الحساب ، المبلغ) ؛
_totalsupply = _totalsupply.add (المبلغ) ؛ _Calances [الحساب] = _Bolances [حساب] .Add (المبلغ) ؛ نقل الانبعاث (العنوان (0) ، الحساب ، المبلغ) ؛ }
/**
Dev يدمر الرموز amount من account ، مما يقلل من
إجمالي العرض.
ينبعث من حدث {transfer} مع to عنوان الصفر.
متطلبات
account هو عنوان الصفر.account على الأقل amount الرموز. */ function _burn (حساب العنوان ، المبلغ uint256) الافتراضية الداخلية {require (حساب! = العنوان (0) ، "ERC20: Burn from the Zero Address") ؛_beforetokentransfer (الحساب ، العنوان (0) ، المبلغ) ؛
_Calances [الحساب] = _Calances [حساب] .Sub (المبلغ ، "ERC20: يتجاوز كمية الحرق الرصيد") ؛ _totalsupply = _totalsupply.sub (المبلغ) ؛ نقل الانبعاث (الحساب ، العنوان (0) ، المبلغ) ؛ }
/**
يحدد dev amount كبدل spender عن الرموز المميزة owner .
هذه الوظيفة الداخلية تعادل approve ، ويمكن استخدامها
على سبيل المثال ، قم بتعيين البدلات التلقائية لبعض الأنظمة الفرعية ، إلخ.
ينبعث من حدث {موافقة}.
متطلبات:
owner عنوان الصفر.spender الصفر. */ function _approve (مالك العنوان ، العنوان ، spender ، uint256 المبلغ) الافتراضية الداخلية {require (ال. تتطلب (SPENDER! = العنوان (0) ، "ERC20: الموافقة على عنوان الصفر") ؛_allowances [المالك] [spender] = المبلغ ؛ انبعاث الموافقة (المالك ، المنافس ، المبلغ) ؛ }
/**
/**
from to كلاهما غير صفري ، amount من الرموز fromto .from الصفر ، سيتم استخلاص amount الرموز to .to الصفر ، سيتم حرق amount from الرموز المميزة.from وإلى to لا صفر.// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
dev هذا العقد يمتد رمز ERC20 مع آلية لقطة. عند إنشاء لقطة ، توازن الأرصدة و
يتم تسجيل إجمالي العرض في ذلك الوقت للوصول لاحقًا.
يمكن استخدام هذا لإنشاء آليات بأمان بناءً على أرصدة رمزية مثل الأرباح غير الموثوقة أو التصويت المرجح.
في التطبيقات الساذجة ، من الممكن القيام بهجوم "إنفاق مزدوج" من خلال إعادة استخدام نفس التوازن من مختلف
حسابات. باستخدام لقطات لحساب الأرباح أو قوة التصويت ، لم تعد تلك الهجمات تنطبق. يمكن أن يكون أيضا
تستخدم لإنشاء آلية forking فعالة ERC20.
يتم إنشاء اللقطات بواسطة وظيفة {_snapshot} الداخلية ، والتي ستنبعث من حدث {snapshot} وإرجاع أ
معرف اللقطة. للحصول على إجمالي العرض في وقت لقطة ، اتصل بالوظيفة {TotalSupplyat} مع اللقطة
بطاقة تعريف. للحصول على رصيد حساب في وقت لقطة ، اتصل بوظيفة {palanceofat} مع معرف اللقطة
وعنوان الحساب.
==== تكاليف الغاز
لقطات فعالة. خلق لقطة هو o (1) . استرجاع الأرصدة أو إجمالي العرض من لقطة هو _O (سجل
n) _ في عدد اللقطات التي تم إنشاؤها ، على الرغم من أن n لحساب معين سيكون كثيرًا بشكل عام
أصغر منذ أن تم تخزين الأرصدة المتطابقة في لقطات لاحقة كإدخال واحد.
هناك عام مستمر لنقل ERC20 العادي بسبب مسك الدفاتر الإضافية لقطات. هذا النفقات العامة
مهم فقط للانتقال الأول الذي يتبع على الفور لقطة لحساب معين. تالي
سيكون للنقل تكلفة عادية حتى اللقطة التالية ، وهلم جرا. */العقد التجريدي erc20snapshot هو erc20 {// مستوحى من Jordi Baylina MinimeToken لتسجيل الأرصدة التاريخية: //
باستخدام Safemath لـ UINT256 ؛ باستخدام المصفوفات لـ UINT256 [] ؛ باستخدام عدادات للعدادات.
// تحتوي القيم النقطة على صفائف من IDS والقيمة المقابلة لهذا المعرف. يمكن أن تكون هذه مجموعة من بنية A // Snapshot ، ولكن هذا من شأنه أن يعوق استخدام الوظائف التي تعمل على صفيف. struct snapshots {uint256 [] ids ؛ uint256 [] القيم ؛ }
رسم الخرائط (العنوان => لقطات) _AccountbalustyNapshots ؛ لقطات خاصة _totalsupplysnapshots ؛
// معرفات اللقطة تزيد رتابة ، مع القيمة الأولى هي 1. معرف 0 غير صالح. counters.counter private _currentsnapshotid ؛
/**
id . */ لقطة الحدث (uint256 id) ؛/**
تقوم Dev بإنشاء لقطة جديدة وإرجاع معرف اللقطة.
ينبعث من حدث {snapshot} الذي يحتوي على نفس المعرف.
{_snapshot} internal وعليك أن تقرر كيفية فضحه خارجيًا. قد يقتصر استخدامه على
مجموعة من الحسابات ، على سبيل المثال باستخدام {AccessControl} ، أو قد تكون مفتوحة للجمهور.
[تحذير]
====
في حين أن هناك طريقة مفتوحة لاتصال {_snapshot} مطلوب لآليات تقليل الثقة بعض الثقة مثل forking ،
يجب أن تفكر في أنه يمكن استخدامه من قبل المهاجمين بطريقتين.
أولاً ، يمكن استخدامه لزيادة تكلفة استرداد القيم من اللقطات ، على الرغم من أنها ستنمو
لوجاريتميا مما يجعل هذا الهجوم غير فعال على المدى الطويل. ثانياً ، يمكن استخدامه للاستهداف
حسابات محددة وزيادة تكلفة نقل ERC20 لهم ، بالطرق المحددة في تكاليف الغاز
القسم أعلاه.
لم نقم بقياس الأرقام الفعلية ؛ إذا كان هذا شيء تهتم به ، فيرجى التواصل معنا.
==== */ function _snapshot () الإرجاع الظاهري الداخلي (uint256) {_currentsnapshotid.increment () ؛
uint256 currentId = _currentsnapshotid.current () ؛ لقطة تنبعث منها (CurrentId) ؛ إرجاع CurrentID. }
/**
@Dev يسترجع رصيد account في الوقت الذي تم فيه إنشاء snapshotId . */ function balanceofat (حساب العنوان ، uint256 snapshotid) إرجاع العرض العام (uint256) {(bool snapshotted ، uint256 value) = _valueat (snapshotid ، _AccountbalancesNapshots [account]) ؛
إرجاع لقطة؟ القيمة: توازن (حساب) ؛ }
/**
@Dev يسترجع إجمالي العرض في الوقت الذي تم فيه إنشاء snapshotId . */ وظيفة otalsupplyat (uint256 snapshotid) إرجاع العرض العام (uint256) {(bool snapshotted ، uint256 value) = _valueat (snapshotid ، _totalsupplysnapshots) ؛
إرجاع لقطة؟ القيمة: otalsupply () ؛ }
// تحديث الرصيد و/أو إجمالي لقطات التوريد قبل تعديل القيم. يتم تنفيذ ذلك // في خطاف _beforetokentrans ، الذي يتم تنفيذه لعمليات _mint و _burn و _transfer. الدالة _beforetokentransfer (العنوان من ، العنوان إلى ، uint256 المبلغ) تجاوز الافتراضية الداخلية {super._beforetokentransfer (من ، إلى ، المبلغ) ؛
if (from == address (0)) {// mint _updateaccountsnapshot (to) ؛ _updatetOtalSupplySnapshot () ؛ } آخر إذا (إلى == عنوان (0)) {// burn _updateaccountsnapshot (من) ؛ _updatetOtalSupplySnapshot () ؛ } آخر {// transfer _updateaccountsnapshot (من) ؛ _updateaccountsnapshot (إلى) ؛ }}
الدالة _valueat (UINT256 Snapshotid ، لقطات تخزين لقطات) إرجاع عرض خاص (Bool ، Uint256) {require (snapshotid> 0 ، "ERC20SNAPSHOT: ID IS 0") ؛ // solhint-dis-next-line-line-length-length تتطلب (snapshotid <= _currentsnapshotid.current () ، "erc20snapshot: معرف غير موجود") ؛
// 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]);
}
}
الدالة _updateaccountsnapshot (حساب العنوان) الخاص {_updatesnapshot (_AccountbalustyNapshots [حساب] ، BalanceOf (حساب)) ؛ }
الدالة _updatetOtalSupplySnapshot () private {_updatesnapshot (_totalsupplysnapshots ، totalsupply ()) ؛ }
الدالة _updatesnapshot (لقطات لقطات تخزين ، uint256 currentValue) private {uint256 currentId = _currentsnapshotid.current () ؛ if (_lastsnapshotid (snapshots.ids) <currentId) {snapshots.ids.push (currentId) ؛ snapshots.values.push (CurrentValue) ؛ }}
الدالة _lastssnapshotid (uint256 [] معرفات التخزين) إرجاع العرض الخاص (uint256) {if (ids.length == 0) {return 0 ؛ } آخر {ids ids [ids.length - 1] ؛ }}}
// ترخيص جزئي: معهد ماساتشوستس للتكنولوجيا
Pragma Slidity ^0.6.0 ؛
/**
مكتبة dev للإدارة
https://en.wikipedia.org/wiki/set_(abstract_data_type budapsets] من البدائية
الأنواع.
مجموعات لها الخصائص التالية:
(س (1)).
مثال العقد {
// Add the library methods
using EnumerableSet for EnumerableSet.AddressSet;
// Declare a set state variable
EnumerableSet.AddressSet private mySet;
}
اعتبارًا من V3.0.0 ، مجموعات فقط من address ( AddressSet ) و uint256
( UintSet ) مدعومة. */ Library enumerableset {// لتنفيذ هذه المكتبة لأنواع متعددة مع القليل من الكود // التكرار قدر الإمكان ، فإننا نكتبها من حيث نوع مجموعة عامة مع قيم // bytes32. // يستخدم تطبيق SET وظائف خاصة ، وتواصل المستخدم // التطبيقات (مثل مجموعة العنوان) مجرد مغلفات حول المجموعة // الأساسية. // هذا يعني أنه لا يمكننا سوى إنشاء replistableseets جديدة للأنواع التي تناسب // في bytes32.
STRIC SET {// تخزين قيم 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 يزيل قيمة من مجموعة. س (1).
إرجاع صحيح إذا تمت إزالة القيمة من المجموعة ، فهذا إذا كان
حاضر. */ function _remove (مجموعة تخزين مجموعة ، قيمة BYTES32) عوائد خاصة (BOOL) {// نقرأ وتخزين فهرس القيمة لمنع قراءات متعددة من نفس فتحة التخزين UINT256 valueIndex = set._indexes [value] ؛
إذا كان (valueIndex! = 0) {// مكافئًا لـ (set ، value) // حذف عنصر من صفيف _values في O (1) ، نقوم بتبديل العنصر للحذف مع آخر واحد في // الصفيف ، ثم إزالة العنصر الأخير (أحيانًا يسمى "المبادلة والبوب"). // هذا يعدل ترتيب الصفيف ، كما هو موضح في {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;
} آخر {return false ؛ }}
/**
/**
/**
index الموضع في المجموعة. س (1).index أقل من {Length}. */ function _at (مجموعة التخزين ، فهرس UINT256) إرجاع العرض الخاص (bytes32) {require (set._values.length> index ، "inumerableset: index Out of Bounds") ؛ إرجاع set._values [الفهرس] ؛ }// adventset
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
أدوار. 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 . Can be used/**
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}
حدث.
متطلبات:
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.
متطلبات:
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}
حدث.
متطلبات:
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();
}
}