QX ERC20 Science Token /** *2020-12-24의 Etherscan.io에서 확인을 위해 제출
Pragma Solidity ^0.6.0;
/**
@dev 랩퍼는 오버플로가 추가 된 Solidity의 산술 작업에 대한 래퍼입니다
체크 무늬.
오버플로에 대한 견고성 랩의 산술 작업. 이것은 쉽게 결과 할 수 있습니다
버그에서 프로그래머는 일반적으로 오버플로가
오류, 이것은 높은 수준 프로그래밍 언어의 표준 동작입니다.
SafeMath
작동 오버 플로우.
확인되지 않은 작업 대신이 라이브러리를 사용하면 전체가 제거됩니다.
버그 클래스이므로 항상 사용하는 것이 좋습니다. / 라이브러리 SAFEMATH { / *
@dev는 서명되지 않은 두 개의 정수를 추가하여 반환합니다.
과다.
Solidity 's + 운영자에 대응합니다.
요구 사항 :
반환 c; }
/**
- 에 대응합니다./**
@dev는 서명되지 않은 두 개의 정수의 뺄셈을 반환하여 사용자 정의 메시지로 되돌아갑니다.
오버플로 (결과가 음수 일 때).
Solidity 's - 에 대응합니다.
요구 사항 :
반환 c; }
/**
@dev는 서명되지 않은 두 개의 정수의 곱셈을 반환하여
과다.
Solidity * 운영자에 대응합니다.
요구 사항 :
UINT256 C = A * B; 요구 사항 (C / A == B, "SAFEMATH : 곱셈 오버플로");
반환 c; }
/**
/ Operator에 대응합니다. 참고 :이 기능은 a를 사용합니다revert/**
@dev는 서명되지 않은 두 개의 정수의 정수 부서를 반환합니다. 사용자 정의 메시지로 되돌아갑니다
0에 의한 분할. 결과는 0으로 반올림됩니다.
Solidity / Operator에 대응합니다. 참고 :이 기능은 a를 사용합니다
견고한 동안 Opcode (남은 가스를 그대로 두지 않음)를 revert
유효하지 않은 Opcode를 사용하여 되돌립니다 (남은 가스를 모두 소비).
요구 사항 :
반환 c; }
/**
% 운영자에 대응합니다. 이 기능은 revert/**
% 운영자에 대응합니다. 이 기능은 revert// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
@dev 표준 수학 유틸리티는 견고성 언어로 누락되었습니다. / 라이브러리 수학 { / *
/**
/**
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
@dev는 정렬 된 array 검색하고 포함하는 첫 번째 색인을 반환합니다.
element 와 더 크거나 같은 값. 그러한 지수가 존재하지 않으면 (즉, 모두
배열의 값은 element 보다 엄격하게 작음), 배열 길이는 다음과 같습니다.
반환. 시간 복잡성 O (log n).
array 오름차순으로 정렬 될 것으로 예상되며
반복 된 요소. */ function findUpperBound (UINT256 [] 스토리지 배열, UINT256 요소) 내부보기 returns (uint256) {if (array.length == 0) {return 0; }
UINT256 LOW = 0; UINT256 High = array.length;
while (낮음 <높음) {UINT256 MID = MATH.AVERAGE (낮음, 높음);
// 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; } else {return low; }}}
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
@Title 카운터
@Author Matt Condon (@shrugs)
@dev는 하나만 증가하거나 감소 할 수있는 카운터를 제공합니다. 이것은 예를 들어 숫자를 추적하는 데 사용할 수 있습니다
매핑의 요소, ERC721 ID 발행 또는 요청 ID 계수.
using Counters for Counters.Counter;
1의 증분이있는 256 비트 정수를 넘어갈 수 없으므로 increment {safemath}를 건너 뛸 수 있습니다.
오버 플로우 점검으로 가스를 절약합니다. 그러나 기본 _value 는 결코
직접 액세스했습니다. */ 라이브러리 카운터 {UINT256에 SAFEMATH 사용;
구조 카운터 {//이 변수는 라이브러리 사용자가 직접 액세스해서는 안됩니다. 상호 작용은 // 라이브러리의 기능으로 제한되어야합니다. Solidity V0.5.2 기간 동안, 이것은 시행 될 수 없지만, 이것은 다음과 같은 기능을 추가 할 제안이 있지만 : Ethereum/Solidity#4637 UINT256 _value; // 기본값 : 0}
기능 전류 (카운터 스토리지 카운터) 내부보기 (UINT256) {return counter._value; }
함수 증분 (카운터 스토리지 카운터) 내부 {// {safemath} 오버 플로우 점검을 여기에서 건너 뛸 수 있습니다. 상단 카운터에서 주석을 참조하십시오 ._value += 1; }
함수 감소 (카운터 스토리지 카운터) 내부 {counter._value = counter._value.sub (1); }}
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/*
@dev는 현재 실행 컨텍스트에 대한 정보를 제공합니다.
트랜잭션 발신자 및 데이터. 일반적으로 사용할 수 있습니다
MSG.Sender 및 Msg.Data를 통해 직접 액세스해서는 안됩니다.
GSN 메타 트랜잭션을 처리 할 때 계정 발송 및
실행 비용은 실제 발신자가 아닐 수 있습니다 (응용 프로그램까지
걱정됩니다).
이 계약은 중간 도서관과 같은 계약에만 필요합니다. */ 초록 계약 컨텍스트 {function _msgsender () 내부보기 가상 반환 (주소 지불 가능) {return msg.sender; }
함수 _msgdata () 내부보기 가상 리턴 (bytes memory) {this; // Bytecode를 생성하지 않고 Silence State Mutability 경고 - Ethereum/Solidity#2691 return msg.data; }}
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
EIP에 정의 된 ERC20 표준의 @dev 인터페이스. / 인터페이스 IERC20 { / *
/**
account 별로 소유 한 토큰 금액을 반환합니다. */ function balanceof (주소 계정) 외부보기 반환 (UINT256);/**
recipient 로 amount 토큰을 이동합니다./**
spender 가 될 나머지 토큰 수를 반환합니다.owner 를 대신하여 지출 할 수 있습니다. 이것은/**
spender 의 허용으로 amount 설정합니다./**
sender amount recipientamount 공제됩니다/**
value 토큰이 한 계정에서 ( from )로 이동할 때 방출됩니다.to .value 은 0 일 수 있습니다. */ 이벤트 전송 (주소 색인, 주소 지수로 인덱스 된 주소, UINT256 값);/**
owner 에 대한 spender 의 허용이 설정 될 때 방출됩니다.value 는 새로운 수당입니다. */ 이벤트 승인 (주소 색인 소유자, 주소 색인 된 스펜더, UINT256 값); }// 부분 라이센스 : MIT
Pragma Solidity ^0.6.2;
/**
@dev 주소 유형 / 라이브러리 주소와 관련된 기능 모음 { / *
account 계약 인 경우 @dev는 true를 반환합니다.
[중요한]
====
이 함수가 반환되는 주소를 가정하는 것은 안전하지 않습니다.
False는 외부 소유 계정 (EOA)이며 계약이 아닙니다.
무엇보다도 isContract 다음에 대해 False를 반환합니다
주소 유형 :
==== */ function iscontract (주소 계정) 내부보기 반환 (bool) {//이 메소드는 extCodesize에 의존합니다.이 방법은 // 구성의 계약에 대해 0을 반환합니다. 코드는 // 생성자 실행의 끝에만 저장되기 때문입니다.
UINT256 크기; // solhint-disable-next-line no-inline-assembly 어셈블리 {size : = extCodesize (Account)} return size> 0; }
/**
@dev Solidity의 transfer 위한 교체 : Wei amount 송금합니다.
recipient , 사용 가능한 모든 가스를 전달하고 오류를 반복합니다.
https://eips.ethereum.org/eips/eip-1884] 가스 비용을 증가시킵니다
특정 opcodes의 경우 계약을 체결하는 것은 2300 가스 한도를 초과합니다.
transfer 에 의해 부과되어
transfer . {sendValue}이 제한을 제거합니다.
https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/] more].
중요 : 제어는 recipient 에게 전달되기 때문에 Care는
재창조 취약점을 생성하지 않도록합니다. 사용을 고려하십시오
{ReentrancyGuard} 또는
https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks------- interactions-pattern] checks-effects-interaction 패턴]. */ function sendValue (주소 지불 가능한 수신자, UINT256 금액) 내부 {require (address (this (this) .Balance> = 금액 : 주소 : 불충분 한 균형 ");
// Solhint-disable-next-line 피하기 수준-통신, 피하기-값 (bool success,) = Recepitient.call {value : alk} ( ""); 요구 (성공, "주소 : 값을 보낼 수없고, 수령인이 되돌릴 수 있습니다"); }
/**
call 사용하여 견고 함수 호출을 수행합니다. 에이call 기능 호출에 대한 안전하지 않은 교체품입니다.target 되돌아 오는 이유가되면 이에 의해 거품이 듭니다.target 계약이어야합니다.data 로 target 호출하는 것은 되돌아서는 안됩니다./**
functionCall ]와 동일하지만target 되돌아 갈 때 errorMessage 백이 이유를 되돌립니다./**
functionCall ],value Wei를 target 으로 전송합니다.value 의 ETH 잔액을 가져야합니다.payable 해야합니다./**
functionCallWithValue ], 그러나target 되돌아 갈 때 낙절로 errorMessage 사용하여 이유를 되돌립니다.함수 _functionCallwithValue (주소 대상, 바이트 메모리 데이터, UINT256 WIVIALUE, 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);
}
}
}}
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
{IERC20} 인터페이스의 @DEV 구현.
이 구현은 토큰이 생성되는 방식에 적합합니다. 이것은 의미합니다
{_mint}를 사용하여 파생 계약에 공급 메커니즘을 추가해야합니다.
일반적인 메커니즘은 {erc20presetminterpauser}를 참조하십시오.
팁 : 자세한 글을 보려면 가이드를 참조하십시오
https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226]
공급 메커니즘을 구현하기 위해].
우리는 일반 OpenZeppelin 지침을 따랐습니다. 기능이 대신 회복됩니다
실패시 false 반환. 그럼에도 불구 하고이 행동은 기존입니다
ERC20 응용 프로그램의 기대와 상충되지 않습니다.
또한 {ranstalfrom}에 대한 호출에 {approval} 이벤트가 방출됩니다.
이를 통해 응용 프로그램이 모든 계정에 대한 수당을 재구성 할 수 있습니다.
상기 사건을 들음으로써. EIP의 다른 구현은 방출되지 않을 수 있습니다
사양에서 필요하지 않은 이러한 이벤트.
마지막으로, 비표준 {ledeaseAllowance} 및 {alloweAllowance}
설정과 관련된 잘 알려진 문제를 완화하기 위해 기능이 추가되었습니다.
참작. {IERC20-APPROVE}를 참조하십시오. */ contract erc20은 컨텍스트, IERC20 {UINT256에 SAFEMATH 사용; 주소 주소 사용;
매핑 (주소 => uint256) 개인 _balances;
매핑 (주소 => 매핑 (address => uint256)) private _allowances;
UINT256 Private _totalSupply;
문자열 private _name; 문자열 private _symbol; UINT8 개인 _decimals;
/**
/**
/**
/**
decimals 2 와 같으면 505 토큰의 잔액이5,05 ( 505 / 10 ** 2 )로 표시됩니다./**
/**
/**
recipient 제로 주소가 될 수 없습니다.amount 의 잔액이 있어야합니다. */ 기능 전송 (주소 수신자, UINT256 금액) 공개 가상 재정의 반환 (bool) {_transfer (_msgsender (), 수신자, 금액); 진실을 반환하십시오. }/**
/**
spender 제로 주소가 될 수 없습니다. */ 함수 승인 (주소 Spender, UINT256 금액) 공개 가상 재정의 반환 (bool) {_ approve (_msgsender (), spender, umle); 진실을 반환하십시오. }/**
sender 와 recipient 제로 주소가 될 수 없습니다.sender 최소한 amount 의 잔액이 있어야합니다.sender 의 토큰에 대한 허용이 있어야합니다.amount . */ 기능 전송 (주소 발신자, 주소 수신자, UINT256 금액) 공개 가상 재정의 반환 (bool) {_transfer (발신자, 수신자, 금액); _ approve (sender, _msgsender (), _allowances [sender] [_ msgsender ()]. sub (금액, "ERC20 : 전송 금액은 허용량을 초과"); 진실을 반환하십시오. }/**
spender 에 부여한 수당을 원자 적으로 증가시킵니다.spender 제로 주소가 될 수 없습니다. */ 함수 증가 allowance (주소 Spender, UINT256 addevalue) public Virtual Returns (bool) {_ applove (_msgsender (), spender, _allowances [_msgsender ()] [spender] .add (addvalue)); 진실을 반환하십시오. }/**
spender 에 부여한 수당을 원자 적으로 감소시킵니다.spender 제로 주소가 될 수 없습니다.spender 적어도 발신자에게 수당이 있어야합니다.subtractedValue . */ 함수 감소 (주소 Spender, UINT256 SubtressedValue) public Virtual Returns (BOOL) {_Approve (_msgsender (), Spender, _allowances [_msgsender ()] [Spender] .sub (suptractedValue, "erc20 : Zerc20 감소"); 진실을 반환하십시오. }/**
@dev는 sender 에서 recipient 로 토큰 amount 이동합니다.
이것은 내부 기능이며 {송신}과 동일하며 사용될 수 있습니다.
예를 들어 자동 토큰 수수료, 슬래시 메커니즘 등을 구현하십시오.
{송신} 이벤트를 방출합니다.
요구 사항 :
sender 제로 주소가 될 수 없습니다.recipient 제로 주소가 될 수 없습니다.sender 최소한 amount 의 잔액이 있어야합니다. */ function _transfer (주소 발신자, 주소 수신자, UINT256 금액) 내부 virtual {require (sender! = address (0), "erc20 : 0 주소에서 전송"); 요구 (수신자! = 주소 (0), "ERC20 : 0 주소로 전송");_beforeTokentRansfer (발신자, 수신자, 금액);
_balances [sender] = _balances [sender] .sub (금액, "ERC20 : 전송 금액은 잔액을 초과한다"); _balances [수신자] = _balances [수신자] .add (금액); 전송 방출 (발신자, 수신자, 금액); }
/** @dev는 amount 토큰을 생성하여 account 에 할당하여 증가합니다.
총 공급.
세트 from 0 주소로 {송신} 이벤트를 방출합니다.
요구 사항
to 수 없습니다. */ function _MINT (주소 계정, UINT256 금액) 내부 가상 {require (계정! = 주소 (0), "erc20 : mint to the Zero 주소");_beforetokentRansfer (주소 (0), 계정, 금액);
_TOTALSUPPLY = _TOTALSUPPLY.ADD (금액); _balances [계정] = _balances [계정] .add (금액); 전송 방출 (주소 (0), 계정, 금액); }
/**
@dev는 account 에서 amount 토큰을 파괴하여 감소합니다
총 공급.
0 주소로 설정 to {송신} 이벤트를 제출합니다.
요구 사항
account 제로 주소가 될 수 없습니다.account 최소한 amount 이 있어야합니다. */ function _burn (주소 계정, UINT256 금액) 내부 가상 {require (requible! = address (0), "erc20 : 0 주소에서 연소");_beforetokentRansfer (계정, 주소 (0), 금액);
_balances [ac _TOTALSUPPLY = _TOTALSUPPLY.SUB (금액); 전송 방출 (계정, 주소 (0), 금액); }
/**
@dev는 amount owner 의 토큰보다 spender 의 허용으로 설정합니다.
이 내부 기능은 approve 과 동일하며 사용될 수 있습니다.
예를 들어 특정 서브 시스템 등에 대한 자동 허용량을 설정하십시오.
{승인} 이벤트를 방출합니다.
요구 사항 :
owner 제로 주소가 될 수 없습니다.spender 제로 주소가 될 수 없습니다. */ function _Approve (주소 소유자, 주소 Spender, UINT256 금액) 내부 가상 {require (소유자! = 주소 (0), "erc20 : 0 주소에서 승인"); 요구 사항 (Spender! = 주소 (0), "ERC20 : 0 주소로 승인");_allowances [소유자] [Spender] = 금액; 승인 방출 (소유자, 첨탑, 금액); }
/**
/**
to from 나온 amount '의 토큰 fromto 로 옮길 것입니다.from 0이면 amount 토큰이 to 됩니다.to , ' from 토큰의 amount 태워집니다.to from 결코 0이 아닙니다.// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
@dev이 계약은 스냅 샷 메커니즘으로 ERC20 토큰을 확장합니다. 스냅 샷이 만들어지면 잔액이 있습니다
당시의 총 공급은 나중에 액세스 할 수 있도록 기록됩니다.
이것은 신뢰할 수없는 배당금 또는 가중 투표와 같은 토큰 잔액을 기반으로 메커니즘을 안전하게 만드는 데 사용될 수 있습니다.
순진한 구현에서는 다른 잔액을 다른 잔액을 재사용하여 "이중 지출"공격을 수행 할 수 있습니다.
계정. 스냅 샷을 사용하여 배당금 또는 투표권을 계산함으로써 이러한 공격은 더 이상 적용되지 않습니다. 또한 가능합니다
효율적인 ERC20 포킹 메커니즘을 만드는 데 사용됩니다.
스냅 샷은 내부 {_snapshot} 함수에 의해 생성되며 {snapshot} 이벤트를 방출하고 a를 반환합니다.
스냅 샷 ID. 스냅 샷시 총 공급을 얻으려면 스냅 샷으로 함수 {TotalSupplyat}을 호출하십시오.
ID. 스냅 샷시 계정의 잔액을 얻으려면 스냅 샷 ID로 {balanceofat} 함수를 호출하십시오.
그리고 계정 주소.
==== 가스 비용
스냅 샷은 효율적입니다. 스냅 샷 생성은 O (1) 입니다. 스냅 샷에서 잔액 검색 또는 총 공급은 _o입니다 (로그
n) _ 생성 된 스냅 샷 수에서 특정 계정의 경우 N은 일반적으로 크지 만
후속 스냅 샷에서 동일한 균형이 단일 항목으로 저장되므로 더 작습니다.
추가 스냅 샷 부기로 인해 일반 ERC20 전송에 대한 지속적인 오버 헤드가 있습니다. 이 오버 헤드입니다
특정 계정에 대한 스냅 샷을 즉시 따르는 첫 번째 전송에만 중요합니다. 후속
전송은 다음 스냅 샷까지 정상적인 비용을받습니다. */Abstract 계약 ERC20SNAPSHOT는 ERC20 {// Jordi Baylina의 Minimetoken에서 영감을 받아 역사적 잔액을 기록합니다 : // https://github.com/giveth/minimd/blob/ea04d950eea153a04c51fa510b9dddded390cb/contracts/mintocts/mintacts/mintracts/mintracts/Mintracts/Mintracts/Mintracts/Mintracts/Mintracts/Mintracts.
UINT256의 SAFEMATH 사용; UINT256 []에 배열 사용; 카운터에 카운터 사용;
// Snapshotted 값에는 ID 배열과 해당 ID에 해당하는 값이 있습니다. 이것들은 // snapshot struct의 배열 일 수 있지만 배열에서 작동하는 함수 사용을 방해합니다. 구조 스냅 샷 {uint256 [] ids; UINT256 [] 값; }
매핑 (주소 => 스냅 샷) private _accountbalancesnapshots; 스냅 샷 개인 _totalSupplySnapShots;
// 스냅 샷 ID는 단조로 증가하며 첫 번째 값은 1입니다. 0의 ID는 유효하지 않습니다. COUNTERS.COUNTER PRIVATE _CURRENTSNAPSHOTID;
/**
id 로 식별 된 스냅 샷이 생성 될 때 {_snapShot}에 의해 방출됩니다. */ 이벤트 스냅 샷 (UINT256 ID);/**
@dev는 새 스냅 샷을 생성하고 스냅 샷 ID를 반환합니다.
동일한 ID가 포함 된 {snapshot} 이벤트를 방출합니다.
{_snapShot}은 internal 이므로 외부에서 노출하는 방법을 결정해야합니다. 사용량은 a로 제한 될 수 있습니다
예를 들어 {accesscontrol}을 사용하는 것과 같은 계정 세트 또는 대중에게 공개 될 수 있습니다.
[경고]
====
포킹과 같은 특정 신뢰 최소화 메커니즘에는 {_snapshot}을 호출하는 열린 방법이 필요하지만
공격자가 두 가지 방법으로 사용할 수 있다고 생각해야합니다.
먼저, 스냅 샷에서 값 검색 비용을 늘리는 데 사용될 수 있지만 증가 할 수 있습니다.
따라서 로그는이 공격을 장기적으로 비효율적으로 렌더링합니다. 둘째, 타겟팅하는 데 사용될 수 있습니다
가스 비용에 명시된 방식으로 특정 계정 및 ERC20 이전 비용 증가
위의 섹션.
우리는 실제 숫자를 측정하지 않았습니다. 이것이 관심있는 것이라면 우리에게 연락하십시오.
==== */ function _snapShot () 내부 가상 반환 (uint256) {_currentsnapshotid.increment ();
uint256 currentId = _currentsNapShotId.current (); 스냅 샷을 방출합니다 (currentID); CurrentId 리턴; }
/**
@dev는 snapshotId 생성 될 때 account 잔액을 검색합니다. */ function balancefat (주소 계정, UINT256 SnapShotID) 공개보기 (UINT256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _accountbalancesnapshots [account]);
반환 스냅 샷? 값 : Balanceof (계정); }
/**
@dev는 snapshotId 생성 된 시점의 총 공급을 검색합니다. */ function totalsUpplyat (uint256 snapshotid) public view returns (uint256) {(bool snapshotted, uint256 value) = _valueat (snapshotid, _totalsupplysnapshots);
반환 스냅 샷? 값 : TotalSupply (); }
// 값이 수정되기 전에 균형 및/또는 총 공급 스냅 샷을 업데이트합니다. _beforetokentransfer 후크에서 // _Mint, _burn 및 _transfer 작업에 대해 실행됩니다. 함수 _beforeTokentRansfer (주소로부터 주소, UINT256 금액) 내부 가상 재정의 {super._beforetokentRansfer (from, to, toms);
if (from == address (0)) {// mint _updateaccountsnapShot (to); _updateToTalSupplySnapShot (); } else if (to == address (0)) {// burn _updateAccountsnapShot (from); _updateToTalSupplySnapShot (); } else {// 전송 _UPDATEACCOUNTSSNAPSHOT (from); _updateAccountsnapShot (to); }}
function _valueat (UINT256 SnapshotID, Snapshots 스토리지 스냅 샷) 비공개 뷰 리턴 (bool, uint256) {require (snapshotid> 0, "erc20snapshot : id is 0"); // solhint-disable-next-line max-line-length request (snapshotid <= _currentsnapshotid.current (), "erc20snapshot : nonexistent 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]);
}
}
함수 _UPDATEACCOUNTSSNAPSHOT (주소 계정) private {_updatesNapShot (_accountBalancesNapShots [계정], balanceof (계정)); }
함수 _UPDATETALSUPPLYSNAPSHOT () 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); }}
함수 _LASTSNAPSHOTID (UINT256 [] Storage IDS) 개인보기 리턴 (UINT256) {if (ids.length == 0) {return 0; } else {return ids [ids.length -1]; }}}
// 부분 라이센스 : MIT
Pragma Solidity ^0.6.0;
/**
관리를위한 @dev 라이브러리
https://en.wikipedia.org/wiki/set_(ABSTRANT_DATA_TYPE)의 Primitive
유형.
세트에는 다음 속성이 있습니다.
(O (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 값의 일반적인 세트 유형으로 작성합니다. // 구현 세트는 개인 기능을 사용하고 사용자를 향한 // 구현 (예 : 주소 세트)은 // 기본 세트 주위의 래퍼 일뿐입니다. // 이것은 BYTES32에서 //에 맞는 유형에 대해서만 새로운 열거 자리를 만들 수 있음을 의미합니다.
struct 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는 세트에서 값을 제거합니다. o (1).
값이 세트에서 제거되면 true를 반환합니다.
현재의. */ function _REMOVE (Set Storage Set, Bytes32 value) private returns (bool) {// 값의 색인을 읽고 저장하여 동일한 스토리지 슬롯 UINT256 ValueIndex = set._indexes [value]에서 다중 판독 값을 방지합니다.
if (valueIndex! = 0) {// acture (set, value) // O (1)의 _Values 배열에서 요소를 삭제하려면 // 배열에서 마지막 요소와 함께 삭제 한 다음 마지막 요소를 제거합니다 (때때로 '스왑 및 POP'). // {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 에 저장된 값을 반환합니다. o (1).index 엄격하게 {길이}보다 작아야합니다. */ function _AT (Set Storage Set, UINT256 INDEX) 개인보기 리턴 (BYTES32) {요구 사항 (set._Values.length> index, "enumerableset : index of bounds"); return set._values [index]; }// 주소 세트
구조 주소 세트 {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 . 사용할 수 있습니다/**
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();
}
}