Refactor to ECMA6 (babel) and JS class added

This commit is contained in:
Jordi Baylina
2017-02-10 07:24:56 +01:00
parent 7cdae6b451
commit c86e6db09b
15 changed files with 1003 additions and 568 deletions

7
.babelrc Normal file
View File

@@ -0,0 +1,7 @@
{
"presets": ["es2015", "stage-2"],
"plugins": [
"add-module-exports"
]
}

46
.eslintrc Normal file
View File

@@ -0,0 +1,46 @@
{
"env": {
"browser": true,
"es6": true,
"node": true,
"mocha": true
},
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
// indentation
"indent": [ 2, 4 ],
// spacing
"template-curly-spacing": [ 2, "always" ],
"array-bracket-spacing": [ 2, "always" ],
"object-curly-spacing": [ 2, "always" ],
"computed-property-spacing": [ 2, "always" ],
"no-multiple-empty-lines": [ 2, { "max": 1, "maxEOF": 0, "maxBOF": 0 } ],
// strings
"quotes": [ 2, "double", "avoid-escape" ],
// code arrangement matter
"no-use-before-define": [ 2, { "functions": false } ],
// make it meaningful
"prefer-const": 1,
// keep it simple
"complexity": [ 1, 5 ],
// Consisten return
"consistent-return": 0,
// Allow concatenations
"prefer-template": 0,
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.js", "**/*.spec.js", "**/compile.js", "**/test/*.js"]}],
// react
"react/prefer-es6-class": 0,
"react/jsx-filename-extension": 0,
"react/jsx-indent": [ 2, 4 ]
}
}

View File

@@ -1 +0,0 @@
606060405234610000575b60008054600160a060020a03191633600160a060020a03161790555b5b60eb806100356000396000f300606060405263ffffffff60e060020a6000350416633cebb8238114602c578063f77c4791146044575b6000565b346000576042600160a060020a0360043516606a565b005b34600057604e60b0565b60408051600160a060020a039092168252519081900360200190f35b60005433600160a060020a039081169116146083576000565b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0383161790555b5b50565b600054600160a060020a0316815600a165627a7a723058201ac9c85aae8e4d06c1c5e920b3f51b10496145a1e83669684a8ec816be04e5c10029

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

View File

@@ -149,8 +149,6 @@ contract MiniMeToken is Controlled {
decimals = _decimalUnits; // Set the decimals
symbol = _tokenSymbol; // Set the symbol
parentToken = MiniMeToken(_parentToken);
parentSnapShotBlock = _parentSnapShotBlock;
transfersEnabled = _transfersEnabled;
creationBlock = block.number;
}

File diff suppressed because one or more lines are too long

299
dist/minimetoken.js vendored Normal file
View File

@@ -0,0 +1,299 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _async = require("async");
var _async2 = _interopRequireDefault(_async);
var _bignumber = require("bignumber.js");
var _bignumber2 = _interopRequireDefault(_bignumber);
var _runethtx = require("runethtx");
var _MiniMeTokenSol = require("../contracts/MiniMeToken.sol.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var MiniMeToken = function () {
function MiniMeToken(web3, address) {
_classCallCheck(this, MiniMeToken);
this.web3 = web3;
this.contract = this.web3.eth.contract(_MiniMeTokenSol.MiniMeTokenAbi).at(address);
}
_createClass(MiniMeToken, [{
key: "getState",
value: function getState(cb) {
var _this = this;
var promise = new Promise(function (resolve, reject) {
var st = {
balances: {}
};
var accounts = void 0;
_async2.default.series([function (cb1) {
_this.contract.name(function (err, _name) {
if (err) {
cb1(err);return;
}
st.name = _name;
cb1();
});
}, function (cb1) {
_this.contract.decimals(function (err, _decimals) {
if (err) {
cb1(err);return;
}
st.decimals = _decimals;
cb1();
});
}, function (cb1) {
_this.web3.eth.getAccounts(function (err, _accounts) {
if (err) {
cb1(err);return;
}
accounts = _accounts;
cb1();
});
}, function (cb1) {
_this.contract.totalSupply(function (err, _totalSupply) {
if (err) {
cb1(err);return;
}
st.totalSupply = _totalSupply.div(new _bignumber2.default(10).pow(st.decimals)).toNumber();
cb1();
});
}, function (cb1) {
_this.contract.parentToken(function (err, _parentToken) {
if (err) {
cb1(err);return;
}
st.parentToken = _parentToken;
cb1();
});
}, function (cb1) {
_this.contract.parentSnapShotBlock(function (err, _parentSnapShotBlock) {
if (err) {
cb1(err);return;
}
st.parentSnapShotBlock = _parentSnapShotBlock;
cb1();
});
}, function (cb1) {
_async2.default.eachSeries(accounts, function (account, cb2) {
_this.contract.balanceOf(account, function (err, res) {
if (err) {
cb2(err);return;
}
st.balances[account] = res.div(new _bignumber2.default(10).pow(st.decimals)).toNumber();
cb2();
});
}, cb1);
}], function (err2) {
if (err2) {
reject(err2);
} else {
resolve(st);
}
});
});
if (cb) {
promise.then(function (value) {
cb(null, value);
}, function (reason) {
cb(reason);
});
} else {
return promise;
}
}
}, {
key: "createCloneToken",
value: function createCloneToken(opts, cb) {
var _this2 = this;
var params = Object.assign({}, opts, {
contract: this.contract,
method: "createCloneToken",
extraGas: 5000
});
var promise = new Promise(function (resolve, reject) {
(0, _runethtx.send)(params, function (err2, txHash) {
if (err2) {
reject(err2);
return;
}
_this2.web3.eth.getTransactionReceipt(txHash, function (err3, res) {
if (err3) {
reject(err3);
return;
}
var cloneTokenAddr = _this2.web3.toBigNumber(res.logs[0].topics[1]).toString(16);
while (cloneTokenAddr.length < 40) {
cloneTokenAddr = "0" + cloneTokenAddr;
}cloneTokenAddr = "0x" + cloneTokenAddr;
var miniMeTokenClone = new MiniMeToken(_this2.web3, cloneTokenAddr);
resolve(miniMeTokenClone);
});
});
});
if (cb) {
promise.then(function (value) {
cb(null, value);
}, function (reason) {
cb(reason);
});
} else {
return promise;
}
}
}, {
key: "convertAmountAndSend",
value: function convertAmountAndSend(method, opts, cb) {
var _this3 = this;
var promise = new Promise(function (resolve, reject) {
var params = Object.assign({}, opts, {
contract: _this3.contract,
method: method
});
_this3.contract.decimals(function (err, _decimals) {
if (err) {
reject(err);
return;
}
params.amount = new _bignumber2.default(10).pow(_decimals).mul(params.amount);
(0, _runethtx.send)(params, function (err2, txHash) {
if (err2) {
reject(err2);
return;
}
resolve(txHash);
});
});
});
if (cb) {
promise.then(function (value) {
cb(null, value);
}, function (reason) {
cb(reason);
});
} else {
return promise;
}
}
}, {
key: "transfer",
value: function transfer(opts, cb) {
return this.convertAmountAndSend("transfer", opts, cb);
}
}, {
key: "generateTokens",
value: function generateTokens(opts, cb) {
return this.convertAmountAndSend("generateTokens", opts, cb);
}
}, {
key: "destroyTokens",
value: function destroyTokens(opts, cb) {
var params = Object.assign({}, opts);
params.extraGas = 50000;
return this.convertAmountAndSend("destroyTokens", params, cb);
}
}, {
key: "approve",
value: function approve(opts, cb) {
return this.convertAmountAndSend("approve", opts, cb);
}
}, {
key: "allowance",
value: function allowance(opts, cb) {
var _this4 = this;
var promise = new Promise(function (resolve, reject) {
var decimals = void 0;
var allowance = void 0;
_async2.default.series([function (cb1) {
_this4.contract.decimals(function (err, _decimals) {
if (err) {
cb1(err);
return;
}
decimals = _decimals;
cb1();
});
}, function (cb1) {
_this4.contract.allowance(opts.owner, opts.spender, function (err, res) {
if (err) {
cb1(err);
return;
}
allowance = res.div(new _bignumber2.default(10).pow(decimals)).toNumber();
cb1();
});
}], function (err2) {
if (err2) {
reject(err2);
} else {
resolve(allowance);
}
});
});
if (cb) {
promise.then(function (value) {
cb(null, value);
}, function (reason) {
cb(reason);
});
} else {
return promise;
}
}
}], [{
key: "deploy",
value: function deploy(web3, opts, cb) {
var params = Object.assign({}, opts);
params.parentToken = params.parentToken || 0;
params.parentSnapShotBlock = params.parentSnapShotBlock || 0;
params.transfersEnabled = typeof params.transfersEnabled === "undefined" ? true : params.transfersEnabled;
_async2.default.series([function (cb1) {
params.abi = _MiniMeTokenSol.MiniMeTokenFactoryAbi;
params.byteCode = _MiniMeTokenSol.MiniMeTokenFactoryByteCode;
(0, _runethtx.deploy)(web3, params, function (err, _tokenFactory) {
if (err) {
cb1(err);
return;
}
params.tokenFactory = _tokenFactory.address;
cb1();
});
}, function (cb1) {
params.abi = _MiniMeTokenSol.MiniMeTokenAbi;
params.byteCode = _MiniMeTokenSol.MiniMeTokenByteCode;
(0, _runethtx.deploy)(web3, params, cb1);
}], function (err, res) {
if (err) return cb(err);
var minime = new MiniMeToken(web3, res[1].address);
cb(null, minime);
});
}
}]);
return MiniMeToken;
}();
exports.default = MiniMeToken;
module.exports = exports["default"];

15
js/compile.js Normal file
View File

@@ -0,0 +1,15 @@
import ethConnector from "ethconnector";
import path from "path";
ethConnector.compile(
path.join(__dirname, "../contracts/MiniMeToken.sol"),
path.join(__dirname, "../contracts/MiniMeToken.sol.js"),
(err) => {
if (err) {
console.log(err);
process.exit(1);
} else {
process.exit(0);
}
},
);

271
js/minimetoken.js Normal file
View File

@@ -0,0 +1,271 @@
import async from "async";
import BigNumber from "bignumber.js";
import { deploy, send } from "runethtx";
import {
MiniMeTokenAbi,
MiniMeTokenByteCode,
MiniMeTokenFactoryAbi,
MiniMeTokenFactoryByteCode,
} from "../contracts/MiniMeToken.sol.js";
export default class MiniMeToken {
constructor(web3, address) {
this.web3 = web3;
this.contract = this.web3.eth.contract(MiniMeTokenAbi).at(address);
}
getState(cb) {
const promise = new Promise((resolve, reject) => {
const st = {
balances: {},
};
let accounts;
async.series([
(cb1) => {
this.contract.name((err, _name) => {
if (err) { cb1(err); return; }
st.name = _name;
cb1();
});
},
(cb1) => {
this.contract.decimals((err, _decimals) => {
if (err) { cb1(err); return; }
st.decimals = _decimals;
cb1();
});
},
(cb1) => {
this.web3.eth.getAccounts((err, _accounts) => {
if (err) { cb1(err); return; }
accounts = _accounts;
cb1();
});
},
(cb1) => {
this.contract.totalSupply((err, _totalSupply) => {
if (err) { cb1(err); return; }
st.totalSupply =
_totalSupply.div(new BigNumber(10).pow(st.decimals)).toNumber();
cb1();
});
},
(cb1) => {
this.contract.parentToken((err, _parentToken) => {
if (err) { cb1(err); return; }
st.parentToken = _parentToken;
cb1();
});
},
(cb1) => {
this.contract.parentSnapShotBlock((err, _parentSnapShotBlock) => {
if (err) { cb1(err); return; }
st.parentSnapShotBlock = _parentSnapShotBlock;
cb1();
});
},
(cb1) => {
async.eachSeries(accounts, (account, cb2) => {
this.contract.balanceOf(account, (err, res) => {
if (err) { cb2(err); return; }
st.balances[ account ] =
res.div(new BigNumber(10).pow(st.decimals)).toNumber();
cb2();
});
}, cb1);
},
], (err2) => {
if (err2) {
reject(err2);
} else {
resolve(st);
}
});
});
if (cb) {
promise.then(
(value) => {
cb(null, value);
},
(reason) => {
cb(reason);
});
} else {
return promise;
}
}
static deploy(web3, opts, cb) {
const params = Object.assign({}, opts);
params.parentToken = params.parentToken || 0;
params.parentSnapShotBlock = params.parentSnapShotBlock || 0;
params.transfersEnabled = typeof params.transfersEnabled === "undefined" ? true : params.transfersEnabled;
async.series([
(cb1) => {
params.abi = MiniMeTokenFactoryAbi;
params.byteCode = MiniMeTokenFactoryByteCode;
deploy(web3, params, (err, _tokenFactory) => {
if (err) {
cb1(err);
return;
}
params.tokenFactory = _tokenFactory.address;
cb1();
});
},
(cb1) => {
params.abi = MiniMeTokenAbi;
params.byteCode = MiniMeTokenByteCode;
deploy(web3, params, cb1);
},
],
(err, res) => {
if (err) return cb(err);
const minime = new MiniMeToken(web3, res[ 1 ].address);
cb(null, minime);
});
}
createCloneToken(opts, cb) {
const params = Object.assign({}, opts, {
contract: this.contract,
method: "createCloneToken",
extraGas: 5000,
});
const promise = new Promise((resolve, reject) => {
send(params, (err2, txHash) => {
if (err2) {
reject(err2);
return;
}
this.web3.eth.getTransactionReceipt(txHash, (err3, res) => {
if (err3) {
reject(err3);
return;
}
let cloneTokenAddr =
this.web3.toBigNumber(res.logs[ 0 ].topics[ 1 ]).toString(16);
while (cloneTokenAddr.length < 40) cloneTokenAddr = "0" + cloneTokenAddr;
cloneTokenAddr = "0x" + cloneTokenAddr;
const miniMeTokenClone = new MiniMeToken(this.web3, cloneTokenAddr);
resolve(miniMeTokenClone);
});
});
});
if (cb) {
promise.then(
(value) => {
cb(null, value);
},
(reason) => {
cb(reason);
});
} else {
return promise;
}
}
convertAmountAndSend(method, opts, cb) {
const promise = new Promise((resolve, reject) => {
const params = Object.assign({}, opts, {
contract: this.contract,
method,
});
this.contract.decimals((err, _decimals) => {
if (err) {
reject(err);
return;
}
params.amount = new BigNumber(10).pow(_decimals).mul(params.amount);
send(params, (err2, txHash) => {
if (err2) {
reject(err2);
return;
}
resolve(txHash);
});
});
});
if (cb) {
promise.then(
(value) => {
cb(null, value);
},
(reason) => {
cb(reason);
});
} else {
return promise;
}
}
transfer(opts, cb) {
return this.convertAmountAndSend("transfer", opts, cb);
}
generateTokens(opts, cb) {
return this.convertAmountAndSend("generateTokens", opts, cb);
}
destroyTokens(opts, cb) {
const params = Object.assign({}, opts);
params.extraGas = 50000;
return this.convertAmountAndSend("destroyTokens", params, cb);
}
approve(opts, cb) {
return this.convertAmountAndSend("approve", opts, cb);
}
allowance(opts, cb) {
const promise = new Promise((resolve, reject) => {
let decimals;
let allowance;
async.series([
(cb1) => {
this.contract.decimals((err, _decimals) => {
if (err) {
cb1(err);
return;
}
decimals = _decimals;
cb1();
});
},
(cb1) => {
this.contract.allowance(opts.owner, opts.spender, (err, res) => {
if (err) {
cb1(err);
return;
}
allowance = res.div(new BigNumber(10).pow(decimals)).toNumber();
cb1();
});
},
], (err2) => {
if (err2) {
reject(err2);
} else {
resolve(allowance);
}
});
});
if (cb) {
promise.then(
(value) => {
cb(null, value);
},
(reason) => {
cb(reason);
});
} else {
return promise;
}
}
}

View File

@@ -1,77 +0,0 @@
/*jslint node: true */
"use strict";
var async = require('async');
var ethConnector = require('ethconnector');
var path = require('path');
var _ = require('lodash');
var miniMeTokenAbi;
var minimeToken;
var miniMeTokenFactoryAbi;
var miniMeTokenFactory;
var src;
exports.deploy = function(opts, cb) {
var compilationResult;
return async.series([
function(cb) {
ethConnector.loadSol(path.join(__dirname, "../MiniMeToken.sol"), function(err, _src) {
if (err) return cb(err);
src = _src;
cb();
});
},
function(cb) {
ethConnector.applyConstants(src, opts, function(err, _src) {
if (err) return cb(err);
src = _src;
cb();
});
},
function(cb) {
ethConnector.solCompile(src, function(err, result) {
if (err) return cb(err);
compilationResult = result;
cb();
});
},
function(cb) {
miniMeTokenFactoryAbi = JSON.parse(compilationResult[":MiniMeTokenFactory"].interface);
ethConnector.deploy(compilationResult[":MiniMeTokenFactory"].interface,
compilationResult[":MiniMeTokenFactory"].bytecode,
0,
0,
function(err, _miniMeTokenFactory) {
if (err) return cb(err);
miniMeTokenFactory = _miniMeTokenFactory;
cb();
});
},
function(cb) {
miniMeTokenAbi = JSON.parse(compilationResult[":MiniMeToken"].interface);
exports.miniMeTokenAbi = miniMeTokenAbi;
ethConnector.deploy(compilationResult[":MiniMeToken"].interface,
compilationResult[":MiniMeToken"].bytecode,
0,
0,
miniMeTokenFactory.address,
0,
0,
opts.tokenName,
opts.decimalUnits,
opts.tokenSymbol,
(opts.transfersEnabled === false) ? false : true,
function(err, _minimeToken) {
if (err) return cb(err);
minimeToken = _minimeToken;
cb();
});
}
], function(err) {
if (err) return cb(err);
cb(null,minimeToken, compilationResult);
});
};

View File

@@ -1,13 +1,14 @@
{
"name": "minime",
"version": "0.0.3",
"version": "0.1.1",
"description": "MiniMe contract",
"main": "index.js",
"main": "js/minimetoken.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "mocha"
"test": "mocha --compilers js:babel-core/register",
"build": "rm -rf dist/* && babel-node js/compile.js && babel js/minimetoken.js -o dist/minimetoken.js"
},
"repository": {
"type": "git",
@@ -31,6 +32,16 @@
},
"homepage": "https://github.com/Giveth/minime",
"dependencies": {
"ethconnector": "0.0.24"
"async": "^2.1.4",
"bignumber.js": "^4.0.0",
"ethconnector": "0.0.24",
"lodash": "^4.17.4",
"runethtx": "0.0.5"
},
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.22.0",
"babel-preset-stage-2": "^6.22.0"
}
}

View File

@@ -1,20 +1,10 @@
/*jslint node: true */
/*global describe, it, before, beforeEach, after, afterEach */
"use strict";
import ethConnector from "ethconnector";
import assert from "assert"; // node.js core module
import async from "async";
import MiniMeToken from "../js/minimetoken";
var miniMeTokenHelper = require('../js/minimetoken_helper.js');
var ethConnector = require('ethconnector');
var BigNumber = require('bignumber.js');
var assert = require("assert"); // node.js core module
var async = require('async');
var _ = require('lodash');
var verbose = false;
const verbose = false;
// b[0] -> 0, 0, 0, 0
// b[1] -> 0,10, 0, 0
@@ -25,531 +15,399 @@ var verbose = false;
// b[5] -> 0, 6, 1, 0
// b[6] -> 0, 2, 5. 0
describe("MiniMeToken test", () => {
let miniMeToken;
let miniMeTokenClone;
const b = [];
describe('MiniMeToken test', function(){
var miniMeToken;
var miniMeTokenClone;
var b = [];
before(function(done) {
this.timeout(200000000);
ethConnector.init('testrpc' ,{gasLimit: 4000000}, done);
// ethConnector.init('rpc', done);
before((done) => {
ethConnector.init("testrpc", { gasLimit: 4000000 }, done);
});
it('should deploy all the contracts ', function(done){
this.timeout(200000000);
var now = Math.floor(new Date().getTime() /1000);
miniMeTokenHelper.deploy({
it("should deploy all the contracts", (done) => {
MiniMeToken.deploy(ethConnector.web3, {
tokenName: "MiniMe Test Token",
decimalUnits: 18,
tokenSymbol: "MMT",
}, function(err, _miniMeToken) {
}, (err, _miniMeToken) => {
assert.ifError(err);
assert.ok(_miniMeToken.address);
assert.ok(_miniMeToken.contract.address);
miniMeToken = _miniMeToken;
done();
});
});
it('Should generate tokens for address 1', function(done) {
this.timeout(2000);
async.series([
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
assert.ifError(err);
b[0] = _blockNumber;
log("b[0]->"+b[0]);
cb();
});
},
function(cb) {
miniMeToken.generateTokens(ethConnector.accounts[1], ethConnector.web3.toWei(10), {
from: ethConnector.accounts[0],
gas: 200000},
function(err) {
assert.ifError(err);
cb();
}
);
},
function(cb) {
miniMeToken.totalSupply(function(err, _totalSupply) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 10);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 10);
cb();
});
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
assert.ifError(err);
b[1] = _blockNumber;
log("b[1]->"+b[1]);
cb();
});
}
],function(err) {
done();
});
});
it('Should transfer tokens from address 1 to address 2', function(done) {
this.timeout(2000);
async.series([
function(cb) {
miniMeToken.transfer.estimateGas(ethConnector.accounts[2], ethConnector.web3.toWei(2), {
from: ethConnector.accounts[1],
gas: 200000},
function(err, res) {
assert.ifError(err);
log("Gas for transfer: "+res);
cb();
}
);
},
function(cb) {
miniMeToken.transfer(ethConnector.accounts[2], ethConnector.web3.toWei(2), {
from: ethConnector.accounts[1],
gas: 200000},
function(err) {
assert.ifError(err);
cb();
}
);
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
assert.ifError(err);
b[2] = _blockNumber;
log("b[2]->"+b[2]);
cb();
});
},
function(cb) {
miniMeToken.totalSupply(function(err, _totalSupply) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 10);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 8);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[2], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 2);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], b[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance).toNumber(), 10);
cb();
});
},
],function(err) {
done();
});
});
it('Should allow and transfer tokens from address 2 to address 1 allowed to 3', function(done) {
async.series([
function(cb) {
miniMeToken.approve(ethConnector.accounts[3], ethConnector.web3.toWei(2), {
from: ethConnector.accounts[2],
gas: 200000},
function(err) {
assert.ifError(err);
cb();
}
);
},
function(cb) {
miniMeToken.allowance(ethConnector.accounts[2], ethConnector.accounts[3], function(err, _allowed) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_allowed), 2);
cb();
});
},
function(cb) {
miniMeToken.transferFrom(ethConnector.accounts[2], ethConnector.accounts[1], ethConnector.web3.toWei(1), {
from: ethConnector.accounts[3],
gas: 200000},
function(err) {
assert.ifError(err);
cb();
}
);
},
function(cb) {
miniMeToken.allowance(ethConnector.accounts[2], ethConnector.accounts[3], function(err, _allowed) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_allowed), 1);
cb();
});
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
assert.ifError(err);
b[3] = _blockNumber;
log("b[3]->"+b[3]);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 9);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[2], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 1);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], b[2], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 8);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[2], b[2], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 2);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], b[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 10);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[2], b[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], b[0], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[2], b[0], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], 0, function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[2], 0, function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
],function(err) {
done();
});
});
}).timeout(20000000);
it('Should Destroy 3 tokens from 1 and 1 from 2', function(done) {
it("Should generate tokens for address 1", (done) => {
async.series([
function(cb) {
miniMeToken.destroyTokens(ethConnector.accounts[1], ethConnector.web3.toWei(3), {
from: ethConnector.accounts[0],
gas: 200000},
function(err) {
assert.ifError(err);
cb();
}
);
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
b[4] = _blockNumber;
log("b[4]->"+b[4]);
b[ 0 ] = _blockNumber;
log("b[0]->" + b[ 0 ]);
cb();
});
},
function(cb) {
miniMeToken.totalSupply(function(err, _balance) {
(cb) => {
miniMeToken.generateTokens({
owner: ethConnector.accounts[ 1 ],
amount: 10,
from: ethConnector.accounts[ 0 ],
}, cb);
},
(cb) => {
miniMeToken.getState((err, _st) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 7);
assert.equal(_st.totalSupply, 10);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 10);
cb();
});
},
function(cb) {
miniMeToken.balanceOf(ethConnector.accounts[1], function(err, _balance) {
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
b[ 1 ] = _blockNumber;
log("b[1]->" + b[ 1 ]);
cb();
});
},
],function(err) {
done();
});
});
it('Should Create the clone token', function(done) {
this.timeout(200000000);
], done);
}).timeout(6000);
it("Should transfer tokens from address 1 to address 2", (done) => {
async.series([
function(cb) {
miniMeToken.createCloneToken.estimateGas(
"Clone Token 1",
18,
"MMTc",
Number.MAX_SAFE_INTEGER,
true,
{
from: ethConnector.accounts[3],
gas: 4000000
},
function(err, res) {
assert.ifError(err);
log("Gas to create: " +res);
cb();
}
);
(cb) => {
miniMeToken.transfer({
to: ethConnector.accounts[ 2 ],
from: ethConnector.accounts[ 1 ],
amount: 2,
}, cb);
},
function(cb) {
miniMeToken.createCloneToken(
"Clone Token 1",
18,
"MMTc",
Number.MAX_SAFE_INTEGER,
true,
{
from: ethConnector.accounts[3],
gas: 4000000
},
function(err, txHash) {
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
b[ 2 ] = _blockNumber;
log("b[2]->" + b[ 2 ]);
cb();
});
},
(cb) => {
miniMeToken.getState((err, _st) => {
assert.ifError(err);
assert.equal(_st.totalSupply, 10);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 8);
assert.equal(_st.balances[ ethConnector.accounts[ 2 ] ], 2);
cb();
});
},
(cb) => {
miniMeToken.contract.balanceOfAt(
ethConnector.accounts[ 1 ],
b[ 1 ],
(err, _balance) => {
assert.ifError(err);
ethConnector.web3.eth.getTransactionReceipt(txHash, function(err, res) {
var cloneTokenAddr = ethConnector.web3.toBigNumber(res.logs[0].topics[1]).toString(16);
while (cloneTokenAddr.length < 40) cloneTokenAddr = '0' + cloneTokenAddr;
cloneTokenAddr = '0x' + cloneTokenAddr;
miniMeTokenClone = ethConnector.web3.eth.contract( miniMeTokenHelper.miniMeTokenAbi).at(cloneTokenAddr);
cb();
});
assert.equal(ethConnector.web3.fromWei(_balance).toNumber(), 10);
cb();
});
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
assert.ifError(err);
b[5] = _blockNumber;
log("b[5]->"+b[5]);
cb();
});
},
function(cb) {
miniMeTokenClone.parentToken(function(err, _parentAddress) {
assert.ifError(err);
assert.equal(_parentAddress, miniMeToken.address);
cb();
});
},
function(cb) {
miniMeTokenClone.parentSnapShotBlock(function(err, _parentSnapshotBlock) {
assert.ifError(err);
assert.equal(_parentSnapshotBlock, b[5]);
cb();
});
},
function(cb) {
miniMeTokenClone.totalSupply(function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 7);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOf(ethConnector.accounts[1], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
cb();
});
},
function(cb) {
miniMeTokenClone.totalSupplyAt(b[4], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
],function(err) {
done();
});
});
it('Should move tokens in the clone token from 2 to 3', function(done) {
], done);
}).timeout(6000);
it("Should allow and transfer tokens from address 2 to address 1 allowed to 3", (done) => {
async.series([
function(cb) {
miniMeTokenClone.transfer(ethConnector.accounts[2], ethConnector.web3.toWei(4), {
from: ethConnector.accounts[1],
gas: 300000},
function(err) {
(cb) => {
miniMeToken.approve({
spender: ethConnector.accounts[ 3 ],
amount: 2,
from: ethConnector.accounts[ 2 ],
}, cb);
},
(cb) => {
miniMeToken.allowance({
owner: ethConnector.accounts[ 2 ],
spender: ethConnector.accounts[ 3 ],
}, (err, _allowed) => {
assert.ifError(err);
assert.equal(_allowed, 2);
cb();
});
},
(cb) => {
miniMeToken.contract.transferFrom(
ethConnector.accounts[ 2 ],
ethConnector.accounts[ 1 ],
ethConnector.web3.toWei(1),
{
from: ethConnector.accounts[ 3 ],
gas: 200000,
}, (err) => {
assert.ifError(err);
cb();
}
);
});
},
function(cb) {
ethConnector.web3.eth.getBlockNumber(function (err, _blockNumber) {
(cb) => {
miniMeToken.allowance({
owner: ethConnector.accounts[ 2 ],
spender: ethConnector.accounts[ 3 ],
}, (err, _allowed) => {
assert.ifError(err);
b[6] = _blockNumber;
log("b[6]->"+b[6]);
assert.equal(_allowed, 1);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOf(ethConnector.accounts[1], function(err, _balance) {
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 2);
b[ 3 ] = _blockNumber;
log("b[3]->" + b[ 3 ]);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOf(ethConnector.accounts[2], function(err, _balance) {
(cb) => {
miniMeToken.getState((err, _st) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 5);
assert.equal(_st.totalSupply, 10);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 9);
assert.equal(_st.balances[ ethConnector.accounts[ 2 ] ], 1);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[1], b[5], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 2 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 8);
cb();
});
},
function(cb) {
miniMeToken.balanceOfAt(ethConnector.accounts[2], b[5], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 1);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 2 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 2);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOfAt(ethConnector.accounts[1], b[5], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 1 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 10);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOfAt(ethConnector.accounts[2], b[5], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 1);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 1 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOfAt(ethConnector.accounts[1], b[4], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 0 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.balanceOfAt(ethConnector.accounts[2], b[4], function(err, _balance) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 0 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.totalSupply(function(err, _totalSupply) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 1 ], 0,
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.totalSupplyAt(b[5], function(err, _totalSupply) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
cb();
});
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 2 ], 0,
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
function(cb) {
miniMeTokenClone.totalSupplyAt(b[4], function(err, _totalSupply) {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 0);
cb();
});
}
],function(err) {
done();
});
], done);
});
it("Should Destroy 3 tokens from 1 and 1 from 2", (done) => {
async.series([
(cb) => {
miniMeToken.destroyTokens({
owner: ethConnector.accounts[ 1 ],
amount: 3,
from: ethConnector.accounts[ 0 ],
}, cb);
},
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
b[ 4 ] = _blockNumber;
log("b[4]->" + b[ 4 ]);
cb();
});
},
(cb) => {
miniMeToken.getState((err, _st) => {
assert.ifError(err);
assert.equal(_st.totalSupply, 7);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 6);
cb();
});
},
], done);
});
function bcDelay(secs, cb) {
send("evm_increaseTime", [secs], function(err, result) {
if (err) return cb(err);
// Mine a block so new time is recorded.
send("evm_mine", function(err, result) {
if (err) return cb(err);
cb();
});
});
}
it("Should Create the clone token", (done) => {
async.series([
(cb) => {
miniMeToken.createCloneToken({
cloneTokenName: "Clone Token 1",
cloneDecimalUnits: 18,
cloneTokenSymbol: "MMTc",
snapshotBlock: Number.MAX_SAFE_INTEGER,
transfersEnabled: true,
}, (err, _miniMeTokenClone) => {
assert.ifError(err);
miniMeTokenClone = _miniMeTokenClone;
cb();
});
},
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
b[ 5 ] = _blockNumber;
log("b[5]->" + b[ 5 ]);
cb();
});
},
(cb) => {
miniMeTokenClone.getState((err, _st) => {
assert.ifError(err);
assert.equal(_st.parentToken, miniMeToken.contract.address);
assert.equal(_st.parentSnapShotBlock, b[ 5 ]);
assert.equal(_st.totalSupply, 7);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 6);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.totalSupplyAt(b[ 4 ], (err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 4 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
], done);
}).timeout(6000);
it("Should move tokens in the clone token from 2 to 3", (done) => {
async.series([
(cb) => {
miniMeTokenClone.transfer({
to: ethConnector.accounts[ 2 ],
amount: 4,
from: ethConnector.accounts[ 1 ],
}, cb);
},
(cb) => {
ethConnector.web3.eth.getBlockNumber((err, _blockNumber) => {
assert.ifError(err);
b[ 6 ] = _blockNumber;
log("b[6]->" + b[ 6 ]);
cb();
});
},
(cb) => {
miniMeTokenClone.getState((err, _st) => {
assert.ifError(err);
assert.equal(_st.totalSupply, 7);
assert.equal(_st.balances[ ethConnector.accounts[ 1 ] ], 2);
assert.equal(_st.balances[ ethConnector.accounts[ 2 ] ], 5);
cb();
});
},
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 5 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
cb();
});
},
(cb) => {
miniMeToken.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 5 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 1);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 5 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 6);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 5 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 1);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.balanceOfAt(ethConnector.accounts[ 1 ], b[ 4 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.balanceOfAt(ethConnector.accounts[ 2 ], b[ 4 ],
(err, _balance) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_balance), 0);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.totalSupplyAt(b[ 5 ],
(err, _totalSupply) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 7);
cb();
});
},
(cb) => {
miniMeTokenClone.contract.totalSupplyAt(b[ 4 ],
(err, _totalSupply) => {
assert.ifError(err);
assert.equal(ethConnector.web3.fromWei(_totalSupply), 0);
cb();
});
},
], done);
});
function log(S) {
if (verbose) {
console.log(S);
}
}
// CALL a low level rpc
function send(method, params, callback) {
if (typeof params == "function") {
callback = params;
params = [];
}
ethConnector.web3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: method,
params: params || [],
id: new Date().getTime()
}, callback);
}
});