代币是以太坊这类通用编程区块链之上最显著和有用的应用形态。
6个函数、2个事件
// 获取系统金额发行量
function totalSupply() virtual public view returns (uint totalSupply);
// 获取_owner余额
function balanceOf(address _owner) virtual public view returns (uint balance);
// 调用者(msg.sender)向 _t0 转账 _value
function transfer(address _to, uint256 _value) virtual public returns (bool success);
// 下面两个函数通常一起使用
// 2、授权后,被授权的人调用此函数,相当于手动取钱! 与transfer的区别在于 一个是甲方直接给你钱,一个是甲方授权,乙方自己取钱。
function transferFrom(address _from, address _to, uint256 _value) virtual public returns (bool success);
// 1、用于授权,msg.sender 授权给 _spender 可以动用 _value
function approve(address _spender, uint256 _value) virtual public returns (bool success);
// 查看_owner 授权给 _spender 的余额数量
function allowance(address _owner, address _spender) virtual public view returns (uint remaining);
// 转账事件,每次发生转账交易后触发事件让别人知道
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// 授权事件,每次发生一个地址给另一个地址授权后触发事件让别人知道
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
代币的名称
function name() virtual public view returns (string calldata);
代币的代号、标识,通常为字母缩写
function symbol() virtual public view returns (string calldata);
返回令牌使用的小数位数 - 例如"8",意味着将令牌量除以"100000000"以获取其用户的表示形式。
function decimals() virtual public view returns (uint8);
1、合约contract 关键字之前需要加上abstract修饰
2、在抽象的函数内,添加virtual关键字
3、在继承函数时,需要对继承的函数名中加上override修饰符


ERC20.sol合约:
pragma solidity ^0.6.0;
abstract contract ERC20 {
// function name() public view returns (string)
// function symbol() public view returns (string)
// function decimals() public view returns (uint8)
function totalSupply() virtual public view returns (uint totalSupply);
function balanceOf(address _owner) virtual public view returns (uint balance);
function transfer(address _to, uint256 _value) virtual public returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) virtual public returns (bool success);
function approve(address _spender, uint256 _value) virtual public returns (bool success);
function allowance(address _owner, address _spender) virtual public view returns (uint remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
pcCoin.sol合约 继承自 ERC20
pragma solidity ^0.6.0;
import "./ERC20.sol";
contract pcCoin is ERC20{
uint256 _totalSupply; // 总供应量
address public _owner; // 部署合约的人
mapping(address=>uint256) _balances; // address的余额
mapping(address=>mapping(address=>uint256)) _approves; // a授权给b多少余额
// 转账事件,转过之后让人能看到
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// 授权事件,授权之后让人能看到
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
constructor(uint256 totalSupply) public {
_owner = msg.sender; // _owner初始化为部署合约的人
_totalSupply = totalSupply;
}
// 设置权限
modifier onlyOwner(){
require(msg.sender == _owner);
_;
}
//给指定账户投钱,只有部署合约的人有这个权限
function airDrop(address _to, uint256 _value) onlyOwner public {
require(_to != address(0) && _value > 0);
_balances[_to] = _value;
_totalSupply += _value;
}
// 返回总供应量
function totalSupply() override public view returns(uint totalSupply){
totalSupply = _totalSupply;
return totalSupply;
}
function balanceOf(address _owner) override public view returns(uint balance){
require(_owner != address(0), "owner should not be empty! ");
return _balances[_owner];
}
function transfer(address _to, uint256 _value) override public returns (bool success){
require(_to != address(0), "_to should not be empty !");
require(_balances[msg.sender] >= _value && _value>0, "value should be valid !!");
_balances[msg.sender] -= _value;
_balances[_to] += _value;
success = true;
emit Transfer(msg.sender, _to, _value);
return success;
}
// 被授权者来调用此函数,可理解为自己取钱,_from是授权的人
function transferFrom(address _from, address _to, uint256 _value) override public returns (bool success){
require(_from != address(0) && _to != address(0));
require(_approves[_from][msg.sender] >= _value); // _from 授权给 msg.sender 的钱必须大于 _value
_approves[_from][msg.sender] -= _value; // 取了钱后,_from 授权给 msg.sender 的钱就要减少
_balances[_to] += _value;
success = true;
emit Transfer(_from, _to, _value);
return success;
}
// 调用此函数,意为调用者(msg.sender)授权给_spender多少可动的钱
function approve(address _spender, uint256 _value) override public returns (bool success){
require(_spender != address(0));
require(_balances[msg.sender] >= _value && _value > 0);
_approves[msg.sender][_spender] += _value; // 授权
_balances[msg.sender] -= _value;
success = true;
emit Approval(msg.sender, _spender, _value);
return success;
}
function allowance(address _owner, address _spender) override public view returns (uint remaining){
return _approves[_owner][_spender];
}
}
部署到区块链网络(我部署的是私有链ganache网络)

下面可以调函数
