decert.me挑战 ERC20

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;


contract BaseERC20 {
    string public name; 
    string public symbol; 
    uint8 public decimals; 

    uint256 public totalSupply; 

    mapping (address => uint256) balances; 

    mapping (address => mapping (address => uint256)) allowances; 

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor() public {
        // write your code here
        // set name,symbol,decimals,totalSupply
        name="BaseERC20";
        symbol="BERC20";
        decimals=18;
        totalSupply=100000000*(10**uint256(18));


        balances[msg.sender] = totalSupply;  
    }

    function balanceOf(address _owner) public view returns (uint256 balance) {
        // write your code here
        return balances[_owner];

    }

    function transfer(address _to, uint256 _value) public returns (bool success) {
        // write your code here
        require(balances[msg.sender]>=_value,"ERC20: transfer amount exceeds balance");
        balances[msg.sender]-=_value;
        balances[_to]+=_value;
        emit Transfer(msg.sender, _to, _value);  
        return true;   
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        // write your code here
        require(balances[_from]>=_value,"ERC20: transfer amount exceeds balance");
        require(allowances[_from][msg.sender]>=_value,"ERC20: transfer amount exceeds allowance");
        allowances[_from][msg.sender]-=_value;
        balances[_from]-=_value;
        balances[_to]+=_value;
        emit Transfer(_from, _to, _value); 
        return true; 
    }

    function approve(address _spender, uint256 _value) public returns (bool success) {
        // write your code here
        allowances[msg.sender][_spender]=_value;
        emit Approval(msg.sender, _spender, _value); 
        return true; 
    }

    function allowance(address _owner, address _spender) public view returns (uint256 remaining) {   
        // write your code here     
        return allowances[_owner][_spender];
    }
}

ERC20的难点我觉得主要在于transferFrom这个函数。看openzeppelin的官方实现,transferFrom这个函数被msg.sender调用,用于_from给_to转账。也就是说,msg.sender可以用_from给msg.sender的额度,给_to转账。一开始我以为这个是扣_to的额度,但并不是的,扣的是调用者msg.sender的额度。简单来说,就是msg.sender可以使用_from给自己的额度,然后给任意一个地址(_to)转账。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值