솔리디티 리믹스 환경에서 토큰 발행하는 방법
아래 사이트에 접속한다.
Solidity Remix - Ehtereum IDE
https://remix.polkadot.io/
Remix - Ethereum IDE
remix.polkadot.io

Create new file 을 눌러 .sol 파일을 생성한다.
아래 코드를 복붙 (solidity 0.8.7 버전 기준으로 작성)
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;
// ----------------------------------------------------------------------------
// ThsisNo token contract
//
// Symbol : TNO
// Name : ThsisNo Token
// Total supply : 100000
// Decimals : 2
// Owner Account : 0x03331
//
// Enjoy.
//
// (c) by Idea thsisno 2026. DM Licence.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// ----------------------------------------------------------------------------
interface ERC20Interface {
function totalSupply() external view returns (uint);
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
function transferFrom(address from, address to, uint tokens) external returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// ----------------------------------------------------------------------------
// ERC20 Token
// ----------------------------------------------------------------------------
contract INVENToken is ERC20Interface {
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
constructor() {
symbol = "ASC";
name = "AssetChain Token";
decimals = 2;
_totalSupply = 100000;
balances[0x03331] = _totalSupply;
emit Transfer(address(0), 0x03331, _totalSupply);
}
// ------------------------------------------------------------------------
// Total supply
// ------------------------------------------------------------------------
function totalSupply() public view override returns (uint) {
return _totalSupply - balances[address(0)];
}
// ------------------------------------------------------------------------
// Get the token balance for account tokenOwner
// ------------------------------------------------------------------------
function balanceOf(address tokenOwner) public view override returns (uint balance) {
return balances[tokenOwner];
}
// ------------------------------------------------------------------------
// Transfer the balance from token owner's account to to account
// ------------------------------------------------------------------------
function transfer(address to, uint tokens) public override returns (bool success) {
require(balances[msg.sender] >= tokens, "Insufficient balance");
balances[msg.sender] -= tokens;
balances[to] += tokens;
emit Transfer(msg.sender, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Approve spender to spend tokens from token owner's account
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public override returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
// ------------------------------------------------------------------------
// Transfer tokens from one account to another using allowance
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public override returns (bool success) {
require(balances[from] >= tokens, "Insufficient balance");
require(allowed[from][msg.sender] >= tokens, "Allowance exceeded");
balances[from] -= tokens;
allowed[from][msg.sender] -= tokens;
balances[to] += tokens;
emit Transfer(from, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Returns the amount of tokens approved by the owner for the spender
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public view override returns (uint remaining) {
return allowed[tokenOwner][spender];
}
// ------------------------------------------------------------------------
// Don't accept ETH
// ------------------------------------------------------------------------
fallback() external payable {
revert();
}
receive() external payable {
revert();
}
}
이건 transfer, mint, burn 이 사용된 코드
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;
// ----------------------------------------------------------------------------
// AssetChain token contract
// ----------------------------------------------------------------------------
interface ERC20Interface {
function totalSupply() external view returns (uint);
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
function transferFrom(address from, address to, uint tokens) external returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// ----------------------------------------------------------------------------
// ERC20 Token with Mint & Burn
// ----------------------------------------------------------------------------
contract INVENToken is ERC20Interface {
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;
address public owner;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
modifier onlyOwner() {
require(msg.sender == owner, "Only owner");
_;
}
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
constructor() {
symbol = "ATC";
name = "AssetChain Token";
decimals = 2;
owner = msg.sender;
_mint(owner, 100000);
}
// ------------------------------------------------------------------------
// Total supply
// ------------------------------------------------------------------------
function totalSupply() public view override returns (uint) {
return _totalSupply;
}
// ------------------------------------------------------------------------
// Balance
// ------------------------------------------------------------------------
function balanceOf(address tokenOwner) public view override returns (uint balance) {
return balances[tokenOwner];
}
// ------------------------------------------------------------------------
// transfer
// ------------------------------------------------------------------------
function transfer(address to, uint tokens) public override returns (bool success) {
require(balances[msg.sender] >= tokens, "Insufficient balance");
balances[msg.sender] -= tokens;
balances[to] += tokens;
emit Transfer(msg.sender, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Approve
// ------------------------------------------------------------------------
function approve(address spender, uint tokens) public override returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
// ------------------------------------------------------------------------
// transferFrom
// ------------------------------------------------------------------------
function transferFrom(address from, address to, uint tokens) public override returns (bool success) {
require(balances[from] >= tokens, "Insufficient balance");
require(allowed[from][msg.sender] >= tokens, "Allowance exceeded");
balances[from] -= tokens;
allowed[from][msg.sender] -= tokens;
balances[to] += tokens;
emit Transfer(from, to, tokens);
return true;
}
// ------------------------------------------------------------------------
// Allowance
// ------------------------------------------------------------------------
function allowance(address tokenOwner, address spender) public view override returns (uint remaining) {
return allowed[tokenOwner][spender];
}
// ------------------------------------------------------------------------
// mint
// ------------------------------------------------------------------------
function mint(address to, uint amount) public onlyOwner {
_mint(to, amount);
}
function _mint(address to, uint amount) internal {
_totalSupply += amount;
balances[to] += amount;
emit Transfer(address(0), to, amount);
}
// ------------------------------------------------------------------------
// burn
// ------------------------------------------------------------------------
function burn(uint amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
_totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
}
첫 번째 코드의 Owner Account 부분은 메타마스크 지갑에서 테스트넷 네트워크 주소를 복사해서 자신의 지갑 주소로 바꾸면 된다.
https://metamask.io/ko
MetaMask: 최고의 암호화폐 지갑 플랫폼, 블록체인 지갑
암호화폐 지갑을 설정하고 웹3의 모든 기능을 이용하하여 데이터, 자산, 디지털 정체성까지 완전한 제어를 즐기세요. 1억 명 이상의 사용자가 선택한 웹3 지갑입니다.
metamask.io
Westend 테스트넷 토큰을 받아둔 게 있어서 Westend 사용


코드 작성이 완료되었으면 사이드 3번째 컴파일로 이동해 Compile 파일명.sol 을 클릭해 컴파일한다.


컴파일이 정상적으로 완료되면 화살표가 체크 표시로 바뀌게 된다.
컴파일 아래에 있는 Deploy로 이동한다.

ENVIROMENT에서 메타마스크 지갑을 연결한다.
CONTRACT는 INVENTToken - 파일명.sol 을 선택한다.
그리고 Deploy

컨펌 클릭해서 진행



배포가 완료되었다.
이제 토큰의 주소를 복사해야 한다.
Debug 옆의 아래 화살표를 클릭해 contract address를 복사하거나, Deployed/Unpinned Contracts에서 복사 버튼을 누르면 된다.

메타마스크로 돌아가 토큰 가져오기를 통해 주소를 불러오면 나의 토큰의 메타마스크에 등록된다.


트랜잭션이나 주소는 여기서 검색 가능
https://blockscout-asset-hub.parity-chains-scw.parity.io/