How do I include a burn function to this ERC20 token Solidity code?

pragma solidity ^0.5.0 < 0.6.0;

// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
//
// ----------------------------------------------------------------------------
contract ERC20Interface {
    function totalSupply() public view returns (uint);
    function balanceOf(address tokenOwner) public view returns (uint balance);
    function allowance(address tokenOwner, address spender) public view returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

// ----------------------------------------------------------------------------
// Safe Math Library 
// ----------------------------------------------------------------------------
contract SafeMath {
    function safeAdd(uint a, uint b) public pure returns (uint c) {
        c = a + b;
        require(c >= a);
    }
    function safeSub(uint a, uint b) public pure returns (uint c) {
        require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0);
        c = a / b;
    }
}


contract LeadToken is ERC20Interface, SafeMath {
    string public name;
    string public symbol;
    uint8 public decimals; // 18 decimals is the strongly suggested default, avoid changing it
    
    uint256 public _totalSupply;
    
    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;
    
    /**
     * Constrctor function
     *
     * Initializes contract with initial supply tokens to the creator of the contract
     */
    constructor() public {
        name = "LeadToken";
        symbol = "LEAD";
        decimals = 18;
        _totalSupply = 1000000000000000000000000000;
        
        balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }
    
    function totalSupply() public view returns (uint) {
        return _totalSupply  - balances[address(0)];
    }
    
    function balanceOf(address tokenOwner) public view returns (uint balance) {
        return balances[tokenOwner];
    }
    
    function allowance(address tokenOwner, address spender) public view returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }
    
    function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }
    
    function transfer(address to, uint tokens) public returns (bool success) {
        balances[msg.sender] = safeSub(balances[msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }
    
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = safeSub(balances[from], tokens);
        allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        emit Transfer(from, to, tokens);
        return true;
    }
}
1 Like

I would really appreciate it if some one here can help me implement a burn function to the code.

1 Like

Hi @cryptcode,

You may want to change to use the OpenZeppelin Contracts ERC20 implementation for your ERC20 token as so far your token is straight forward.

SimpleToken.sol

The following is a simple ERC20 token.

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleToken is ERC20, ERC20Detailed {

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
        _mint(msg.sender, 10000 * (10 ** uint256(decimals())));
    }
}

SimpleBurnableToken.sol

To change to make SimpleToken burnable, we can just inherit from ERC20Burnable

pragma solidity ^0.5.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol";

/**
 * @title SimpleBurnableToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleBurnableToken is ERC20, ERC20Detailed, ERC20Burnable {

    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
        _mint(msg.sender, 10000 * (10 ** uint256(decimals())));
    }
}

Deploy

We can deploy the token using OpenZeppelin CLI 2.8: Release Candidate (npm i @openzeppelin/cli@rc) and deploy as a regular contract (to make it upgradeable we would need to inherit from @openzeppelin/contracts-ethereum-package)

$ npx oz deploy
✓ Compiled contracts with solc 0.5.16 (commit.9c3226ce)
? Choose the kind of deployment regular
? Pick a network development
? Pick a contract to deploy SimpleBurnableToken
✓ Deployed instance of SimpleBurnableToken
0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab

Check total supply

$ npx oz call
? Pick a network development
? Pick an instance SimpleBurnableToken at 0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab
? Select which function totalSupply()
✓ Method 'totalSupply()' returned: 10000000000000000000000
10000000000000000000000

Burn

Burn from the current account.

$ npx oz send-tx
? Pick a network development
? Pick an instance SimpleBurnableToken at 0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab
? Select which function burn(amount: uint256)
? amount: uint256: 10000000000000000000

----

Let me know if you have any questions.
✓ Transaction successful. Transaction hash: 0xd9a85bc729a747aae0a164e9dda9c98eb40141003056505e8c6e7b51c5dd1838
Events emitted:
 - Transfer(0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1, 0x0000000000000000000000000000000000000000, 10000000000000000000)

Check total supply (after burning)

$ npx oz call
? Pick a network development
? Pick an instance SimpleBurnableToken at 0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab
? Select which function totalSupply()
✓ Method 'totalSupply()' returned: 9990000000000000000000
9990000000000000000000

Hi @cryptcode,

Checking to see if the above example answered your question?