OwnerHelper
관리자만 사용할 수 있는 함수가 필요
특정 함수를 관리자만 사용할 수 있도록 설정하는 OwnerHelper 함수를 구현
OwnerHelper를 사용하여 public으로 공개되어 있는 함수 중, 관리자만 접근 가능한 함수 구현
Interface 부분 추가
abstract contract OwnerHelper {
address private _owner;
event OwnershipTransferred(address indexed preOwner, address indexed nextOwner);
modifier onlyOwner {
require(msg.sender == _owner, "OwnerHelper: caller is not owner");
_;
}
constructor() {
_owner = msg.sender;
}
function owner() public view virtual returns (address) {
return _owner;
}
function transferOwnership(address newOwner) onlyOwner public {
require(newOwner != _owner);
require(newOwner != address(0x0));
address preOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(preOwner, newOwner);
}
OwnerHelper 컨트랙트는 abstract contract라고 하는 추상 컨트랙트이다
abstract contract는 contract의 구현된 기능과 interface의 추상화 기능 모두를 포함한다
abstract contract는 만약 실제 contract에서 사용하지 않는다면 추상으로 표시되어 사용되지 않는다
_owner는 관리자를 나타낸다.
address private _owner;
OwnershipTransferred이벤트는 관리자가 변경되었을때 이전 관리자의 주소와 새로운 관리자의 주소 로그를 남긴다
event OwnershipTransferred(address indexed preOwner, address indexed nextOwner);
onlyOwner 함수 변경자는 함수 실행 이전에 함수를 실행시키는 사람이 관리자인지 확인
modifier onlyOwner {
require(msg.sender == _owner, "OwnerHelper: caller is not owner");
_;
}
메인컨트렉트 수정
contract SimpleToken is ERC20Interface, OwnerHelper {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) public _allowances;
uint256 public _totalSupply;
string public _name;
string public _symbol;
uint8 public _decimals;
bool public _tokenLock;
mapping (address => bool) public _personalTokenLock;
constructor(string memory getName, string memory getSymbol) {
_name = getName;
_symbol = getSymbol;
_decimals = 18;
_totalSupply = 100000000e18;
_balances[msg.sender] = _totalSupply;
_tokenLock = true;
}
........
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(isTokenLock(sender, recipient) == false, "TokenLock: invalid token transfer");
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance.sub(amount);
_balances[recipient] = _balances[recipient].add(amount);
}
function isTokenLock(address from, address to) public view returns (bool lock) {
lock = false;
if(_tokenLock == true)
{
lock = true;
}
if(_personalTokenLock[from] == true || _personalTokenLock[to] == true) {
lock = true;
}
}
// 다음의 코드에서 함수로 전달되는 파라미터 브라켓 뒤에 오는 onlyOwner가 예시입니다.
function removeTokenLock() onlyOwner public {
require(_tokenLock == true);
_tokenLock = false;
}
// 다음의 코드에서 함수로 전달되는 파라미터 브라켓 뒤에 오는 onlyOwner가 예시입니다.
function removePersonalTokenLock(address _who) onlyOwner public {
require(_personalTokenLock[_who] == true);
_personalTokenLock[_who] = false;
}
}
TokenLock
isTokenLock
bool public _tokenLock;
mapping (address => bool) public _personalTokenLock;
constructor(string memory getName, string memory getSymbol) {
// ~~
_tokenLock = true;
}
function isTokenLock(address from, address to) public view returns (bool lock) {
lock = false;
if(_tokenLock == true)
{
lock = true;
}
if(_personalTokenLock[from] == true || _personalTokenLock[to] == true) {
lock = true;
}
}
tokenLock은 토큰의 전체 락에 대한 처리, tokenPersonalLock은 토큰의 개인 락에 대한 처리
함수 isTokenLock은 전체 락과, 보내는 사람의 락, 받는 사람의 락을 검사하여 락이 걸려 있는지 확인
_transfer에 락 검사하기
_transfer에 검사를 추가해, 보내는 사람과 받는 사람 중 락이 걸려있다면 토큰은 이동이 불가
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(isTokenLock(sender, recipient) == false, "TokenLock: invalid token transfer");
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance.sub(amount);
_balances[recipient] = _balances[recipient].add(amount);
}
락들을 제거 할 수 있는 removeTokenLock과 removePersonalTokenLock도 존재
해당 함수들은 onlyOwner를 적용하여 관리자만 락을 해제할 수 있도록 해야 한다.
락을 적용하게 되면 모든 락을 해제할 때만 토큰의 이동이 가능
function removeTokenLock() onlyOwner public {
require(_tokenLock == true);
_tokenLock = false;
}
function removePersonalTokenLock(address _who) onlyOwner public {
require(_personalTokenLock[_who] == true);
_personalTokenLock[_who] = false;
}
다음 블로깅에 블로깅한 기능들을 조합하여 전체 코드를 조합해보자
'솔리디티' 카테고리의 다른 글
call vs delegate call 알아보기 (0) | 2023.01.04 |
---|---|
솔리디티 Erc-20 토큰 기본 전문 (0) | 2022.02.04 |
솔리디티 SafeMath 이해하기 (0) | 2022.02.04 |
솔리디티 ERC-20 인터페이스와 구현 (0) | 2022.02.04 |
솔리디티 이해하기 기초-2 (0) | 2022.02.04 |
댓글