# 简单代币合约

写在前面:

    1. 哪个用户创建合约,哪个用户就是 senter 默认 from 值
    1. 货币发行之初,minter 也是没钱的,需要 mint 挖矿划转钱过去
    1. send 是从 minter 发送到 receiver 里的
    1. 合约的货币和测试链上的货币不一样,测试的货币有钱,不等于子货币有钱

# 子货币

// SPDX-License-Identifier: MIT
pragma solidity >0.4.22 <0.6.0;
contract Coin {
  address public minter;
  mapping(address=>uint) public balances;
  event Sent(address from, address to, uint amount);
  // minter 发合约的账户
  constructor() public {minter = msg.sender;}
  function mint(address receiver,  uint amount)  public{
    // 现在调用mint的人是原来定好的minter
    require(msg.sender == minter);
    balances[receiver]+=amount;
  }
  function send(address  receiver, uint amount) public{
    require(amount<=balances[msg.sender]);
    balances[msg.sender] -= amount; // unit258 有上限和下限
    balances[receiver] += amount;
    // 调用发布事件 Sent
    emit Sent(msg.sender, receiver, amount);
  }
}

# 代码解读

# address public minter;

  • 这行声明了一个可以被公开访问的 address 类型的状态变量
  • 关键字public自动生成一个函数,允许你在这个合约之外访问这个状态变量的当前值

# mapping(address=>uint) public balances;

  • 也创建一个公共状态变量,但它是一个更复杂的数据类型,该类型将 address 映射为无符号整数
  • mappings可以看作是一个hash 表,它会执行虚拟初始化,把所有可能存在的键都映射到一个字节表示为全零的值

# event Sent(address from, address to, uint amount);

  • 声明了一个“事件”(event),他会在 send 函数的最后一行触发
  • 用户可以监听区块链上正在发生的事件,而不会花费太多成本,一旦它被发出,监听该事件的 listener 都将收到通知
  • 所有的事件都包含了from, toamount三个参数,可以方便追踪事务

# emit Sent(msg.sender, receiver, amount);

emit(4.21 没有 emit)

  • 触发 Sent 事件,并将参数传入

# 事件监听

Coin.Sent().watch({}, "", function (err, res) {
  if (!err) {
    console.log("Coin transfer:  " + res.args.amount);
    console.log("coins were sent from:  " + res.args.from);
    console.log("to: " + res.args.to);
    console.log(
      "Balances now: \n" +
        "Sender: " +
        Coin.balances.call(res.args.from) +
        "\n" +
        "Receiver: " +
        Coin.balances.call(result.arg.to)
    );
  }
});

# 代码优化

上面的代币都是由mint发放,总量不确定

// SPDX-License-Identifier: MIT
pragma solidity >0.4.22 <0.6.0;
contract Coin {
  mapping(address=>uint)  public balances;
  constructor(uint initalSupply) public{
    balances[msg.sender] = initalSupply;
  }
  function send(address receiver, uint amount) public returns (bool success) {
    // 做减法不会溢出
    require(balances[msg.sender]>=amount);
    // 做加法不会溢出
    require(balances[receiver] + amount >= balances[receiver]);
    balances[msg.sender] -= amount;
    balances[receiver] += amount;
    return true;
  }
}

#

浮点型容易缺失精度缺失
allowance; // 允许别人用你的名义划转
indexed 一个事件的检索
Approval 谁拥有授权 谁给他的授权 有多少 value
Burn 销毁机制
**乘方