github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/test/NRC20.js (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  'use strict';
    20  
    21  var Allowed = function (obj) {
    22      this.allowed = {};
    23      this.parse(obj);
    24  }
    25  
    26  Allowed.prototype = {
    27      toString: function () {
    28          return JSON.stringify(this.allowed);
    29      },
    30  
    31      parse: function (obj) {
    32          if (typeof obj != "undefined") {
    33              var data = JSON.parse(obj);
    34              for (var key in data) {
    35                  this.allowed[key] = new BigNumber(data[key]);
    36              }
    37          }
    38      },
    39  
    40      get: function (key) {
    41          return this.allowed[key];
    42      },
    43  
    44      set: function (key, value) {
    45          this.allowed[key] = new BigNumber(value);
    46      }
    47  }
    48  
    49  var StandardToken = function () {
    50      LocalContractStorage.defineProperties(this, {
    51          _name: null,
    52          _symbol: null,
    53          _decimals: null,
    54          _totalSupply: {
    55              parse: function (value) {
    56                  return new BigNumber(value);
    57              },
    58              stringify: function (o) {
    59                  return o.toString(10);
    60              }
    61          }
    62      });
    63  
    64      LocalContractStorage.defineMapProperties(this, {
    65          "balances": {
    66              parse: function (value) {
    67                  return new BigNumber(value);
    68              },
    69              stringify: function (o) {
    70                  return o.toString(10);
    71              }
    72          },
    73          "allowed": {
    74              parse: function (value) {
    75                  return new Allowed(value);
    76              },
    77              stringify: function (o) {
    78                  return o.toString();
    79              }
    80          }
    81      });
    82  };
    83  
    84  StandardToken.prototype = {
    85      init: function (name, symbol, decimals, totalSupply) {
    86          this._name = name;
    87          this._symbol = symbol;
    88          this._decimals = decimals | 0;
    89          this._totalSupply = new BigNumber(totalSupply).mul(new BigNumber(10).pow(decimals));
    90  
    91          var from = Blockchain.transaction.from;
    92          this.balances.set(from, this._totalSupply);
    93          this._transferEvent(true, from, from, this._totalSupply);
    94      },
    95  
    96      // Returns the name of the token
    97      name: function () {
    98          return this._name;
    99      },
   100  
   101      // Returns the symbol of the token
   102      symbol: function () {
   103          return this._symbol;
   104      },
   105  
   106      // Returns the number of decimals the token uses
   107      decimals: function () {
   108          return this._decimals;
   109      },
   110  
   111      totalSupply: function () {
   112          return this._totalSupply.toString(10);
   113      },
   114  
   115      balanceOf: function (owner) {
   116          var balance = this.balances.get(owner);
   117  
   118          if (balance instanceof BigNumber) {
   119              return balance.toString(10);
   120          } else {
   121              return "0";
   122          }
   123      },
   124  
   125      transfer: function (to, value) {
   126          value = new BigNumber(value);
   127          if (value.lt(0)) {
   128              throw new Error("invalid value.");
   129          }
   130  
   131          var from = Blockchain.transaction.from;
   132          var balance = this.balances.get(from) || new BigNumber(0);
   133  
   134          if (balance.lt(value)) {
   135              throw new Error("transfer failed.");
   136          }
   137  
   138          this.balances.set(from, balance.sub(value));
   139          var toBalance = this.balances.get(to) || new BigNumber(0);
   140          this.balances.set(to, toBalance.add(value));
   141  
   142          this._transferEvent(true, from, to, value);
   143      },
   144  
   145      transferFrom: function (from, to, value) {
   146          var spender = Blockchain.transaction.from;
   147          var balance = this.balances.get(from) || new BigNumber(0);
   148  
   149          var allowed = this.allowed.get(from) || new Allowed();
   150          var allowedValue = allowed.get(spender) || new BigNumber(0);
   151          value = new BigNumber(value);
   152  
   153          if (value.gte(0) && balance.gte(value) && allowedValue.gte(value)) {
   154  
   155              this.balances.set(from, balance.sub(value));
   156  
   157              // update allowed value
   158              allowed.set(spender, allowedValue.sub(value));
   159              this.allowed.set(from, allowed);
   160  
   161              var toBalance = this.balances.get(to) || new BigNumber(0);
   162              this.balances.set(to, toBalance.add(value));
   163  
   164              this._transferEvent(true, from, to, value);
   165          } else {
   166              throw new Error("transfer failed.");
   167          }
   168      },
   169  
   170      _transferEvent: function (status, from, to, value) {
   171          Event.Trigger(this.name(), {
   172              Status: status,
   173              Transfer: {
   174                  from: from,
   175                  to: to,
   176                  value: value
   177              }
   178          });
   179      },
   180  
   181      approve: function (spender, currentValue, value) {
   182          var from = Blockchain.transaction.from;
   183  
   184          var oldValue = this.allowance(from, spender);
   185          if (oldValue != currentValue.toString()) {
   186              throw new Error("current approve value mistake.");
   187          }
   188  
   189          var balance = new BigNumber(this.balanceOf(from));
   190          var value = new BigNumber(value);
   191  
   192          if (value.lt(0) || balance.lt(value)) {
   193              throw new Error("invalid value.");
   194          }
   195  
   196          var owned = this.allowed.get(from) || new Allowed();
   197          owned.set(spender, value);
   198  
   199          this.allowed.set(from, owned);
   200  
   201          this._approveEvent(true, from, spender, value);
   202      },
   203  
   204      _approveEvent: function (status, from, spender, value) {
   205          Event.Trigger(this.name(), {
   206              Status: status,
   207              Approve: {
   208                  owner: from,
   209                  spender: spender,
   210                  value: value
   211              }
   212          });
   213      },
   214  
   215      allowance: function (owner, spender) {
   216          var owned = this.allowed.get(owner);
   217  
   218          if (owned instanceof Allowed) {
   219              var spender = owned.get(spender);
   220              if (typeof spender != "undefined") {
   221                  return spender.toString(10);
   222              }
   223          }
   224          return "0";
   225      }
   226  };
   227  
   228  module.exports = StandardToken;