Add advanced features to tokens - token management, additional issuance, exchange, freezing, etc.

This article mainly introduces the implementation of advanced functions of tokens: token management, token issuance, token exchange, asset freezing, and automatic gas replenishment.

write in front

In the previous article: Teach you to create your own digital currency (token) step by step for ICO , we implement a token with the most basic functions. This article will explain how to add more advanced functions based on the previous article.

Implementing Token Managers

Although the blockchain is decentralized, the management of tokens (contracts) is also required in many applications. In order to manage tokens, it is first necessary to add a manager to the contract.

Let's see if it is implemented, first create an owned contract.

    contract owned {
        address public owner;

        function owned() {
            owner = msg.sender;
        }

        modifier onlyOwner {
            require(msg.sender == owner);
            _;
        }

        // 实现所有权转移
        function transferOwnership(address newOwner) onlyOwner {
            owner = newOwner;
        }
    }

The important thing about this contract is to add a function modifier (Function Modifiers) onlyOwner , which is a contract property that can be inherited and overridden. It is used to check some kind of precondition before the function is executed.

If you are familiar with Python, you will find that the function modifier is very similar to the Python decorator.

Then let the token contract inherit owned to have onlyOwner modifier, the code is as follows:

contract MyToken is owned {
    function MyToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        address centralMinter
        ) {
        if(centralMinter != 0 ) owner = centralMinter;
    }
}

Token issuance

Realizing the additional issuance of tokens, the additional issuance of tokens is like the central bank printing money, presumably many people need such a function.

Add the following methods to the contract:

function mintToken(address target, uint256 mintedAmount) onlyOwner {
        balanceOf[target] += mintedAmount;
        totalSupply += mintedAmount;
        Transfer(0, owner, mintedAmount);
        Transfer(owner, target, mintedAmount);
    }

Note that the onlyOwner modifier is added at the end of the function, which means that only owner can call this function.
Its function is very simple, it is to add tokens to the designated account, and at the same time increase the total supply.

Asset Freeze

Sometimes for the needs of supervision, it is necessary to freeze some accounts. After freezing, their assets are still in the account, but transactions are not allowed, and the way to unfreeze them.
Add the following variables and methods to the contract (it can be added anywhere in the contract, but it is recommended to add mappings along with other mappings, as well as events):

    mapping (address => bool) public frozenAccount;
    event FrozenFunds(address target, bool frozen);

    function freezeAccount(address target, bool freeze) onlyOwner {
        frozenAccount[target] = freeze;
        FrozenFunds(target, freeze);
    }

The above code alone cannot be frozen, it needs to be added to the transfer function to take effect, so modify the transfer function

function transfer(address _to, uint256 _value) {
        require(!frozenAccount[msg.sender]);
        ...
}

In this way, before the transfer, a check is made on the account that initiated the transaction, and only the account that is not frozen can be transferred.

Token buying and selling (exchange)

The exchange mechanism between tokens and other digital currencies (ether or other tokens) can be implemented in their own currency. With this function, our contract can make a profit in one buy and one sell.

Let's set the buying and selling price first

    uint256 public sellPrice;
    uint256 public buyPrice;

    function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner {
        sellPrice = newSellPrice;
        buyPrice = newBuyPrice;
    }

setPrices() adds the onlyOwner modifier, note that the price unit for buying and selling is wei (minimum currency unit: 1 eth = 1000000000000000000 wei)

Add to add buy and sell functions:

    function buy() payable returns (uint amount){
        amount = msg.value / buyPrice;                    // calculates the amount
        require(balanceOf[this] >= amount);               // checks if it has enough to sell
        balanceOf[msg.sender] += amount;                  // adds the amount to buyer's balance
        balanceOf[this] -= amount;                        // subtracts amount from seller's balance
        Transfer(this, msg.sender, amount);               // execute an event reflecting the change
        return amount;                                    // ends function and returns
    }

    function sell(uint amount) returns (uint revenue){
        require(balanceOf[msg.sender] >= amount);         // checks if the sender has enough to sell
        balanceOf[this] += amount;                        // adds the amount to owner's balance
        balanceOf[msg.sender] -= amount;                  // subtracts the amount from seller's balance
        revenue = amount * sellPrice;
        msg.sender.transfer(revenue);                     // sends ether to the seller: it's important to do this last to prevent recursion attacks
        Transfer(msg.sender, this, amount);               // executes an event reflecting on the change
        return revenue;                                   // ends function and returns
    }

After adding the buy and sell function, we are required to send enough ether when creating the contract so that the contract can repurchase the tokens on the market, otherwise the contract will go bankrupt and users cannot sell tokens first.

Realize automatic replenishment of Gas

Transactions in Ethereum require gas (fees paid to miners in ether). And if the user does not have ether, only tokens (or we want to hide the details of ether from the user), the function of automatically replenishing gas is required. This feature will make our token more usable.

The logic of automatic replenishment is like this. Before executing the transaction, we judge the user's balance (used to pay the miners' fees). If the user's balance is very small (below a certain threshold), it may affect the transaction, and the contract will be sold automatically. A portion of tokens will be released to supplement the balance to help users complete transactions smoothly.

Let's set the balance threshold first:

uint minBalanceForAccounts;

    function setMinBalance(uint minimumBalanceInFinney) onlyOwner {
         minBalanceForAccounts = minimumBalanceInFinney * 1 finney;
    }

finney is a currency unit 1 finney = 0.001eth
and then the judgment of the user's balance is added to the transaction.

    function transfer(address _to, uint256 _value) {
        ...
        if(msg.sender.balance < minBalanceForAccounts)
            sell((minBalanceForAccounts - msg.sender.balance) / sellPrice);
        if(_to.balance<minBalanceForAccounts)   // 可选,让接受者也补充余额,以便接受者使用代币。
            _to.send(sell((minBalanceForAccounts - _to.balance) / sellPrice));
    }

code deployment

For the complete code of advanced functions, please go to my small column . For the complete deployment method of the project, please refer to the previous article . The difference is that you need to save the balance when creating a contract, as shown in the figure:

There are already many articles in the column introducing the use of Remix Solidity IDE. I won't show you the screenshots one by one here. Please test and verify by yourself.

If you are having trouble creating your token, you are welcome to ask questions on my Knowledge Planet .

Reference documentation

Explain the blockchain in simple terms - learn blockchain systematically and create the best blockchain technology blog.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324876868&siteId=291194637