Added new regression tests (based on pregenerated JSON files).
This commit is contained in:
parent
89c4c75e3c
commit
9625745f4c
@ -26,6 +26,27 @@ function testAddress(test) {
|
|||||||
test.done();
|
test.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testContractAddress(test) {
|
||||||
|
|
||||||
|
// @TODO: Mine a large collection of these from the blockchain
|
||||||
|
|
||||||
|
var getContractAddress = require('../utils/contract-address.js').getContractAddress;
|
||||||
|
|
||||||
|
// Transaction: 0x939aa17985bc2a52a0c1cba9497ef09e092355a805a8150e30e24b753bac6864
|
||||||
|
var transaction = {
|
||||||
|
from: '0xb2682160c482eb985ec9f3e364eec0a904c44c23',
|
||||||
|
nonce: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
test.equal(
|
||||||
|
getContractAddress(transaction),
|
||||||
|
"0x3474627D4F63A678266BC17171D87f8570936622",
|
||||||
|
'Failed to match contract address'
|
||||||
|
)
|
||||||
|
|
||||||
|
test.done();
|
||||||
|
}
|
||||||
|
|
||||||
function testRLPCoder(test) {
|
function testRLPCoder(test) {
|
||||||
var rlp = require('../utils/rlp.js');
|
var rlp = require('../utils/rlp.js');
|
||||||
|
|
||||||
@ -59,6 +80,7 @@ function testUnits(test) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"address": testAddress,
|
"address": testAddress,
|
||||||
|
"contract-address": testContractAddress,
|
||||||
"rlp-coder": testRLPCoder,
|
"rlp-coder": testRLPCoder,
|
||||||
"units": testUnits,
|
"units": testUnits,
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var Wallet = require('../wallet/index.js');
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
var username = 'ricmoo';
|
|
||||||
var password = 'password';
|
|
||||||
Wallet.summonBrainWallet(username, password).then(function(wallet) {
|
|
||||||
test.equal(wallet.address, '0xbed9d2E41BdD066f702C4bDB86eB3A3740101acC', 'wrong wallet generated');
|
|
||||||
test.done();
|
|
||||||
}, function(error) {
|
|
||||||
test.ok(false, 'Failed to generarte brain wallet');
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
@ -1,29 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
//var Wallet = require('../index.js');
|
|
||||||
var ethersAddress = require('../utils/address.js');
|
|
||||||
|
|
||||||
var ethereumUtil = require('ethereumjs-util');
|
|
||||||
|
|
||||||
var utils = require('./utils.js');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
function testAddress(address) {
|
|
||||||
var official = ethereumUtil.toChecksumAddress(address);
|
|
||||||
var ethers = ethersAddress.getAddress(address);
|
|
||||||
test.equal(ethers, official, 'wrong address');
|
|
||||||
}
|
|
||||||
|
|
||||||
test.expect(2 + 10000);
|
|
||||||
|
|
||||||
testAddress('0x0000000000000000000000000000000000000000');
|
|
||||||
testAddress('0xffffffffffffffffffffffffffffffffffffffff');
|
|
||||||
for (var i = 0; i < 10000; i++) {
|
|
||||||
testAddress(utils.randomHexString(20));
|
|
||||||
}
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var ethersAddress = require('../utils/address.js');
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
// Transaction: 0x939aa17985bc2a52a0c1cba9497ef09e092355a805a8150e30e24b753bac6864
|
|
||||||
var transaction = {
|
|
||||||
from: '0xb2682160c482eb985ec9f3e364eec0a904c44c23',
|
|
||||||
nonce: 10,
|
|
||||||
}
|
|
||||||
|
|
||||||
test.equal(
|
|
||||||
ethersAddress.getContractAddress(transaction),
|
|
||||||
ethersAddress.getAddress('0x3474627d4f63a678266bc17171d87f8570936622'),
|
|
||||||
'Failed to match contract address'
|
|
||||||
)
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var bigNumberify = require('../utils/bignumber.js').bigNumberify;
|
|
||||||
var ethersUnits = require('../utils/units.js');
|
|
||||||
|
|
||||||
// @TODO: Add testcases where format receives hexidecimal string
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
function checkFormat(wei, targetEther, options) {
|
|
||||||
var ether = ethersUnits.formatEther(wei, options);
|
|
||||||
//console.log(wei, targetEther, options, ether);
|
|
||||||
test.equal(ether, targetEther, 'Failed to match formatted ether');
|
|
||||||
ether = ether.replace(/,/g, '');
|
|
||||||
test.ok(ethersUnits.parseEther(ether).eq(wei), 'Failed to convert back to wei');
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkParse(ether, targetWei) {
|
|
||||||
//console.log(ether, targetWei, Wallet.parseEther(ether));
|
|
||||||
test.ok(targetWei.eq(ethersUnits.parseEther(ether)), 'Failed to match target wei');
|
|
||||||
}
|
|
||||||
|
|
||||||
checkParse('123.012345678901234567', bigNumberify('123012345678901234567'));
|
|
||||||
|
|
||||||
checkParse('1.0', bigNumberify('1000000000000000000'));
|
|
||||||
checkParse('1', bigNumberify('1000000000000000000'));
|
|
||||||
checkParse('1.00', bigNumberify('1000000000000000000'));
|
|
||||||
checkParse('01.0', bigNumberify('1000000000000000000'));
|
|
||||||
|
|
||||||
checkParse('-1.0', bigNumberify('-1000000000000000000'));
|
|
||||||
|
|
||||||
checkParse('0.1', bigNumberify('100000000000000000'));
|
|
||||||
checkParse('.1', bigNumberify('100000000000000000'));
|
|
||||||
checkParse('0.10', bigNumberify('100000000000000000'));
|
|
||||||
checkParse('.100', bigNumberify('100000000000000000'));
|
|
||||||
checkParse('00.100', bigNumberify('100000000000000000'));
|
|
||||||
|
|
||||||
checkParse('-0.1', bigNumberify('-100000000000000000'));
|
|
||||||
|
|
||||||
|
|
||||||
checkFormat(bigNumberify('10000000000000000'), '0.01');
|
|
||||||
checkFormat(bigNumberify('1000000000000000000'), '1.0');
|
|
||||||
checkFormat(bigNumberify('1230000000000000000'), '1.23');
|
|
||||||
checkFormat(bigNumberify('-1230000000000000000'), '-1.23');
|
|
||||||
|
|
||||||
checkFormat(bigNumberify('1000000000000000000'), '1.000000000000000000', {pad: true});
|
|
||||||
checkFormat(bigNumberify('123000000000000000000'), '123.000000000000000000', {pad: true});
|
|
||||||
checkFormat(bigNumberify('1230000000000000000'), '1.230000000000000000', {pad: true});
|
|
||||||
|
|
||||||
checkFormat(bigNumberify('-1230000000000000000'), '-1.230000000000000000', {pad: true});
|
|
||||||
|
|
||||||
checkFormat(bigNumberify('1234567890000000000000000'), '1,234,567.89', {pad: false, commify: true});
|
|
||||||
checkFormat(bigNumberify('1234567890000000000000000'), '1,234,567.890000000000000000', {pad: true, commify: true});
|
|
||||||
checkFormat(bigNumberify('-1234567890000000000000000'), '-1,234,567.89', {pad: false, commify: true});
|
|
||||||
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var ethersAddress = require('../utils/address.js');
|
|
||||||
|
|
||||||
var ethereumUtil = require('ethereumjs-util');
|
|
||||||
var iban = require('../node_modules/web3/lib/web3/iban.js');
|
|
||||||
|
|
||||||
var utils = require('./utils.js');
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
function testAddress(address) {
|
|
||||||
var officialIban = (iban.fromAddress(address))._iban;
|
|
||||||
|
|
||||||
var address = ethersAddress.getAddress(officialIban);
|
|
||||||
var officialAddress = ethereumUtil.toChecksumAddress(address)
|
|
||||||
|
|
||||||
var ethersIban = ethersAddress.getAddress(address, true);
|
|
||||||
|
|
||||||
test.equal(address, officialAddress, 'wrong address');
|
|
||||||
test.equal(ethersIban, officialIban, 'wrong ICAP address');
|
|
||||||
}
|
|
||||||
|
|
||||||
test.expect(2 * (2 + 10000));
|
|
||||||
|
|
||||||
testAddress('0x0000000000000000000000000000000000000000');
|
|
||||||
testAddress('0xffffffffffffffffffffffffffffffffffffffff');
|
|
||||||
for (var i = 0; i < 10000; i++) {
|
|
||||||
testAddress(utils.randomHexString(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
var ethersWallet = require('../wallet/index.js');
|
|
||||||
|
|
||||||
var ethereumUtil = require('ethereumjs-util');
|
|
||||||
|
|
||||||
var utils = require('./utils.js');
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
for (var i = 0; i < 10000; i++) {
|
|
||||||
var privateKey = utils.randomBuffer(32);
|
|
||||||
var ethereumLib = '0x' + ethereumUtil.privateToAddress(privateKey).toString('hex');
|
|
||||||
var ethers = (new ethersWallet(privateKey)).address;
|
|
||||||
test.equal(ethers, ethereumUtil.toChecksumAddress(ethereumLib), 'wrong address');
|
|
||||||
}
|
|
||||||
test.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
var Wallet = require('../wallet/index.js');
|
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
|
|
||||||
function equals(a, b) {
|
|
||||||
if (typeof(a) !== typeof(b)) { return false; }
|
|
||||||
if (Array.isArray(a)) {
|
|
||||||
if (!Array.isArray(b)) { return false; }
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
if (a[i] !== b[i]) { return false; }
|
|
||||||
}
|
|
||||||
} else if (typeof(a) === 'object') {
|
|
||||||
if (!equals(Object.keys(a), Object.keys(b))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (var key in a) {
|
|
||||||
if (!equals(a[key], b[key])) { return false; }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (a === b);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var crowdsale = [
|
|
||||||
{
|
|
||||||
address: '0x2e326fA404Fc3661de4F4361776ed9bBABDC26E3',
|
|
||||||
data: fs.readFileSync('./test-wallets/wallet-test-encseed-foo.json').toString(),
|
|
||||||
password: 'foo',
|
|
||||||
privateKey: '0xcf367fc32bf789b3339c6664af4a12263e9db0e0eb70f247da1d1165e150c487',
|
|
||||||
type: 'crowdsale'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
address: '0x0b88d4b324ec24C8c078551e6e5075547157E5b6',
|
|
||||||
data: fs.readFileSync('./test-wallets/wallet-test-encseed-no-password.json').toString(),
|
|
||||||
password: '',
|
|
||||||
privateKey: '0xd4375d2a931db84ea8825b69a3128913597744d9236cacec675cc18e1bda4446',
|
|
||||||
type: 'crowdsale'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
var geth = [
|
|
||||||
{
|
|
||||||
address: '0x88a5C2d9919e46F883EB62F7b8Dd9d0CC45bc290',
|
|
||||||
data: fs.readFileSync('./test-wallets/wallet-test-geth-foo.json').toString(),
|
|
||||||
password: 'foo',
|
|
||||||
privateKey: '0xf03e581353c794928373fb0893bc731aefc4c4e234e643f3a46998b03cd4d7c5',
|
|
||||||
type: 'version3'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
address: '0x4A9cf99357F5789251a8D7FaD5b86D0F31EEB938',
|
|
||||||
data: fs.readFileSync('./test-wallets/wallet-test-geth-no-password.json').toString(),
|
|
||||||
password: '',
|
|
||||||
privateKey: '0xa016182717223d01f776149ec0b4a217d0e9930cad263f205427c6d3cd5560e7',
|
|
||||||
type: 'version3'
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Test crowdsale private key decryption
|
|
||||||
crowdsale.forEach(function(testcase) {
|
|
||||||
|
|
||||||
// Check wallet type detection
|
|
||||||
test.ok(Wallet.isCrowdsaleWallet(testcase.data), 'wrong wallet type detected');
|
|
||||||
//test.ok(!Wallet.isValidWallet(testcase.data), 'wrong wallet type detected');
|
|
||||||
|
|
||||||
var wallet = Wallet.decryptCrowdsale(testcase.data, testcase.password);
|
|
||||||
|
|
||||||
test.equal(wallet.privateKey, testcase.privateKey, 'wrong private key');
|
|
||||||
test.equal(wallet.address, testcase.address, 'wrong address');
|
|
||||||
});
|
|
||||||
|
|
||||||
var async = [];
|
|
||||||
|
|
||||||
geth.forEach(function(testcase) {
|
|
||||||
// Check wallet type detection
|
|
||||||
//test.ok(Wallet.isValidWallet(testcase.data), 'wrong wallet type detected');
|
|
||||||
test.ok(!Wallet.isCrowdsaleWallet(testcase.data), 'wrong wallet type detected');
|
|
||||||
|
|
||||||
async.push(new Promise(function(resolve, reject) {
|
|
||||||
|
|
||||||
// Test private key decryption
|
|
||||||
var password = new Buffer(testcase.password, 'utf8');
|
|
||||||
Wallet.decrypt(testcase.data, password).then(function(wallet) {
|
|
||||||
test.equals(wallet.privateKey, testcase.privateKey, 'wrong private key')
|
|
||||||
test.equals(wallet.address, testcase.address, 'wrong address');
|
|
||||||
resolve();
|
|
||||||
}, function(error) {
|
|
||||||
console.log(error);
|
|
||||||
test.ok(false, 'callback returned error - ' + error.message);
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
var privateKey = new Buffer(32);
|
|
||||||
privateKey.fill(0x42);
|
|
||||||
var password = new Buffer("foo", 'utf8');
|
|
||||||
async.push(new Promise(function(resolve, reject) {
|
|
||||||
(new Wallet(privateKey)).encrypt(password, {
|
|
||||||
scrypt: { N: (1 << 10), r: 4, p: 2 },
|
|
||||||
iv: '0xdeadbeef1deadbeef2deadbeef301234',
|
|
||||||
salt: '0xabcd1abcd2abcd3abcd4abcd5abcd6ef',
|
|
||||||
uuid: '0x01234567890123456789012345678901',
|
|
||||||
}).then(function(json) {
|
|
||||||
/*
|
|
||||||
var jsonWallet = fs.readFileSync('./test-wallets/wallet-test-life.json').toString();
|
|
||||||
test.ok(equals(JSON.parse(json), JSON.parse(jsonWallet)), 'failed to encrypt wallet')
|
|
||||||
//test.equal(json, jsonWallet, 'failed to encrypt wallet');
|
|
||||||
Wallet.decrypt(json, password).then(function(wallet) {
|
|
||||||
test.equal(wallet.privateKey, '0x' + privateKey.toString('hex'), 'decryption failed');
|
|
||||||
*/
|
|
||||||
resolve();
|
|
||||||
/*
|
|
||||||
}, function(error) {
|
|
||||||
test.ok(false, 'callback returned error - ' + error.message);
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}, function(error) {
|
|
||||||
test.ok(false, 'callback returned error - ' + error.message);
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
Promise.all(async).then(function(results) {
|
|
||||||
test.done();
|
|
||||||
}, function(error) {
|
|
||||||
console.log(error);
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,492 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
//var Wallet = require('../index.js');
|
|
||||||
var contracts = require('../contracts/index.js');
|
|
||||||
|
|
||||||
var bigNumber = require('../utils/bignumber.js');
|
|
||||||
var convert = require('../utils/convert.js');
|
|
||||||
|
|
||||||
var solc = require('solc');
|
|
||||||
var ethereumVm = require('ethereumjs-vm');
|
|
||||||
var ethereumUtil = require('ethereumjs-util');
|
|
||||||
|
|
||||||
var BN = require('bn.js');
|
|
||||||
|
|
||||||
var utils = require('./utils.js');
|
|
||||||
var random = utils.random;
|
|
||||||
|
|
||||||
// Create the indent given a tabstop
|
|
||||||
function indent(tabs) {
|
|
||||||
var indent = new Buffer(tabs * 4);
|
|
||||||
indent.fill(32);
|
|
||||||
return indent.toString('utf8')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function createContractOutput(types, values) {
|
|
||||||
var source = 'contract Test {\n';
|
|
||||||
source += ' function test() constant returns (' + types.join(', ') + ') {\n';
|
|
||||||
|
|
||||||
var returns = [];
|
|
||||||
for (var i = 0; i < types.length; i++) {
|
|
||||||
var name = String.fromCharCode(97 + i);
|
|
||||||
|
|
||||||
// Array type; do a deep copy
|
|
||||||
if (types[i].indexOf('[') >= 0) {
|
|
||||||
|
|
||||||
// Each count (or optionally empty) array type
|
|
||||||
var arrays = types[i].match(/\[[0-9]*\]/g);
|
|
||||||
|
|
||||||
// Allocate the space (only dynamic arrays require new)
|
|
||||||
source += indent(2) + types[i] + ' memory ' + name;
|
|
||||||
if (arrays[arrays.length - 1] === '[]') {
|
|
||||||
source += ' = new ' + types[i] + '(' + values[i].length+ ')';
|
|
||||||
}
|
|
||||||
source +=';\n';
|
|
||||||
|
|
||||||
var baseType = types[i].substring(0, types[i].indexOf('['));
|
|
||||||
|
|
||||||
function recursiveSet(item, indices) {
|
|
||||||
if (Array.isArray(item)) {
|
|
||||||
item.forEach(function(item, index) {
|
|
||||||
var i = indices.slice();
|
|
||||||
i.unshift(index);
|
|
||||||
recursiveSet(item, i);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var loc = '';
|
|
||||||
indices.forEach(function(index) {
|
|
||||||
loc = '[' + index + ']' + loc;
|
|
||||||
})
|
|
||||||
|
|
||||||
if (item instanceof BN) { item = item.toString(10); }
|
|
||||||
source += indent(2) + name + loc + ' = ' + baseType + '(' + item + ');\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
recursiveSet(values[i], []);
|
|
||||||
|
|
||||||
// Dynamic type: bytes
|
|
||||||
} else if (types[i] === 'bytes') {
|
|
||||||
source += indent(2) + 'bytes memory ' + name + ' = new bytes(' + values[i].length + ');\n';
|
|
||||||
source += indent(2) + 'assembly {\n'
|
|
||||||
source += indent(3) + 'mstore(' + name + ', ' + values[i].length + ')\n';
|
|
||||||
for (var j = 0; j < values[i].length; j++) {
|
|
||||||
source += indent(3) + 'mstore8(add(' + name + ', ' + (32 + j) + '), ' + values[i][j] + ')\n';
|
|
||||||
}
|
|
||||||
source += indent(2) + '}\n'
|
|
||||||
/*
|
|
||||||
var value = '';
|
|
||||||
for (var j = 0; j < values[i].length; j++) {
|
|
||||||
value += '\\' + 'x' + values[i].slice(j, j + 1).toString('hex');
|
|
||||||
}
|
|
||||||
source += ' bytes memory ' + name + ' = "' + value + '";\n';
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Dynamic type: string
|
|
||||||
} else if (types[i] === 'string') {
|
|
||||||
source += ' string memory ' + name + ' = "' + values[i] + '";\n';
|
|
||||||
|
|
||||||
// Static type; just use the stack
|
|
||||||
} else {
|
|
||||||
source += ' ' + types[i] + ' ' + name + ' = ' + types[i] + '(' + values[i] + ');\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track the name to return
|
|
||||||
returns.push(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the values
|
|
||||||
source += ' return (' + returns.join(', ') + ');\n';
|
|
||||||
|
|
||||||
source += ' }\n';
|
|
||||||
source += '}\n';
|
|
||||||
|
|
||||||
try {
|
|
||||||
var contract = solc.compile(source, 0);
|
|
||||||
contract = contract.contracts.Test;
|
|
||||||
contract.sourceCode= source;
|
|
||||||
return contract;
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Failed to compile ========');
|
|
||||||
console.log({types: types, values: values, contract: contract});
|
|
||||||
console.log(source);
|
|
||||||
console.log('========');
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
|
|
||||||
function dumpHex(data) {
|
|
||||||
for (var i = 2; i < data.length; i += 64) {
|
|
||||||
console.log(' ' + data.substring(i, i + 64));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function recursiveEqual(a, b) {
|
|
||||||
if (typeof(b) === 'boolean') {
|
|
||||||
if (typeof(a) !== 'boolean' || a !== b) { return false; }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof(b) === 'string') {
|
|
||||||
if (typeof(a) !== 'string' || a !== b) {
|
|
||||||
console.log('String', new Buffer(a), new Buffer(b));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b.buffer) {
|
|
||||||
if (convert.hexlify(a) !== convert.hexlify(b)) { return false; }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b._bn) {
|
|
||||||
return b.eq(bigNumber.bigNumberify(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (typeof(a) === 'number' || BN.isBN(a)) { a = bigNumber.bigNumberify(a); }
|
|
||||||
//if (typeof(b) === 'number' || BN.isBN(b)) { b = bigNumber.bigNumberify(b); }
|
|
||||||
//if (typeof(a) === 'string' && !convert.isHexString(a)) { a = '0x' + (new Buffer(a)).toString('hex'); }
|
|
||||||
//if (typeof(b) === 'string' && !convert.isHexString(b)) { b = '0x' + (new Buffer(b)).toString('hex'); }
|
|
||||||
|
|
||||||
if (Array.isArray(a)) {
|
|
||||||
if (!Array.isArray(b) || a.length !== b.length) { return fail(); }
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
if (!recursiveEqual(a[i], b[i])) { return false; }
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var checkPromises = [];
|
|
||||||
|
|
||||||
var nextTestId = 0;
|
|
||||||
var remaining = {};
|
|
||||||
function check(types, values, normalizedValues) {
|
|
||||||
if (!normalizedValues) { normalizedValues = values; }
|
|
||||||
|
|
||||||
// First make sure we agree with ourself
|
|
||||||
var ethersData = contracts.Interface.encodeParams(types, values);
|
|
||||||
var ethersValues = contracts.Interface.decodeParams(types, ethersData);
|
|
||||||
|
|
||||||
// Convert the result object into an Array
|
|
||||||
var ethersValuesArray = [];
|
|
||||||
for (var i = 0; ethersValues[i] !== undefined; i++) {
|
|
||||||
ethersValuesArray.push(ethersValues[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var okSelf = recursiveEqual(normalizedValues, ethersValuesArray);
|
|
||||||
test.ok(okSelf, "self encode/decode failed");
|
|
||||||
if (!okSelf) {
|
|
||||||
console.log('okSelf', types, values, normalizedValues, ethersValues, ethersValuesArray);
|
|
||||||
console.log('=================');
|
|
||||||
}
|
|
||||||
|
|
||||||
checkPromises.push(new Promise(function(resolve, reject) {
|
|
||||||
var testId = (nextTestId++);
|
|
||||||
remaining[testId] = true;
|
|
||||||
|
|
||||||
// Use this when a contracts "hangs" (ie. 0-length arrays seem to hang the VM)
|
|
||||||
//console.log('a', testId, types, values);
|
|
||||||
|
|
||||||
try {
|
|
||||||
var contract = createContractOutput(types, values);
|
|
||||||
var contractInterface = new contracts.Interface(JSON.parse(contract.interface));
|
|
||||||
var call = contractInterface.test.apply(contractInterface);
|
|
||||||
var vm = new ethereumVm();
|
|
||||||
vm.runCode({
|
|
||||||
code: new Buffer(contract.runtimeBytecode, 'hex'),
|
|
||||||
data: new Buffer(call.data.substring(2), 'hex'),
|
|
||||||
gasLimit: '0x80000000'
|
|
||||||
|
|
||||||
}, function(error, result) {
|
|
||||||
delete remaining[testId];
|
|
||||||
// Use this when contract hangs (see the above try)
|
|
||||||
//console.log('b', testId, Object.keys(remaining).join(','));
|
|
||||||
|
|
||||||
try {
|
|
||||||
var vmData = '0x' + result.return.toString('hex');
|
|
||||||
test.equal(ethersData, vmData, 'Failed to generate same output as VM');
|
|
||||||
if (ethersData !== vmData) {
|
|
||||||
console.log('\n\n');
|
|
||||||
console.log(contract.sourceCode);
|
|
||||||
console.log({
|
|
||||||
types: types,
|
|
||||||
values: values
|
|
||||||
});
|
|
||||||
console.log('ethers=');
|
|
||||||
dumpHex(ethersData);
|
|
||||||
console.log('vm=');
|
|
||||||
dumpHex('0x' + result.return.toString('hex'));
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
} catch(error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch(error) {
|
|
||||||
console.log(error);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test cases: https://github.com/ethereum/solidity.js/blob/master/test/coder.decodeParam.js
|
|
||||||
check(['int'], [new BN(1)]);
|
|
||||||
check(['int'], [new BN(16)]);
|
|
||||||
check(['int'], [new BN(-1)]);
|
|
||||||
check(['int256'], [new BN(1)]);
|
|
||||||
check(['int256'], [new BN(16)]);
|
|
||||||
check(['int256'], [new BN(-1)]);
|
|
||||||
check(['int8'], [new BN(16)]);
|
|
||||||
check(['int32'], [new BN(16)]);
|
|
||||||
check(['int64'], [new BN(16)]);
|
|
||||||
check(['int128'], [new BN(16)]);
|
|
||||||
|
|
||||||
check(['uint'], [new BN(1)]);
|
|
||||||
check(['uint'], [new BN(16)]);
|
|
||||||
check(['uint'], [new BN(-1)], [new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)]);
|
|
||||||
check(['uint256'], [new BN(1)]);
|
|
||||||
check(['uint256'], [new BN(16)]);
|
|
||||||
check(['uint256'], [new BN(-1)], [new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)]);
|
|
||||||
check(['uint8'], [new BN(16)]);
|
|
||||||
check(['uint32'], [new BN(16)]);
|
|
||||||
check(['uint64'], [new BN(16)]);
|
|
||||||
check(['uint128'], [new BN(16)]);
|
|
||||||
|
|
||||||
check(['int', 'int'], [new BN(1), new BN(2)]);
|
|
||||||
check(['int', 'int'], [new BN(1), new BN(2)]);
|
|
||||||
check(['int[2]', 'int'], [[new BN(12), new BN(22)], new BN(3)]);
|
|
||||||
check(['int[2]', 'int[]'], [[new BN(32), new BN(42)], [new BN(3), new BN(4), new BN(5)]]);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['bytes32'],
|
|
||||||
['0x6761766f66796f726b0000000000000000000000000000000000000000000000']
|
|
||||||
);
|
|
||||||
check(
|
|
||||||
['bytes'],
|
|
||||||
[new Buffer('6761766f66796f726b', 'hex')]
|
|
||||||
);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['string'],
|
|
||||||
['\uD835\uDF63']
|
|
||||||
);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['address', 'string', 'bytes6[4]', 'int'],
|
|
||||||
[
|
|
||||||
"0x97916ef549947a3e0d321485a31dd2715a97d455",
|
|
||||||
"foobar2",
|
|
||||||
["0xa165ab0173c6", "0xf0f37bee9244", "0xc8dc0bf08d2b", "0xc8dc0bf08d2b"],
|
|
||||||
34
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['bytes32'],
|
|
||||||
['0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b']
|
|
||||||
);
|
|
||||||
check(
|
|
||||||
['bytes'],
|
|
||||||
[new Buffer('731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b')]
|
|
||||||
);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['bytes32[2]'],
|
|
||||||
[['0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b',
|
|
||||||
'0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b']]
|
|
||||||
);
|
|
||||||
|
|
||||||
check(
|
|
||||||
['bytes'],
|
|
||||||
[new Buffer('131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' +
|
|
||||||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' +
|
|
||||||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b')]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Some extra checks for width and sign tests
|
|
||||||
check(['uint32'], [14], [new BN(14)]);
|
|
||||||
check(['uint32'], [14], [new BN(14)]);
|
|
||||||
check(['uint32'], [-14], [new BN(0xfffffff2)]);
|
|
||||||
check(['int32'], [14], [new BN(14)]);
|
|
||||||
check(['int32'], [-14], [new BN(-14)]);
|
|
||||||
|
|
||||||
check(['int8'], [new BN(1)], [new BN(1)]);
|
|
||||||
check(['int8'], [new BN(-1)], [new BN(-1)]);
|
|
||||||
check(['int8'], [new BN(189)], [new BN(-67)]);
|
|
||||||
check(['int8'], [new BN(-189)], [new BN(67)]);
|
|
||||||
check(['int8'], [new BN(257)], [new BN(1)]);
|
|
||||||
|
|
||||||
check(['uint8'], [new BN(343)], [new BN(87)]);
|
|
||||||
check(['uint8'], [new BN(-1)], [new BN(255)]);
|
|
||||||
|
|
||||||
check(['uint56[5]'], [[new BN(639), new BN(227), new BN(727), new BN(325), new BN(146)]]);
|
|
||||||
|
|
||||||
function randomTypeValue(onlyStatic) {
|
|
||||||
switch (random(0, (onlyStatic ? 5: 8))) {
|
|
||||||
case 0:
|
|
||||||
var size = random(1, 33);
|
|
||||||
return {
|
|
||||||
type: 'bytes' + size,
|
|
||||||
value: function() {
|
|
||||||
var value = '0x' + utils.randomBuffer(size).toString('hex');
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
var signed = (random(0, 2) === 0);
|
|
||||||
var type = (!signed ? 'u': '') + 'int';
|
|
||||||
var size = 32;
|
|
||||||
if (random(0, 4) > 0) {
|
|
||||||
size = random(1, 33)
|
|
||||||
type += (8 * size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: type,
|
|
||||||
value: function() {
|
|
||||||
var mask = '';
|
|
||||||
for (var i = 0; i < size; i++) { mask += 'ff'; }
|
|
||||||
|
|
||||||
var value = random(-500, 1000);
|
|
||||||
var normalized = (new BN(value)).toTwos(size * 8).and(new BN(mask, 16));
|
|
||||||
if (signed) {
|
|
||||||
normalized = normalized.fromTwos(size * 8);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: normalized
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
return {
|
|
||||||
type: 'address',
|
|
||||||
value: function() {
|
|
||||||
var value = '0x' + utils.randomBuffer(20).toString('hex');
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
return {
|
|
||||||
type: 'bool',
|
|
||||||
value: function() {
|
|
||||||
var value = (random(0, 2) === 0);
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 4:
|
|
||||||
var size = random(1, 6); /// @TODO: Support random(0, 6)... Why is that even possible?
|
|
||||||
var subTypeValue = randomTypeValue(true);
|
|
||||||
return {
|
|
||||||
type: subTypeValue.type + '[' + size + ']',
|
|
||||||
value: function() {
|
|
||||||
var values = [];
|
|
||||||
var normalized = [];
|
|
||||||
for (var i = 0; i < size; i++) {
|
|
||||||
var value = subTypeValue.value();
|
|
||||||
values.push(value.value);
|
|
||||||
normalized.push(value.normalized);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
value: values,
|
|
||||||
normalized: normalized
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
return {
|
|
||||||
type: 'bytes',
|
|
||||||
value: function() {
|
|
||||||
var value = utils.randomBuffer(random(0, 100));
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: value
|
|
||||||
};
|
|
||||||
},
|
|
||||||
skip: 0
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
var text = 'abcdefghijklmnopqrstuvwxyz\u2014ABCDEFGHIJKLMNOPQRSTUVWXYZFOOBARfoobar'
|
|
||||||
return {
|
|
||||||
type: 'string',
|
|
||||||
value: function() {
|
|
||||||
var value = text.substring(0, random(0, 60));
|
|
||||||
return {
|
|
||||||
value: value,
|
|
||||||
normalized: value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 7:
|
|
||||||
var size = random(1, 6); // @TODO: bug in solidity or VM prevents this from being 0
|
|
||||||
var subTypeValue = randomTypeValue(true);
|
|
||||||
return {
|
|
||||||
type: subTypeValue.type + '[]',
|
|
||||||
value: function() {
|
|
||||||
var values = [];
|
|
||||||
var normalized = [];
|
|
||||||
for (var i = 0; i < size; i++) {
|
|
||||||
var value = subTypeValue.value();
|
|
||||||
values.push(value.value);
|
|
||||||
normalized.push(value.normalized);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
value: values,
|
|
||||||
normalized: normalized
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @TODO: Test 0 arguments
|
|
||||||
|
|
||||||
// Create a bunch of random test cases
|
|
||||||
for (var i = 0; i < 1000; i++) {
|
|
||||||
var count = random(1, 4);
|
|
||||||
var types = [], values = [], normalized = [];;
|
|
||||||
for (var j = 0; j < count; j++) {
|
|
||||||
var type = randomTypeValue();
|
|
||||||
types.push(type.type);
|
|
||||||
var value = type.value();
|
|
||||||
values.push(value.value);
|
|
||||||
normalized.push(value.normalized);
|
|
||||||
}
|
|
||||||
check(types, values, normalized);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bug in solidity or in the VM, not sure, but this fails
|
|
||||||
// check(['uint8[4][]'], [ [] ]);
|
|
||||||
|
|
||||||
Promise.all(checkPromises).then(function(results) {
|
|
||||||
test.done();
|
|
||||||
}, function(error) {
|
|
||||||
console.log('ERROR', error);
|
|
||||||
test.done();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
var ethersWallet = require('../wallet/index.js');
|
|
||||||
var ethereumTx = require('ethereumjs-tx');
|
|
||||||
|
|
||||||
var convert = require('../utils/convert.js');
|
|
||||||
|
|
||||||
var utils = require('./utils.js');
|
|
||||||
|
|
||||||
|
|
||||||
function randomHexString(lowerRandomInterval, upperOpenInterval) {
|
|
||||||
return utils.randomHexString(utils.random(lowerRandomInterval, upperOpenInterval));
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(test) {
|
|
||||||
|
|
||||||
function testTransaction(privateKey, transaction, signature) {
|
|
||||||
//console.log('===================');
|
|
||||||
//console.log(transaction);
|
|
||||||
var rawTransaction = new ethereumTx(transaction);
|
|
||||||
rawTransaction.sign(privateKey);
|
|
||||||
var ethereumLib = '0x' + rawTransaction.serialize().toString('hex');
|
|
||||||
|
|
||||||
var wallet = new ethersWallet('0x' + privateKey.toString('hex'));
|
|
||||||
var ethers = wallet.sign(transaction);
|
|
||||||
test.equal(ethers, ethereumLib, 'invalid transaction');
|
|
||||||
|
|
||||||
var parsedTransaction = ethersWallet.parseTransaction(ethers);
|
|
||||||
if (wallet.address != parsedTransaction.from) {
|
|
||||||
console.log('FOO', wallet.address, parsedTransaction.from);
|
|
||||||
console.log('RAW', privateKey, transaction, signature, rawTransaction.raw);
|
|
||||||
}
|
|
||||||
test.equal(wallet.address, parsedTransaction.from, 'invalid parseTransaction - from');
|
|
||||||
|
|
||||||
['to', 'data', 'gasLimit', 'gasPrice', 'value', 'nonce'].forEach(function(key) {
|
|
||||||
var a = convert.hexlify(transaction[key] || []).toLowerCase();
|
|
||||||
var b = convert.hexlify(parsedTransaction[key] || []).toLowerCase();
|
|
||||||
|
|
||||||
if (key !== 'to') {
|
|
||||||
a = convert.hexlify(convert.stripZeros(a));
|
|
||||||
b = convert.hexlify(convert.stripZeros(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
test.equal(a, b, 'invalid parseTransaction - ' + key);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < 10000; i++) {
|
|
||||||
var transaction = {
|
|
||||||
to: utils.randomHexString(20),
|
|
||||||
data: randomHexString(0, 10),
|
|
||||||
gasLimit: randomHexString(0, 10),
|
|
||||||
gasPrice: randomHexString(0, 10),
|
|
||||||
value: randomHexString(0, 10),
|
|
||||||
nonce: randomHexString(0, 3),
|
|
||||||
};
|
|
||||||
|
|
||||||
testTransaction(utils.randomBuffer(32), transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See: https://github.com/ethereumjs/ethereumjs-tx/blob/master/test/txs.json
|
|
||||||
testTransaction(new Buffer('164122e5d39e9814ca723a749253663bafb07f6af91704d9754c361eb315f0c1', 'hex'), {
|
|
||||||
nonce: "0x",
|
|
||||||
gasPrice: "0x09184e72a000",
|
|
||||||
gasLimit: "0x2710",
|
|
||||||
to: "0x0000000000000000000000000000000000000000",
|
|
||||||
value: "0x",
|
|
||||||
data: "0x7f7465737432000000000000000000000000000000000000000000000000000000600057",
|
|
||||||
}, {
|
|
||||||
v: "0x1c",
|
|
||||||
r: "0x5e1d3a76fbf824220eafc8c79ad578ad2b67d01b0c2425eb1f1347e8f50882ab",
|
|
||||||
s: "0x5bd428537f05f9830e93792f90ea6a3e2d1ee84952dd96edbae9f658f831ab13"
|
|
||||||
});
|
|
||||||
|
|
||||||
testTransaction(new Buffer('e0a462586887362a18a318b128dbc1e3a0cae6d4b0739f5d0419ec25114bc722', 'hex'), {
|
|
||||||
nonce: "0x06",
|
|
||||||
gasPrice: "0x09184e72a000",
|
|
||||||
gasLimit: "0x01f4",
|
|
||||||
to: "0xbe862ad9abfe6f22bcb087716c7d89a26051f74c",
|
|
||||||
value: "0x016345785d8a0000",
|
|
||||||
data: "0x",
|
|
||||||
}, {
|
|
||||||
v: "0x1c",
|
|
||||||
r: "0x24a484bfa7380860e9fa0a9f5e4b64b985e860ca31abd36e66583f9030c2e29d",
|
|
||||||
s: "0x4d5ef07d9e73fa2fbfdad059591b4f13d0aa79e7634a2bb00174c9200cabb04d"
|
|
||||||
});
|
|
||||||
|
|
||||||
testTransaction(new Buffer('164122e5d39e9814ca723a749253663bafb07f6af91704d9754c361eb315f0c1', 'hex'), {
|
|
||||||
nonce: "0x06",
|
|
||||||
gasPrice: "0x09184e72a000",
|
|
||||||
gasLimit: "0x0974",
|
|
||||||
to: "0xbe862ad9abfe6f22bcb087716c7d89a26051f74c",
|
|
||||||
value: "0x016345785d8a0000",
|
|
||||||
data: "0x00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000fafa0000000000000000000000000000000000000000000000000000000000000dfa0000000000000000000000000000000000000000000000000000000000000dfa00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000df000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000d",
|
|
||||||
}, {
|
|
||||||
v: "0x1c",
|
|
||||||
r: "0x5e9361ca27e14f3af0e6b28466406ad8be026d3b0f2ae56e3c064043fb73ec77",
|
|
||||||
s: "0x29ae9893dac4f9afb1af743e25fbb6a63f7879a61437203cb48c997b0fcefc3a"
|
|
||||||
});
|
|
||||||
|
|
||||||
// Test all possible blank fields
|
|
||||||
var privateKey = new Buffer('0123456789012345678901234567890123456789012345678901234567890123', 'hex');
|
|
||||||
for (var i = 0; i < 64; i++) {
|
|
||||||
var transaction = {};
|
|
||||||
if (i & (1 << 0)) { transaction.nonce = '0x02'; }
|
|
||||||
if (i & (1 << 1)) { transaction.gasPrice = '0x03'; }
|
|
||||||
if (i & (1 << 2)) { transaction.gasLimit = '0x04'; }
|
|
||||||
if (i & (1 << 3)) { transaction.to = '0x0123456789012345678901234567890123456789'; }
|
|
||||||
if (i & (1 << 4)) { transaction.value = '0x05'; }
|
|
||||||
if (i & (1 << 5)) { transaction.data = '0x06'; }
|
|
||||||
testTransaction(privateKey, transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
test.done();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.testSelf = module.exports;
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user