币乎KEY合约源码分析

币乎已经上线20多天了,从这20多天看,Token的激励真是很大啊。还没见过一个刚上线的产品就有用户自动组织打假、抨击发水文的、心甘情愿为币乎筹谋划策。而且币乎的体验目前还说还真是有很大的提升空间,但是活跃用户还是挺多,里面的大V都保持一天发一篇文章的频繁,当然发的大部分都是毫无营养的水文!不过相信币乎的发展,文章的水准会越来越高的。

币乎使用的KEY是ERC20 Token,我们可以直接在etherscan 上查看币乎KEY合约的代码。

直接看KEY合约的主要代码:

pragma solidity ^0.4.11;
import "./DSTokenBase.sol";
import "./DSStop.sol";
contract DSToken is DSTokenBase(0), DSStop {
    bytes32  public  symbol;
    uint256  public  decimals = 18; // standard token precision. override to customize
    address  public  generator;
    modifier onlyGenerator {
        if(msg.sender!=generator) throw;
        _;
    }

    function DSToken(bytes32 symbol_) {
        symbol = symbol_;
        generator=msg.sender;
    }

    function transfer(address dst, uint wad) stoppable note returns (bool) {
        return super.transfer(dst, wad);
    }
    function transferFrom(address src, address dst, uint wad) stoppable note returns (bool) {
        return super.transferFrom(src, dst, wad);
    }
    function approve(address guy, uint wad) stoppable note returns (bool) {
        return super.approve(guy, wad);
    }
    function push(address dst, uint128 wad) returns (bool) {
        return transfer(dst, wad);
    }
    function pull(address src, uint128 wad) returns (bool) {
        return transferFrom(src, msg.sender, wad);
    }
    function mint(uint128 wad) auth stoppable note {
        _balances[msg.sender] = add(_balances[msg.sender], wad);
        _supply = add(_supply, wad);
    }
    function burn(uint128 wad) auth stoppable note {
        _balances[msg.sender] = sub(_balances[msg.sender], wad);
        _supply = sub(_supply, wad);
    }
    // owner can transfer token even stop,
    function generatorTransfer(address dst, uint wad) onlyGenerator note returns (bool) {
        return super.transfer(dst, wad);
    }
    // Optional token name
    bytes32   public  name = "";
    function setName(bytes32 name_) auth {
        name = name_;
    }
}

为什么叫DSToken, 不是应该叫BiHuToken或者BHToken吗?

DSToken 继承了 DSTokenBase 和 DSStop 。DSTokenBase 主要是实现了ERC20 的接口,这在之前的几篇文章中都有提到过,这里就不在介绍了。主要是看下DSStop。

在DSToken中我们可以看到有一个generator属性,这个generator的值在构造函数中设置成了合约发布者的地址。而且还有一个onlyeGenerator的 modifier,用来判断当前操作人是不是合约发布者,这个合约发布者权利还是很大的,后面会再讲。

我们在看下DSStop的实现:

pragma solidity ^0.4.11;
import "./DSAuth.sol";
import "./DSNote.sol";
contract DSStop is DSAuth, DSNote {

    bool public stopped;

    modifier stoppable {
        assert (!stopped);
        _;
    }
    function stop() auth note {
        stopped = true;
    }
    function start() auth note {
        stopped = false;
    }

}

主要是提供了一个stoppable 的modfier, 这个的作用是判断合约有没有处于停止状态,如果合约状态处于停止状态,那么会禁止Token的转账。可以在DSToken的 transfer 和 transferFrom 方法上看到都有 stoppable 的修饰。

function transfer(address dst, uint wad) stoppable note returns (bool) {
    return super.transfer(dst, wad);
}
function transferFrom(address src, address dst, uint wad) stoppable note returns (bool) {
     return super.transferFrom(src, dst, wad);
}

这意味着什么? 意味着 币乎可以随时把KEY归零啊有木有?只要禁止了KEY的流通那不就变成积分了吗?如果变成积分,大家还会有这么大的热情么?当然我们也可以理解这是币乎给自己留的后手,如果政策不允许币乎这么搞,币乎通过禁止KEY的流通来满足监管要求,就像迅雷的链克一样,国内是不允许交易了。币乎要禁止了,国外也是照样不能交易的。

DSStop中的 stop和start 就是关闭和打开KEY流通的方法。在这两个方法上我们又看到 auth 和 note 两个 modifier。先看下auth的实现:

pragma solidity ^0.4.11;
import "./DSAuthEvents.sol";
import "./DSAuthority.sol";
contract DSAuth is DSAuthEvents {
    DSAuthority  public  authority;
    address      public  owner;

    function DSAuth() {
        owner = msg.sender;
        LogSetOwner(msg.sender);
    }

    function setOwner(address owner_)
    auth
    {
        owner = owner_;
        LogSetOwner(owner);
    }

    function setAuthority(DSAuthority authority_)
    auth
    {
        authority = authority_;
        LogSetAuthority(authority);
    }

    modifier auth {
        assert(isAuthorized(msg.sender, msg.sig));
        _;
    }

    function isAuthorized(address src, bytes4 sig) internal returns (bool) {
        if (src == address(this)) {
            return true;
        } else if (src == owner) {
            return true;
        } else if (authority == DSAuthority(0)) {
            return false;
        } else {
            return authority.canCall(src, this, sig);
        }
    }

    function assert(bool x) internal {
        if (!x) throw;
    }
}

DSAuth 中有一个owner的属性,从字面意思可以猜到,owner应该会是管理合约的人,初始化的时候会设为合约发布者,但是后面是可以通过setOwner 来设置为其他账号,一般这个owner会设置为老板吧?。auth 的作用主要是认证当前操作人有没有权限。比如说 mint 跟 burn 这个方法
就需要auth来认证有没有权限了。mint 这个方法有点意思,mint可以给有权限的地址发放KEY,但是mint 是可以增加发行量的,币乎KEY虽然号称发行100亿,但是从这个方法来看,并没有限制KEY的发行量。也就是说币乎后面如果觉得KEY不够用了,还可以继续增发啊!增发啊! burn很好理解,币乎每隔一段时间会回购一定的KEY销毁。 从这个方法也可以看到这个销毁是真的把KEY销毁了,发行总量也减少了。

在来看下note的实现:

pragma solidity ^0.4.11;
contract DSNote {
    event LogNote(
    bytes4   indexed  sig,
    address  indexed  guy,
    bytes32  indexed  foo,
    bytes32  indexed  bar,
    uint        wad,
    bytes             fax
    ) anonymous;

    modifier note {
        bytes32 foo;
        bytes32 bar;

        assembly {
        foo := calldataload(4)
        bar := calldataload(36)
        }

        LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);

        _;
    }
}

这个就很好理解,对于一些重要的操作,币乎都需要记录下来,后面出了问题也可以有记录可查。

最后让我们来看下DSToken 中的generatorTransfer 这个方法,从这个方法可以看到是没有 stopable修饰的,注释上也写明了 即使禁止了转让但是owner还是可以转让Token的。这个方法的作用目前我还没想到有啥作用,既然禁止了token的转让只允许owner一个人可以转让那没什么大意义吧。

币乎目前是我看来非常有活力的社区,虽然才刚起步,但是我相信后面会越来越好。KEY目前在交易所目前价格也要3分一个,随着币乎的发展KEY的价格也会水涨船高的。现在币乎注册还有送7万的KEY,大家如果想要体验下币乎可以使用我的推荐链接,有兴趣的可以来体验下,也算是区块链落地的一个应用吧!

你可能感兴趣的:(币乎KEY合约源码分析)