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;