wooing
新哥 Lv6   
楼主
解析星云的ERC20--NRC20
查看:306   回复:0   发布于2018-04-28 13:48:25

概述

nebulas的NRC20代币,相当于以太坊中的ERC20代币,遵守了REC20协议的货币更容易互换,并且能够在Dapps上运行相同的工作。


标准化是非常有利的,比如:

1、可以方便的对接交易所,使代币几乎不用做额外的工作就可以完成交易所的对接;

2、可以在区块浏览器中方便的查询代币的交易记录;

3、方便投资者阅读智能合约,减少理解成本。


nebulas的NRC20智能合约必须实现以下接口和事件:

标准接口:

function name()

function symbol()

function decimals()

function totalSupply()

function balanceOf(address)

function transfer(address, value)

function transferFrom(from, to, value)

function approve(spender, currentValue, value)

function allowance(owner, spender)


标准事件:

function transferEvent: function(status, from, to, value)

function approveEvent: function(status, from, spender, value)



下面是星云官方的NRC20模版:

'use strict';

//定义授权的Map容器
var Allowed = function (obj) {
    this.allowed = {};
    this.parse(obj);
}

Allowed.prototype = {
    toString: function () {
        return JSON.stringify(this.allowed);
    },

    parse: function (obj) {
        if (typeof obj != "undefined") {
            var data = JSON.parse(obj);
            for (var key in data) {
                this.allowed[key] = new BigNumber(data[key]);
            }
        }
    },

    //查询授权的代币数量
    get: function (key) {
        return this.allowed[key];
    },

    //设置授权的代币数量
    set: function (key, value) {
        this.allowed[key] = new BigNumber(value);
    }
}

//标准的NRC20合约类
var StandardToken = function () {
    LocalContractStorage.defineProperties(this, {
        _name: null,                    //合约名字
        _symbol: null,                  //代币符号
        _decimals: null,                //代币的精度,(小数点位数)
        _totalSupply: {
            parse: function (value) {
                return new BigNumber(value);
            },
            stringify: function (o) {
                return o.toString(10);
            }
        }
    });

    LocalContractStorage.defineMapProperties(this, {
        //定义代币的Map容器,用来存放每一个账户的代币数量
        "balances": {
            parse: function (value) {
                return new BigNumber(value);
            },
            stringify: function (o) {
                return o.toString(10);
            }
        },
        //定义代币授权数量的Map容器,用来存放每一个账户的代币授权数量
        "allowed": {
            parse: function (value) {
                return new Allowed(value);
            },
            stringify: function (o) {
                return o.toString();
            }
        }
    });
};

StandardToken.prototype = {
    //智能合约初始化函数,只会在部署的时候执行一次
    init: function (name, symbol, decimals, totalSupply) {
        this._name = name;
        this._symbol = symbol;
        this._decimals = decimals || 0;
        this._totalSupply = new BigNumber(totalSupply).mul(new BigNumber(10).pow(decimals));

        var from = Blockchain.transaction.from;
        this.balances.set(from, this._totalSupply);
        this.transferEvent(true, from, from, this._totalSupply);
    },

    // 智能合约的名字
    name: function () {
        return this._name;
    },

    // 智能合约的代币的符号
    symbol: function () {
        return this._symbol;
    },

    // 智能合约代币的精度
    decimals: function () {
        return this._decimals;
    },

    // 代币的总发行量
    totalSupply: function () {
        return this._totalSupply.toString(10);
    },

    // 查询账户里的代币余额
    balanceOf: function (owner) {
        var balance = this.balances.get(owner);

        if (balance instanceof BigNumber) {
            return balance.toString(10);
        } else {
            return "0";
        }
    },

    // 向目标地址发送代币
    transfer: function (to, value) {
        value = new BigNumber(value);
        if (value.lt(0)) {
            throw new Error("invalid value.");
        }

        var from = Blockchain.transaction.from;
        var balance = this.balances.get(from) || new BigNumber(0);

        if (balance.lt(value)) {
            throw new Error("transfer failed.");
        }

        this.balances.set(from, balance.sub(value));
        var toBalance = this.balances.get(to) || new BigNumber(0);
        this.balances.set(to, toBalance.add(value));

        this.transferEvent(true, from, to, value);
    },

    // 从授权地址向目标地址发送代币
    transferFrom: function (from, to, value) {
        var spender = Blockchain.transaction.from;
        var balance = this.balances.get(from) || new BigNumber(0);

        var allowed = this.allowed.get(from) || new Allowed();
        var allowedValue = allowed.get(spender) || new BigNumber(0);
        value = new BigNumber(value);

        if (value.gte(0) && balance.gte(value) && allowedValue.gte(value)) {

            this.balances.set(from, balance.sub(value));

            // update allowed value
            allowed.set(spender, allowedValue.sub(value));
            this.allowed.set(from, allowed);

            var toBalance = this.balances.get(to) || new BigNumber(0);
            this.balances.set(to, toBalance.add(value));

            this.transferEvent(true, from, to, value);
        } else {
            throw new Error("transfer failed.");
        }
    },

    //定义交易事件,用于通知浏览器
    transferEvent: function (status, from, to, value) {
        Event.Trigger(this.name(), {
            Status: status,
            Transfer: {
                from: from,
                to: to,
                value: value
            }
        });
    },

    // 给某一地址授权代币
    approve: function (spender, currentValue, value) {
        var from = Blockchain.transaction.from;

        var oldValue = this.allowance(from, spender);
        if (oldValue != currentValue.toString()) {
            throw new Error("current approve value mistake.");
        }

        var balance = new BigNumber(this.balanceOf(from));
        var value = new BigNumber(value);

        if (value.lt(0) || balance.lt(value)) {
            throw new Error("invalid value.");
        }

        var owned = this.allowed.get(from) || new Allowed();
        owned.set(spender, value);

        this.allowed.set(from, owned);

        this.approveEvent(true, from, spender, value);
    },

    // 定义代币授权事件
    approveEvent: function (status, from, spender, value) {
        Event.Trigger(this.name(), {
            Status: status,
            Approve: {
                owner: from,
                spender: spender,
                value: value
            }
        });
    },

    // 查询某个地址的代币授权
    allowance: function (owner, spender) {
        var owned = this.allowed.get(owner);

        if (owned instanceof Allowed) {
            var spender = owned.get(spender);
            if (typeof spender != "undefined") {
                return spender.toString(10);
            }
        }
        return "0";
    }
};

module.exports = StandardToken;


星云NRC20官方说明:https://github.com/nebulasio/wiki/blob/master/NRC20.md

 
回复列表
默认   热门   正序   倒序

回复:解析星云的ERC20--NRC20

Powered by 星云原力社区 5.5.1

©2015 - 2018 原力社区

原力社区论坛 联系站长

您的IP:52.91.185.49,2018-12-13 07:04:47,Processed in 0.01735 second(s).

原力社区,是全球最大的有庞大用户沉淀、开发者沉淀和项目资源沉淀的,能够独立自主的去中心化的第三方社区。