Token Example¶
A complete ERC20-style token implementation.
Contract¶
contract Token {
string public name;
string public symbol;
uint8 public decimals = 9;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
address public owner;
bool public paused;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Paused(address account);
event Unpaused(address account);
error InsufficientBalance(uint256 available, uint256 required);
error InsufficientAllowance(uint256 available, uint256 required);
error ContractPaused();
error Unauthorized();
modifier onlyOwner() {
if (msg.sender != owner) revert Unauthorized();
_;
}
modifier whenNotPaused() {
if (paused) revert ContractPaused();
_;
}
constructor(string memory _name, string memory _symbol, uint256 _initialSupply) {
name = _name;
symbol = _symbol;
owner = msg.sender;
_mint(msg.sender, _initialSupply);
}
function transfer(address to, uint256 amount) public whenNotPaused returns (bool) {
_transfer(msg.sender, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public whenNotPaused returns (bool) {
uint256 currentAllowance = allowance[from][msg.sender];
if (currentAllowance < amount) {
revert InsufficientAllowance(currentAllowance, amount);
}
allowance[from][msg.sender] = currentAllowance - amount;
_transfer(from, to, amount);
return true;
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
function burn(uint256 amount) public {
if (balanceOf[msg.sender] < amount) {
revert InsufficientBalance(balanceOf[msg.sender], amount);
}
balanceOf[msg.sender] -= amount;
totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
function pause() public onlyOwner {
paused = true;
emit Paused(msg.sender);
}
function unpause() public onlyOwner {
paused = false;
emit Unpaused(msg.sender);
}
function _transfer(address from, address to, uint256 amount) internal {
require(to != address(0), "Invalid recipient");
if (balanceOf[from] < amount) {
revert InsufficientBalance(balanceOf[from], amount);
}
balanceOf[from] -= amount;
balanceOf[to] += amount;
emit Transfer(from, to, amount);
}
function _mint(address to, uint256 amount) internal {
require(to != address(0), "Invalid recipient");
totalSupply += amount;
balanceOf[to] += amount;
emit Transfer(address(0), to, amount);
}
}
Build¶
Deploy¶
Key Features¶
- Transfers: Standard transfer and transferFrom
- Approvals: Allowance system for delegated transfers
- Minting: Owner can mint new tokens
- Burning: Users can burn their tokens
- Pausable: Owner can pause transfers