The ERC20 standard does not specify the mint and burn mechanisms, it is therefore up to the developer to define them.
The OpenZeppelin ERC20 reference implementation implements a burn function that decreases both the account balance and the token total supply :
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
The account balance and the total supply are respectively decremented with _balances[account] = accountBalance - amount; and _totalSupply -= amount;.
Although the event Transfer assimilates the burn operation to a transfer to the zero address, this is not the case, and this event is purely conventional.
This _burn function is internal and therefore can only be called within the smart contract and derived contracts. It is up to the developer to decide how to use this feature, if necessary. For example, to allow users to burn their token, you could create a public burn function wrapping the subfunction :
function burn(uint256 amount) public {
_burn(msg.sender, amount)
}
Regarding the zero address, it is true that you can burn tokens by transferring them directly to it. However, the tokens will not be destroyed and the total supply will remain the same. So we can say that may be using the burn function is more appropriate, although no one can prevent a user from sending and forever locking tokens at addresses 0x0 (OpenZeppelin does for this one but this is not required by the standard) or 0x1 for example.
Is 0x0000000000000000000000000000000000000000 a "burn address"?
Sending ERC20 To Burn Address
How to burn tokens erc20?
Send me the tokens instead 😪
More on reddit.comblockchain - How to burn token of Smart contract from another Smart contract? - Stack Overflow
Videos
I see that https://etherscan.io/address/0x0000000000000000000000000000000000000000 owns almost $3 billion in tokens plus $3.5 million ETH.
Is this a burn address? I know in Bitcoin that one can send BTC to an address where no-one knows the private key. Is the same true in Ethereum? If someone wanted to prove that they had "destroyed" a token could they send it to the above-referenced address?
guys someone know how to burn the tokens erc20? i tried to send soem tokens to this address 0x0000000000000000000000000000000000000000 but mycrypto and mew don't let me do it. Tried even with contract options but nothings! Any options?
According to Jeff Wilcke, the right way to burn ETH is to create a contract which immediately self destructs and sends to its own address, or just send ether to his deployed contract which does it all for you:
https://etherscan.io/address/0xb69fba56b2e67e7dda61c8aa057886a8d1468575#code
Here's the code:
pragma solidity ^0.4.11;
contract Burner {
uint256 public totalBurned;
function Purge() public {
// the caller of purge action receives 0.01% out of the
// current balance.
msg.sender.transfer(this.balance / 1000);
assembly {
mstore(0, 0x30ff)
// transfer all funds to a new contract that will selfdestruct
// and destroy all ether in the process.
create(balance(address), 30, 2)
pop
}
}
function Burn() payable {
totalBurned += msg.value;
}
}
A simpler example without assembly is:
contract GetsBurned {
function () payable {
}
function BurnMe () {
// Selfdestruct and send eth to self,
selfdestruct(address(this));
}
}
After calling BurnMe on the second example, you'll see that the address of the contract no longer has any balance or code. The ETH just vanishes!
In the case you need to destroy only tokens developed on Ethereum platform, this functionality may be embedded into the smart contract itself:
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
require(_value > 0);
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
Burn(burner, _value);
}
Source - OpenZeppelin
You may want to embed some additional security check like verifying the address of the function caller if you develop your own centralized token.
Suppose I have a contract "A" which can mint "X" tokens to address "R" . Then suppose I have another Contract "B" which can mint "Y" tokens to address "R" based on a condition that is , address "R" have to burn "K" amount of "X" token to mint "K" amount of "Y" token.
I have a custom mint function in contract "B", where I first try to burn the "X" token then mints "Y" token to the wallet address. As I am using Interface to call the burn function in contract "A", the contract "B"'s address is calling the `burn(uint256 amount)` function not the wallet address. And for this reason I am getting errors while burning. How can I solve this problem ?