以太坊 solidity ERC20代币添加即空投合约——空即是投,投即是空

版权声明:1、本BLOG的目的、形式及内容。   此BLOG为个人维护BLOG,内容均来自原创及互连网转载。最终目的为收集整理自己需要的文章技术等内容,不涉及商业用途。 2、有关原创文章的版权   本BLOG上原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。 3、有关本站侵权   本BLOG所转载的内容,均是本人未发现有对文章版权声明的文章且无来自传统媒体。如 https://blog.csdn.net/xq723310/article/details/82904178

    ERC20时代一个比较火的话题,空投;空投的方式有很多种。方法一,你在钱包里添加该币种,然后就获取到了空投了;方法二,你向Token合约地址转0个eth,即可获取空投,需要你花点手续费;无论是项目方或者币友们,似乎都比较中意第一种方法,毕竟不用花钱,而且还很方便。今天我们就研究一下这个东西是这么实现的。

    首先你需要知道ERC20协议,不知道童鞋们,可以自己到网上去找找看,或者等我有时间写一下。ERC20协议中规定了需要实现balanceOf()函数,返回指定地址的账户余额。

// balanceOf方法原型
function balanceOf(address _owner) constant returns (uint256 balance)

   一般当你在钱包中添加一个新的代币时,钱包的后台程序需要获取当你的代币余额,即他肯定会调用到上边这个函数;既然你知道它肯定会调用它,那我们只需要重写一下balanceOf()这个函数就可以了,在函数里加入空投的功能。这样就能实现添加即空投的功能。

  function balanceOf(address _address) constant returns (uint256) {
      return getBalance(_address);
  }

  function getBalance(address _address) internal returns (uint256) {
    if (_totalSupply < _cutoff && !initialized[_address]) {
            return balances[_address] + _airdropAmount;
        }
        else {
            return balances[_address];
        }
    }

     上边就是一个具体的实现,直接看第二个函数就好了,_cutoff是发币的总量,_totalSupply是当前已经空投出去的代币总量;initialized[_address]的作用就是判断这个地址是不是已经空投过了;满足这两个条件之后呢,就可以给地址空投了;

     其实到这里,空投的功能并没有完,还漏了最重要的一步,为什么这么说呢?

     我们始终要牢记这是个分布式的系统,你的这个查询余额的操作,其实只是对自己节点操作,所以你也只是影响自己的节点,网络上其他节点都不知道你改动,因为你的操作没有通知其他节点,即发交易。虽然你能在钱包里看到有余额,其实这是假的,如果你要把代币发送出去,肯定会失败,为什么,因为其他节点不知道你有这种代币的余额。

    那你肯定也奇怪,为啥你用钱包转账代币没有问题呢?那是因为他们对transfer()也做了手脚,下边我们具体看一下。


    function transfer(address _to, uint256 _amount) returns (bool success) {
        initialize(msg.sender); //特别注意这个函数

        if (balances[msg.sender] >= _amount
            && _amount > 0) {
            initialize(_to);
            if (balances[_to] + _amount > balances[_to]) {

                balances[msg.sender] -= _amount;
                balances[_to] += _amount;

                Transfer(msg.sender, _to, _amount);

                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

      我们再来看一下特别注意的函数initialize()。

    function initialize(address _address) internal returns (bool success) {
        if (_totalSupply < _cutoff && !initialized[_address]) {
            initialized[_address] = true;
            balances[_address] = _airdropAmount;
            _totalSupply += _airdropAmount;
        }
        return true;
    }

       怎么样是不是有点眼熟,和balanceof()类似。没错。在你转账之前,会进行判断你的账户是否空投过,没有空投过,会进行一次空投。

      这样就完美解决了我们之前的问题,钱包的节点由于添加的时候已经空投过了,所以这里调用transfer()时,直接就进行了转账;而网络上的其他节点在你进行转账的时候,检测到你没有空投过,就会先给你空投,然后在进行转账,所以你转账就ok了。

      现在明白了吗?添加即空投其实压根就没有给你空投,你需要转账一下,才可以真正的获得空投,总结一下就是,你必须花一笔矿工费才会真正获取到空投。

猜你喜欢

转载自blog.csdn.net/xq723310/article/details/82904178