Beta 7 with some repo names changed.
This commit is contained in:
1 parent
0f7b40cca7
commit
963c19493a
3408 files changed
+462217
-15516
No files matched your search
+104
@@ -0,0 +1,104 @@
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
var Bytes = require("./bytes");
|
||||
var Nat = require("./nat");
|
||||
var elliptic = require("elliptic");
|
||||
var rlp = require("./rlp");
|
||||
var secp256k1 = new elliptic.ec("secp256k1"); // eslint-disable-line
|
||||
|
||||
var _require = require("./hash"),
|
||||
keccak256 = _require.keccak256,
|
||||
keccak256s = _require.keccak256s;
|
||||
|
||||
var create = function create(entropy) {
|
||||
var innerHex = keccak256(Bytes.concat(Bytes.random(32), entropy || Bytes.random(32)));
|
||||
var middleHex = Bytes.concat(Bytes.concat(Bytes.random(32), innerHex), Bytes.random(32));
|
||||
var outerHex = keccak256(middleHex);
|
||||
return fromPrivate(outerHex);
|
||||
};
|
||||
|
||||
var toChecksum = function toChecksum(address) {
|
||||
var addressHash = keccak256s(address.slice(2));
|
||||
var checksumAddress = "0x";
|
||||
for (var i = 0; i < 40; i++) {
|
||||
checksumAddress += parseInt(addressHash[i + 2], 16) > 7 ? address[i + 2].toUpperCase() : address[i + 2];
|
||||
}return checksumAddress;
|
||||
};
|
||||
|
||||
var fromPrivate = function fromPrivate(privateKey) {
|
||||
var buffer = new Buffer(privateKey.slice(2), "hex");
|
||||
var ecKey = secp256k1.keyFromPrivate(buffer);
|
||||
var publicKey = "0x" + ecKey.getPublic(false, 'hex').slice(2);
|
||||
var publicHash = keccak256(publicKey);
|
||||
var address = toChecksum("0x" + publicHash.slice(-40));
|
||||
return {
|
||||
address: address,
|
||||
privateKey: privateKey
|
||||
};
|
||||
};
|
||||
|
||||
var encodeSignature = function encodeSignature(_ref) {
|
||||
var _ref2 = _slicedToArray(_ref, 3),
|
||||
v = _ref2[0],
|
||||
r = _ref2[1],
|
||||
s = _ref2[2];
|
||||
|
||||
return Bytes.flatten([r, s, v]);
|
||||
};
|
||||
|
||||
var decodeSignature = function decodeSignature(hex) {
|
||||
return [Bytes.slice(64, 65, hex), Bytes.slice(0, 32, hex), Bytes.slice(32, 64, hex)];
|
||||
};
|
||||
|
||||
var makeSign = function makeSign(addToV) {
|
||||
return function (hash, privateKey) {
|
||||
var signature = secp256k1.keyFromPrivate(new Buffer(privateKey.slice(2), "hex")).sign(new Buffer(hash.slice(2), "hex"), { canonical: true });
|
||||
return encodeSignature([Bytes.pad(1, Bytes.fromNumber(addToV + signature.recoveryParam)), Bytes.pad(32, Bytes.fromNat("0x" + signature.r.toString(16))), Bytes.pad(32, Bytes.fromNat("0x" + signature.s.toString(16)))]);
|
||||
};
|
||||
};
|
||||
|
||||
var sign = makeSign(27); // v=27|28 instead of 0|1...
|
||||
|
||||
var recover = function recover(hash, signature) {
|
||||
var vals = decodeSignature(signature);
|
||||
var vrs = { v: Bytes.toNumber(vals[0]), r: vals[1].slice(2), s: vals[2].slice(2) };
|
||||
var ecPublicKey = secp256k1.recoverPubKey(new Buffer(hash.slice(2), "hex"), vrs, vrs.v < 2 ? vrs.v : 1 - vrs.v % 2); // because odd vals mean v=0... sadly that means v=0 means v=1... I hate that
|
||||
var publicKey = "0x" + ecPublicKey.encode("hex", false).slice(2);
|
||||
var publicHash = keccak256(publicKey);
|
||||
var address = toChecksum("0x" + publicHash.slice(-40));
|
||||
return address;
|
||||
};
|
||||
|
||||
var transactionSigningData = function transactionSigningData(tx) {
|
||||
return rlp.encode([Bytes.fromNat(tx.nonce), Bytes.fromNat(tx.gasPrice), Bytes.fromNat(tx.gas), tx.to.toLowerCase(), Bytes.fromNat(tx.value), tx.data, Bytes.fromNat(tx.chainId || "0x1"), "0x", "0x"]);
|
||||
};
|
||||
|
||||
var signTransaction = function signTransaction(tx, privateKey) {
|
||||
var signingData = transactionSigningData(tx);
|
||||
var signature = makeSign(Nat.toNumber(tx.chainId || "0x1") * 2 + 35)(keccak256(signingData), privateKey);
|
||||
var rawTransaction = rlp.decode(signingData).slice(0, 6).concat(decodeSignature(signature));
|
||||
return rlp.encode(rawTransaction);
|
||||
};
|
||||
|
||||
var recoverTransaction = function recoverTransaction(rawTransaction) {
|
||||
var values = rlp.decode(rawTransaction);
|
||||
var signature = encodeSignature(values.slice(6, 9));
|
||||
var recovery = Bytes.toNumber(values[6]);
|
||||
var extraData = recovery < 35 ? [] : [Bytes.fromNumber(recovery - 35 >> 1), "0x", "0x"];
|
||||
var signingData = values.slice(0, 6).concat(extraData);
|
||||
var signingDataHex = rlp.encode(signingData);
|
||||
return recover(keccak256(signingDataHex), signature);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
create: create,
|
||||
toChecksum: toChecksum,
|
||||
fromPrivate: fromPrivate,
|
||||
sign: sign,
|
||||
recover: recover,
|
||||
signTransaction: signTransaction,
|
||||
recoverTransaction: recoverTransaction,
|
||||
transactionSigningData: transactionSigningData,
|
||||
encodeSignature: encodeSignature,
|
||||
decodeSignature: decodeSignature
|
||||
};
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
var Api = function Api(provider) {
|
||||
var Nat = require("./nat");
|
||||
var Map = require("./map");
|
||||
var Bytes = require("./bytes");
|
||||
var keccak256s = require("./hash").keccak256s;
|
||||
var send = function send(method) {
|
||||
return function () {
|
||||
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
params[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
return provider.send(method, params, function (err, result) {
|
||||
return err ? reject(err) : resolve(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// TODO check inputs
|
||||
// TODO move to proper file
|
||||
var encodeABI = function encodeABI(type, value) {
|
||||
if (type === "bytes") {
|
||||
var length = Bytes.length(value);
|
||||
var nextMul32 = (((length - 1) / 32 | 0) + 1) * 32;
|
||||
var lengthEncoded = encodeABI("uint256", Nat.fromNumber(length)).data;
|
||||
var bytesEncoded = Bytes.padRight(nextMul32, value);
|
||||
return { data: Bytes.concat(lengthEncoded, bytesEncoded), dynamic: true };
|
||||
} else if (type === "uint256" || type === "bytes32") {
|
||||
return { data: Bytes.pad(32, value), dynamic: false };
|
||||
} else {
|
||||
throw "Eth-lib can't encode ABI type " + type + " yet.";
|
||||
}
|
||||
};
|
||||
|
||||
var sendTransaction = send("eth_sendTransaction");
|
||||
var sendRawTransaction = send("eth_sendRawTransaction");
|
||||
var getTransactionReceipt = send("eth_getTransactionReceipt");
|
||||
var compileSolidity = send("eth_compileSolidity");
|
||||
var call = send("eth_call");
|
||||
var getBalance = send("eth_getBalance");
|
||||
var accounts = send("eth_accounts");
|
||||
|
||||
var removeEmptyTo = function removeEmptyTo(tx) {
|
||||
return tx.to === "" || tx.to === "0x" ? Map.remove("to")(tx) : tx;
|
||||
};
|
||||
|
||||
var waitTransactionReceipt = getTransactionReceipt; // TODO: implement correctly
|
||||
|
||||
var addTransactionDefaults = function addTransactionDefaults(tx) {
|
||||
return (
|
||||
// Get basic defaults
|
||||
Promise.all([tx.chainId || send("net_version")(), tx.gasPrice || send("eth_gasPrice")(), tx.nonce || send("eth_getTransactionCount")(tx.from, "latest"), tx.value || "0x0", tx.data || "0x"])
|
||||
// Add them to tx
|
||||
.then(function (_ref) {
|
||||
var _ref2 = _slicedToArray(_ref, 5),
|
||||
chainId = _ref2[0],
|
||||
gasPrice = _ref2[1],
|
||||
nonce = _ref2[2],
|
||||
value = _ref2[3],
|
||||
data = _ref2[4];
|
||||
|
||||
return Map.merge(tx)({ chainId: Nat.fromNumber(chainId), gasPrice: gasPrice, nonce: nonce, value: value, data: data });
|
||||
}).then(function (tx) {
|
||||
// Add gas default by estimating
|
||||
if (!tx.gas) {
|
||||
var estimateTx = {};
|
||||
estimateTx.from = tx.from;
|
||||
if (tx.to !== "" && tx.to !== "0x") estimateTx.to = tx.to;
|
||||
estimateTx.value = tx.value;
|
||||
estimateTx.nonce = tx.nonce;
|
||||
estimateTx.data = tx.data;
|
||||
return send("eth_estimateGas")(estimateTx).then(function (usedGas) {
|
||||
return Map.merge(tx)({ gas: Nat.div(Nat.mul(usedGas, "0x6"), "0x5") });
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve(tx);
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
var sendTransactionWithDefaults = function sendTransactionWithDefaults(tx) {
|
||||
return addTransactionDefaults(tx).then(function (tx) {
|
||||
return sendTransaction(removeEmptyTo(tx));
|
||||
});
|
||||
};
|
||||
|
||||
var callWithDefaults = function callWithDefaults(tx, block) {
|
||||
return addTransactionDefaults(tx).then(function (tx) {
|
||||
return call(removeEmptyTo(tx), block || "latest");
|
||||
});
|
||||
};
|
||||
|
||||
var callMethodData = function callMethodData(method) {
|
||||
return function () {
|
||||
for (var _len2 = arguments.length, params = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
||||
params[_key2] = arguments[_key2];
|
||||
}
|
||||
|
||||
var methodSig = method.name + "(" + method.inputs.map(function (i) {
|
||||
return i.type;
|
||||
}).join(",") + ")";
|
||||
var methodHash = keccak256s(methodSig).slice(0, 10);
|
||||
var encodedParams = params.map(function (param, i) {
|
||||
return encodeABI(method.inputs[i].type, param);
|
||||
});
|
||||
var headBlock = "0x";
|
||||
var dataBlock = "0x";
|
||||
for (var i = 0; i < encodedParams.length; ++i) {
|
||||
if (encodedParams[i].dynamic) {
|
||||
var dataLoc = encodedParams.length * 32 + Bytes.length(dataBlock);
|
||||
headBlock = Bytes.concat(headBlock, Bytes.pad(32, Nat.fromNumber(dataLoc)));
|
||||
dataBlock = Bytes.concat(dataBlock, encodedParams[i].data);
|
||||
} else {
|
||||
headBlock = Bytes.concat(headBlock, encodedParams[i].data);
|
||||
}
|
||||
}
|
||||
return Bytes.flatten([methodHash, headBlock, dataBlock]);
|
||||
};
|
||||
};
|
||||
|
||||
// Address, Address, ContractInterface -> Contract
|
||||
var contract = function contract(from, address, contractInterface) {
|
||||
var contract = {};
|
||||
contract._address = address;
|
||||
contract._from = from;
|
||||
contract.broadcast = {};
|
||||
contractInterface.forEach(function (method) {
|
||||
if (method && method.name) {
|
||||
var _call = function _call(type, value) {
|
||||
return function () {
|
||||
var transaction = {
|
||||
from: from,
|
||||
to: address,
|
||||
value: value,
|
||||
data: callMethodData(method).apply(undefined, arguments)
|
||||
};
|
||||
return type === "data" ? Promise.resolve(transaction) : method.constant ? callWithDefaults(transaction) : sendTransactionWithDefaults(transaction).then(type === "receipt" ? waitTransactionReceipt : function (x) {
|
||||
return x;
|
||||
});
|
||||
};
|
||||
};
|
||||
contract[method.name] = _call("receipt", "0x0");
|
||||
if (!method.constant) {
|
||||
contract[method.name + "_data"] = _call("data", "0x0");
|
||||
contract[method.name + "_pay"] = function (value) {
|
||||
return function () {
|
||||
return _call("receipt", value).apply(undefined, arguments);
|
||||
};
|
||||
};
|
||||
contract[method.name + "_pay_txHash"] = function (value) {
|
||||
return function () {
|
||||
return _call("txHash", value).apply(undefined, arguments);
|
||||
};
|
||||
};
|
||||
contract[method.name + "_txHash"] = _call("txHash", "0x0");
|
||||
}
|
||||
}
|
||||
});
|
||||
return contract;
|
||||
};
|
||||
|
||||
// Address, Bytecode -> TxHash
|
||||
var deployBytecode_txHash = function deployBytecode_txHash(from, code) {
|
||||
return sendTransactionWithDefaults({ from: from, data: code, to: "" });
|
||||
};
|
||||
|
||||
// Address, Bytecode -> Receipt
|
||||
var deployBytecode = function deployBytecode(from, code) {
|
||||
return deployBytecode_txHash(from, code).then(waitTransactionReceipt);
|
||||
};
|
||||
|
||||
// Address, Bytecode, ContractInterface
|
||||
var deployBytecodeContract = function deployBytecodeContract(from, code, contractInterface) {
|
||||
return deployBytecode(from, code).then(function (receipt) {
|
||||
return contract(from, receipt.contractAddress, contractInterface);
|
||||
});
|
||||
};
|
||||
|
||||
// Address, String, Address -> Contract
|
||||
var solidityContract = function solidityContract(from, source, at) {
|
||||
return compileSolidity(source).then(function (_ref3) {
|
||||
var abiDefinition = _ref3.info.abiDefinition;
|
||||
return contract(from, at, abiDefinition);
|
||||
});
|
||||
};
|
||||
|
||||
// Address, String -> TxHash
|
||||
var deploySolidity_txHash = function deploySolidity_txHash(from, source) {
|
||||
return compileSolidity(source).then(function (_ref4) {
|
||||
var code = _ref4.code;
|
||||
return deployBytecode_txHash(from, code);
|
||||
});
|
||||
};
|
||||
|
||||
// Address, String -> Receipt
|
||||
var deploySolidity = function deploySolidity(from, source) {
|
||||
return deploySolidity_txHash(from, source).then(waitTransactionReceipt);
|
||||
};
|
||||
|
||||
// Address, String -> Contract
|
||||
var deploySolidityContract = function deploySolidityContract(from, source) {
|
||||
return compileSolidity(source).then(function (_ref5) {
|
||||
var code = _ref5.code,
|
||||
abiDefinition = _ref5.info.abiDefinition;
|
||||
return deployBytecodeContract(from, code, abiDefinition);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
send: send,
|
||||
|
||||
sendTransaction: sendTransaction,
|
||||
sendRawTransaction: sendRawTransaction,
|
||||
getTransactionReceipt: getTransactionReceipt,
|
||||
call: call,
|
||||
getBalance: getBalance,
|
||||
accounts: accounts,
|
||||
|
||||
waitTransactionReceipt: waitTransactionReceipt,
|
||||
addTransactionDefaults: addTransactionDefaults,
|
||||
sendTransactionWithDefaults: sendTransactionWithDefaults,
|
||||
callWithDefaults: callWithDefaults,
|
||||
callMethodData: callMethodData,
|
||||
|
||||
contract: contract,
|
||||
deployBytecode_txHash: deployBytecode_txHash,
|
||||
deployBytecode: deployBytecode,
|
||||
deployBytecodeContract: deployBytecodeContract,
|
||||
|
||||
compileSolidity: compileSolidity,
|
||||
solidityContract: solidityContract,
|
||||
deploySolidity_txHash: deploySolidity_txHash,
|
||||
deploySolidity: deploySolidity,
|
||||
deploySolidityContract: deploySolidityContract
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Api;
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
var generate = function generate(num, fn) {
|
||||
var a = [];
|
||||
for (var i = 0; i < num; ++i) {
|
||||
a.push(fn(i));
|
||||
}return a;
|
||||
};
|
||||
|
||||
var replicate = function replicate(num, val) {
|
||||
return generate(num, function () {
|
||||
return val;
|
||||
});
|
||||
};
|
||||
|
||||
var concat = function concat(a, b) {
|
||||
return a.concat(b);
|
||||
};
|
||||
|
||||
var flatten = function flatten(a) {
|
||||
var r = [];
|
||||
for (var j = 0, J = a.length; j < J; ++j) {
|
||||
for (var i = 0, I = a[j].length; i < I; ++i) {
|
||||
r.push(a[j][i]);
|
||||
}
|
||||
}return r;
|
||||
};
|
||||
|
||||
var chunksOf = function chunksOf(n, a) {
|
||||
var b = [];
|
||||
for (var i = 0, l = a.length; i < l; i += n) {
|
||||
b.push(a.slice(i, i + n));
|
||||
}return b;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
generate: generate,
|
||||
replicate: replicate,
|
||||
concat: concat,
|
||||
flatten: flatten,
|
||||
chunksOf: chunksOf
|
||||
};
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
var A = require("./array.js");
|
||||
|
||||
var at = function at(bytes, index) {
|
||||
return parseInt(bytes.slice(index * 2 + 2, index * 2 + 4), 16);
|
||||
};
|
||||
|
||||
var random = function random(bytes) {
|
||||
var rnd = void 0;
|
||||
if (typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues) rnd = window.crypto.getRandomValues(new Uint8Array(bytes));else if (typeof require !== "undefined") rnd = require("c" + "rypto").randomBytes(bytes);else throw "Safe random numbers not available.";
|
||||
var hex = "0x";
|
||||
for (var i = 0; i < bytes; ++i) {
|
||||
hex += ("00" + rnd[i].toString(16)).slice(-2);
|
||||
}return hex;
|
||||
};
|
||||
|
||||
var length = function length(a) {
|
||||
return (a.length - 2) / 2;
|
||||
};
|
||||
|
||||
var flatten = function flatten(a) {
|
||||
return "0x" + a.reduce(function (r, s) {
|
||||
return r + s.slice(2);
|
||||
}, "");
|
||||
};
|
||||
|
||||
var slice = function slice(i, j, bs) {
|
||||
return "0x" + bs.slice(i * 2 + 2, j * 2 + 2);
|
||||
};
|
||||
|
||||
var reverse = function reverse(hex) {
|
||||
var rev = "0x";
|
||||
for (var i = 0, l = length(hex); i < l; ++i) {
|
||||
rev += hex.slice((l - i) * 2, (l - i + 1) * 2);
|
||||
}
|
||||
return rev;
|
||||
};
|
||||
|
||||
var pad = function pad(l, hex) {
|
||||
return hex.length === l * 2 + 2 ? hex : pad(l, "0x" + "0" + hex.slice(2));
|
||||
};
|
||||
|
||||
var padRight = function padRight(l, hex) {
|
||||
return hex.length === l * 2 + 2 ? hex : padRight(l, hex + "0");
|
||||
};
|
||||
|
||||
var toArray = function toArray(hex) {
|
||||
var arr = [];
|
||||
for (var i = 2, l = hex.length; i < l; i += 2) {
|
||||
arr.push(parseInt(hex.slice(i, i + 2), 16));
|
||||
}return arr;
|
||||
};
|
||||
|
||||
var fromArray = function fromArray(arr) {
|
||||
var hex = "0x";
|
||||
for (var i = 0, l = arr.length; i < l; ++i) {
|
||||
var b = arr[i];
|
||||
hex += (b < 16 ? "0" : "") + b.toString(16);
|
||||
}
|
||||
return hex;
|
||||
};
|
||||
|
||||
var toUint8Array = function toUint8Array(hex) {
|
||||
return new Uint8Array(toArray(hex));
|
||||
};
|
||||
|
||||
var fromUint8Array = function fromUint8Array(arr) {
|
||||
return fromArray([].slice.call(arr, 0));
|
||||
};
|
||||
|
||||
var fromNumber = function fromNumber(num) {
|
||||
var hex = num.toString(16);
|
||||
return hex.length % 2 === 0 ? "0x" + hex : "0x0" + hex;
|
||||
};
|
||||
|
||||
var toNumber = function toNumber(hex) {
|
||||
return parseInt(hex.slice(2), 16);
|
||||
};
|
||||
|
||||
var concat = function concat(a, b) {
|
||||
return a.concat(b.slice(2));
|
||||
};
|
||||
|
||||
var fromNat = function fromNat(bn) {
|
||||
return bn === "0x0" ? "0x" : bn.length % 2 === 0 ? bn : "0x0" + bn.slice(2);
|
||||
};
|
||||
|
||||
var toNat = function toNat(bn) {
|
||||
return bn[2] === "0" ? "0x" + bn.slice(3) : bn;
|
||||
};
|
||||
|
||||
var fromAscii = function fromAscii(ascii) {
|
||||
var hex = "0x";
|
||||
for (var i = 0; i < ascii.length; ++i) {
|
||||
hex += ("00" + ascii.charCodeAt(i).toString(16)).slice(-2);
|
||||
}return hex;
|
||||
};
|
||||
|
||||
var toAscii = function toAscii(hex) {
|
||||
var ascii = "";
|
||||
for (var i = 2; i < hex.length; i += 2) {
|
||||
ascii += String.fromCharCode(parseInt(hex.slice(i, i + 2), 16));
|
||||
}return ascii;
|
||||
};
|
||||
|
||||
// From https://gist.github.com/pascaldekloe/62546103a1576803dade9269ccf76330
|
||||
var fromString = function fromString(s) {
|
||||
var makeByte = function makeByte(uint8) {
|
||||
var b = uint8.toString(16);
|
||||
return b.length < 2 ? "0" + b : b;
|
||||
};
|
||||
var bytes = "0x";
|
||||
for (var ci = 0; ci != s.length; ci++) {
|
||||
var c = s.charCodeAt(ci);
|
||||
if (c < 128) {
|
||||
bytes += makeByte(c);
|
||||
continue;
|
||||
}
|
||||
if (c < 2048) {
|
||||
bytes += makeByte(c >> 6 | 192);
|
||||
} else {
|
||||
if (c > 0xd7ff && c < 0xdc00) {
|
||||
if (++ci == s.length) return null;
|
||||
var c2 = s.charCodeAt(ci);
|
||||
if (c2 < 0xdc00 || c2 > 0xdfff) return null;
|
||||
c = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
|
||||
bytes += makeByte(c >> 18 | 240);
|
||||
bytes += makeByte(c >> 12 & 63 | 128);
|
||||
} else {
|
||||
// c <= 0xffff
|
||||
bytes += makeByte(c >> 12 | 224);
|
||||
}
|
||||
bytes += makeByte(c >> 6 & 63 | 128);
|
||||
}
|
||||
bytes += makeByte(c & 63 | 128);
|
||||
}
|
||||
return bytes;
|
||||
};
|
||||
|
||||
var toString = function toString(bytes) {
|
||||
var s = '';
|
||||
var i = 0;
|
||||
var l = length(bytes);
|
||||
while (i < l) {
|
||||
var c = at(bytes, i++);
|
||||
if (c > 127) {
|
||||
if (c > 191 && c < 224) {
|
||||
if (i >= l) return null;
|
||||
c = (c & 31) << 6 | at(bytes, i) & 63;
|
||||
} else if (c > 223 && c < 240) {
|
||||
if (i + 1 >= l) return null;
|
||||
c = (c & 15) << 12 | (at(bytes, i) & 63) << 6 | at(bytes, ++i) & 63;
|
||||
} else if (c > 239 && c < 248) {
|
||||
if (i + 2 >= l) return null;
|
||||
c = (c & 7) << 18 | (at(bytes, i) & 63) << 12 | (at(bytes, ++i) & 63) << 6 | at(bytes, ++i) & 63;
|
||||
} else return null;
|
||||
++i;
|
||||
}
|
||||
if (c <= 0xffff) s += String.fromCharCode(c);else if (c <= 0x10ffff) {
|
||||
c -= 0x10000;
|
||||
s += String.fromCharCode(c >> 10 | 0xd800);
|
||||
s += String.fromCharCode(c & 0x3FF | 0xdc00);
|
||||
} else return null;
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
random: random,
|
||||
length: length,
|
||||
concat: concat,
|
||||
flatten: flatten,
|
||||
slice: slice,
|
||||
reverse: reverse,
|
||||
pad: pad,
|
||||
padRight: padRight,
|
||||
fromAscii: fromAscii,
|
||||
toAscii: toAscii,
|
||||
fromString: fromString,
|
||||
toString: toString,
|
||||
fromNumber: fromNumber,
|
||||
toNumber: toNumber,
|
||||
fromNat: fromNat,
|
||||
toNat: toNat,
|
||||
fromArray: fromArray,
|
||||
toArray: toArray,
|
||||
fromUint8Array: fromUint8Array,
|
||||
toUint8Array: toUint8Array
|
||||
};
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
var Bytes = require("./bytes");
|
||||
|
||||
var inis = "pbtdkgxjfvlrmnsz".split("");
|
||||
|
||||
var mids = "auie".split("");
|
||||
|
||||
var back = [inis, mids].map(function (chars) {
|
||||
var map = {};
|
||||
for (var i = 0; i < chars.length; ++i) {
|
||||
map[chars[i]] = i;
|
||||
}return map;
|
||||
});
|
||||
|
||||
var syllableFromB64 = function syllableFromB64(b64) {
|
||||
var ini = b64 >>> 2 & 15;
|
||||
var mid = b64 >>> 0 & 3;
|
||||
return inis[ini] + mids[mid];
|
||||
};
|
||||
|
||||
var syllableToB64 = function syllableToB64(syllable) {
|
||||
var ini = back[0][syllable[0]];
|
||||
var mid = back[1][syllable[1]];
|
||||
return ini * 4 + mid;
|
||||
};
|
||||
|
||||
var b64sFromBytes = function b64sFromBytes(bytes) {
|
||||
//BoooooBoooooBoooooBooooo
|
||||
//BoooooooBoooooooBooooooo
|
||||
var b64s = [],
|
||||
b64 = void 0;
|
||||
for (var i = 0, l = Math.ceil(bytes.length * 8 / 6); i < l; ++i) {
|
||||
var j = i / 8 * 6 | 0;
|
||||
b64s.push(i % 4 === 0 ? bytes[j + 0] / 4 | 0 : i % 4 === 1 ? bytes[j + 0] % 4 * 16 + (bytes[j + 1] / 16 | 0) : i % 4 === 2 ? bytes[j + 0] % 16 * 4 + (bytes[j + 1] / 64 | 0) : bytes[j + 0] % 64 * 1);
|
||||
}
|
||||
return b64s;
|
||||
};
|
||||
|
||||
var b64sToBytes = function b64sToBytes(b64s) {
|
||||
var bytes = [];
|
||||
for (var i = 0, l = Math.floor(b64s.length * 6 / 8); i < l; ++i) {
|
||||
var j = i / 6 * 8 | 0;
|
||||
bytes.push(i % 3 === 0 ? b64s[j + 0] % 64 * 4 + (b64s[j + 1] / 16 | 0) : i % 3 === 1 ? b64s[j + 0] % 16 * 16 + (b64s[j + 1] / 4 | 0) : b64s[j + 0] % 4 * 64 + (b64s[j + 1] / 1 | 0));
|
||||
}
|
||||
return bytes;
|
||||
};
|
||||
|
||||
var fromBytes = function fromBytes(bytes) {
|
||||
return b64sFromBytes(Bytes.toArray(bytes)).map(syllableFromB64).join("");
|
||||
};
|
||||
|
||||
var toBytes = function toBytes(syllables) {
|
||||
return Bytes.fromArray(b64sToBytes(syllables.match(/\w\w/g).map(syllableToB64)));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
fromBytes: fromBytes,
|
||||
toBytes: toBytes
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
var times = function times(n, f, x) {
|
||||
for (var i = 0; i < n; ++i) {
|
||||
x = f(x);
|
||||
}
|
||||
return x;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
times: times
|
||||
};
|
||||
+339
@@ -0,0 +1,339 @@
|
||||
// This was ported from https://github.com/emn178/js-sha3, with some minor
|
||||
// modifications and pruning. It is licensed under MIT:
|
||||
//
|
||||
// Copyright 2015-2016 Chen, Yi-Cyuan
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var HEX_CHARS = '0123456789abcdef'.split('');
|
||||
var KECCAK_PADDING = [1, 256, 65536, 16777216];
|
||||
var SHIFT = [0, 8, 16, 24];
|
||||
var RC = [1, 0, 32898, 0, 32906, 2147483648, 2147516416, 2147483648, 32907, 0, 2147483649, 0, 2147516545, 2147483648, 32777, 2147483648, 138, 0, 136, 0, 2147516425, 0, 2147483658, 0, 2147516555, 0, 139, 2147483648, 32905, 2147483648, 32771, 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
|
||||
|
||||
var Keccak = function Keccak(bits) {
|
||||
return {
|
||||
blocks: [],
|
||||
reset: true,
|
||||
block: 0,
|
||||
start: 0,
|
||||
blockCount: 1600 - (bits << 1) >> 5,
|
||||
outputBlocks: bits >> 5,
|
||||
s: function (s) {
|
||||
return [].concat(s, s, s, s, s);
|
||||
}([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
};
|
||||
};
|
||||
|
||||
var update = function update(state, message) {
|
||||
var length = message.length,
|
||||
blocks = state.blocks,
|
||||
byteCount = state.blockCount << 2,
|
||||
blockCount = state.blockCount,
|
||||
outputBlocks = state.outputBlocks,
|
||||
s = state.s,
|
||||
index = 0,
|
||||
i,
|
||||
code;
|
||||
|
||||
// update
|
||||
while (index < length) {
|
||||
if (state.reset) {
|
||||
state.reset = false;
|
||||
blocks[0] = state.block;
|
||||
for (i = 1; i < blockCount + 1; ++i) {
|
||||
blocks[i] = 0;
|
||||
}
|
||||
}
|
||||
if (typeof message !== "string") {
|
||||
for (i = state.start; index < length && i < byteCount; ++index) {
|
||||
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
|
||||
}
|
||||
} else {
|
||||
for (i = state.start; index < length && i < byteCount; ++index) {
|
||||
code = message.charCodeAt(index);
|
||||
if (code < 0x80) {
|
||||
blocks[i >> 2] |= code << SHIFT[i++ & 3];
|
||||
} else if (code < 0x800) {
|
||||
blocks[i >> 2] |= (0xc0 | code >> 6) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
blocks[i >> 2] |= (0xe0 | code >> 12) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
|
||||
} else {
|
||||
code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);
|
||||
blocks[i >> 2] |= (0xf0 | code >> 18) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code >> 12 & 0x3f) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
|
||||
blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
state.lastByteIndex = i;
|
||||
if (i >= byteCount) {
|
||||
state.start = i - byteCount;
|
||||
state.block = blocks[blockCount];
|
||||
for (i = 0; i < blockCount; ++i) {
|
||||
s[i] ^= blocks[i];
|
||||
}
|
||||
f(s);
|
||||
state.reset = true;
|
||||
} else {
|
||||
state.start = i;
|
||||
}
|
||||
}
|
||||
|
||||
// finalize
|
||||
i = state.lastByteIndex;
|
||||
blocks[i >> 2] |= KECCAK_PADDING[i & 3];
|
||||
if (state.lastByteIndex === byteCount) {
|
||||
blocks[0] = blocks[blockCount];
|
||||
for (i = 1; i < blockCount + 1; ++i) {
|
||||
blocks[i] = 0;
|
||||
}
|
||||
}
|
||||
blocks[blockCount - 1] |= 0x80000000;
|
||||
for (i = 0; i < blockCount; ++i) {
|
||||
s[i] ^= blocks[i];
|
||||
}
|
||||
f(s);
|
||||
|
||||
// toString
|
||||
var hex = '',
|
||||
i = 0,
|
||||
j = 0,
|
||||
block;
|
||||
while (j < outputBlocks) {
|
||||
for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) {
|
||||
block = s[i];
|
||||
hex += HEX_CHARS[block >> 4 & 0x0F] + HEX_CHARS[block & 0x0F] + HEX_CHARS[block >> 12 & 0x0F] + HEX_CHARS[block >> 8 & 0x0F] + HEX_CHARS[block >> 20 & 0x0F] + HEX_CHARS[block >> 16 & 0x0F] + HEX_CHARS[block >> 28 & 0x0F] + HEX_CHARS[block >> 24 & 0x0F];
|
||||
}
|
||||
if (j % blockCount === 0) {
|
||||
f(s);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
return "0x" + hex;
|
||||
};
|
||||
|
||||
var f = function f(s) {
|
||||
var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49;
|
||||
|
||||
for (n = 0; n < 48; n += 2) {
|
||||
c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40];
|
||||
c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41];
|
||||
c2 = s[2] ^ s[12] ^ s[22] ^ s[32] ^ s[42];
|
||||
c3 = s[3] ^ s[13] ^ s[23] ^ s[33] ^ s[43];
|
||||
c4 = s[4] ^ s[14] ^ s[24] ^ s[34] ^ s[44];
|
||||
c5 = s[5] ^ s[15] ^ s[25] ^ s[35] ^ s[45];
|
||||
c6 = s[6] ^ s[16] ^ s[26] ^ s[36] ^ s[46];
|
||||
c7 = s[7] ^ s[17] ^ s[27] ^ s[37] ^ s[47];
|
||||
c8 = s[8] ^ s[18] ^ s[28] ^ s[38] ^ s[48];
|
||||
c9 = s[9] ^ s[19] ^ s[29] ^ s[39] ^ s[49];
|
||||
|
||||
h = c8 ^ (c2 << 1 | c3 >>> 31);
|
||||
l = c9 ^ (c3 << 1 | c2 >>> 31);
|
||||
s[0] ^= h;
|
||||
s[1] ^= l;
|
||||
s[10] ^= h;
|
||||
s[11] ^= l;
|
||||
s[20] ^= h;
|
||||
s[21] ^= l;
|
||||
s[30] ^= h;
|
||||
s[31] ^= l;
|
||||
s[40] ^= h;
|
||||
s[41] ^= l;
|
||||
h = c0 ^ (c4 << 1 | c5 >>> 31);
|
||||
l = c1 ^ (c5 << 1 | c4 >>> 31);
|
||||
s[2] ^= h;
|
||||
s[3] ^= l;
|
||||
s[12] ^= h;
|
||||
s[13] ^= l;
|
||||
s[22] ^= h;
|
||||
s[23] ^= l;
|
||||
s[32] ^= h;
|
||||
s[33] ^= l;
|
||||
s[42] ^= h;
|
||||
s[43] ^= l;
|
||||
h = c2 ^ (c6 << 1 | c7 >>> 31);
|
||||
l = c3 ^ (c7 << 1 | c6 >>> 31);
|
||||
s[4] ^= h;
|
||||
s[5] ^= l;
|
||||
s[14] ^= h;
|
||||
s[15] ^= l;
|
||||
s[24] ^= h;
|
||||
s[25] ^= l;
|
||||
s[34] ^= h;
|
||||
s[35] ^= l;
|
||||
s[44] ^= h;
|
||||
s[45] ^= l;
|
||||
h = c4 ^ (c8 << 1 | c9 >>> 31);
|
||||
l = c5 ^ (c9 << 1 | c8 >>> 31);
|
||||
s[6] ^= h;
|
||||
s[7] ^= l;
|
||||
s[16] ^= h;
|
||||
s[17] ^= l;
|
||||
s[26] ^= h;
|
||||
s[27] ^= l;
|
||||
s[36] ^= h;
|
||||
s[37] ^= l;
|
||||
s[46] ^= h;
|
||||
s[47] ^= l;
|
||||
h = c6 ^ (c0 << 1 | c1 >>> 31);
|
||||
l = c7 ^ (c1 << 1 | c0 >>> 31);
|
||||
s[8] ^= h;
|
||||
s[9] ^= l;
|
||||
s[18] ^= h;
|
||||
s[19] ^= l;
|
||||
s[28] ^= h;
|
||||
s[29] ^= l;
|
||||
s[38] ^= h;
|
||||
s[39] ^= l;
|
||||
s[48] ^= h;
|
||||
s[49] ^= l;
|
||||
|
||||
b0 = s[0];
|
||||
b1 = s[1];
|
||||
b32 = s[11] << 4 | s[10] >>> 28;
|
||||
b33 = s[10] << 4 | s[11] >>> 28;
|
||||
b14 = s[20] << 3 | s[21] >>> 29;
|
||||
b15 = s[21] << 3 | s[20] >>> 29;
|
||||
b46 = s[31] << 9 | s[30] >>> 23;
|
||||
b47 = s[30] << 9 | s[31] >>> 23;
|
||||
b28 = s[40] << 18 | s[41] >>> 14;
|
||||
b29 = s[41] << 18 | s[40] >>> 14;
|
||||
b20 = s[2] << 1 | s[3] >>> 31;
|
||||
b21 = s[3] << 1 | s[2] >>> 31;
|
||||
b2 = s[13] << 12 | s[12] >>> 20;
|
||||
b3 = s[12] << 12 | s[13] >>> 20;
|
||||
b34 = s[22] << 10 | s[23] >>> 22;
|
||||
b35 = s[23] << 10 | s[22] >>> 22;
|
||||
b16 = s[33] << 13 | s[32] >>> 19;
|
||||
b17 = s[32] << 13 | s[33] >>> 19;
|
||||
b48 = s[42] << 2 | s[43] >>> 30;
|
||||
b49 = s[43] << 2 | s[42] >>> 30;
|
||||
b40 = s[5] << 30 | s[4] >>> 2;
|
||||
b41 = s[4] << 30 | s[5] >>> 2;
|
||||
b22 = s[14] << 6 | s[15] >>> 26;
|
||||
b23 = s[15] << 6 | s[14] >>> 26;
|
||||
b4 = s[25] << 11 | s[24] >>> 21;
|
||||
b5 = s[24] << 11 | s[25] >>> 21;
|
||||
b36 = s[34] << 15 | s[35] >>> 17;
|
||||
b37 = s[35] << 15 | s[34] >>> 17;
|
||||
b18 = s[45] << 29 | s[44] >>> 3;
|
||||
b19 = s[44] << 29 | s[45] >>> 3;
|
||||
b10 = s[6] << 28 | s[7] >>> 4;
|
||||
b11 = s[7] << 28 | s[6] >>> 4;
|
||||
b42 = s[17] << 23 | s[16] >>> 9;
|
||||
b43 = s[16] << 23 | s[17] >>> 9;
|
||||
b24 = s[26] << 25 | s[27] >>> 7;
|
||||
b25 = s[27] << 25 | s[26] >>> 7;
|
||||
b6 = s[36] << 21 | s[37] >>> 11;
|
||||
b7 = s[37] << 21 | s[36] >>> 11;
|
||||
b38 = s[47] << 24 | s[46] >>> 8;
|
||||
b39 = s[46] << 24 | s[47] >>> 8;
|
||||
b30 = s[8] << 27 | s[9] >>> 5;
|
||||
b31 = s[9] << 27 | s[8] >>> 5;
|
||||
b12 = s[18] << 20 | s[19] >>> 12;
|
||||
b13 = s[19] << 20 | s[18] >>> 12;
|
||||
b44 = s[29] << 7 | s[28] >>> 25;
|
||||
b45 = s[28] << 7 | s[29] >>> 25;
|
||||
b26 = s[38] << 8 | s[39] >>> 24;
|
||||
b27 = s[39] << 8 | s[38] >>> 24;
|
||||
b8 = s[48] << 14 | s[49] >>> 18;
|
||||
b9 = s[49] << 14 | s[48] >>> 18;
|
||||
|
||||
s[0] = b0 ^ ~b2 & b4;
|
||||
s[1] = b1 ^ ~b3 & b5;
|
||||
s[10] = b10 ^ ~b12 & b14;
|
||||
s[11] = b11 ^ ~b13 & b15;
|
||||
s[20] = b20 ^ ~b22 & b24;
|
||||
s[21] = b21 ^ ~b23 & b25;
|
||||
s[30] = b30 ^ ~b32 & b34;
|
||||
s[31] = b31 ^ ~b33 & b35;
|
||||
s[40] = b40 ^ ~b42 & b44;
|
||||
s[41] = b41 ^ ~b43 & b45;
|
||||
s[2] = b2 ^ ~b4 & b6;
|
||||
s[3] = b3 ^ ~b5 & b7;
|
||||
s[12] = b12 ^ ~b14 & b16;
|
||||
s[13] = b13 ^ ~b15 & b17;
|
||||
s[22] = b22 ^ ~b24 & b26;
|
||||
s[23] = b23 ^ ~b25 & b27;
|
||||
s[32] = b32 ^ ~b34 & b36;
|
||||
s[33] = b33 ^ ~b35 & b37;
|
||||
s[42] = b42 ^ ~b44 & b46;
|
||||
s[43] = b43 ^ ~b45 & b47;
|
||||
s[4] = b4 ^ ~b6 & b8;
|
||||
s[5] = b5 ^ ~b7 & b9;
|
||||
s[14] = b14 ^ ~b16 & b18;
|
||||
s[15] = b15 ^ ~b17 & b19;
|
||||
s[24] = b24 ^ ~b26 & b28;
|
||||
s[25] = b25 ^ ~b27 & b29;
|
||||
s[34] = b34 ^ ~b36 & b38;
|
||||
s[35] = b35 ^ ~b37 & b39;
|
||||
s[44] = b44 ^ ~b46 & b48;
|
||||
s[45] = b45 ^ ~b47 & b49;
|
||||
s[6] = b6 ^ ~b8 & b0;
|
||||
s[7] = b7 ^ ~b9 & b1;
|
||||
s[16] = b16 ^ ~b18 & b10;
|
||||
s[17] = b17 ^ ~b19 & b11;
|
||||
s[26] = b26 ^ ~b28 & b20;
|
||||
s[27] = b27 ^ ~b29 & b21;
|
||||
s[36] = b36 ^ ~b38 & b30;
|
||||
s[37] = b37 ^ ~b39 & b31;
|
||||
s[46] = b46 ^ ~b48 & b40;
|
||||
s[47] = b47 ^ ~b49 & b41;
|
||||
s[8] = b8 ^ ~b0 & b2;
|
||||
s[9] = b9 ^ ~b1 & b3;
|
||||
s[18] = b18 ^ ~b10 & b12;
|
||||
s[19] = b19 ^ ~b11 & b13;
|
||||
s[28] = b28 ^ ~b20 & b22;
|
||||
s[29] = b29 ^ ~b21 & b23;
|
||||
s[38] = b38 ^ ~b30 & b32;
|
||||
s[39] = b39 ^ ~b31 & b33;
|
||||
s[48] = b48 ^ ~b40 & b42;
|
||||
s[49] = b49 ^ ~b41 & b43;
|
||||
|
||||
s[0] ^= RC[n];
|
||||
s[1] ^= RC[n + 1];
|
||||
}
|
||||
};
|
||||
|
||||
var keccak = function keccak(bits) {
|
||||
return function (str) {
|
||||
var msg;
|
||||
if (str.slice(0, 2) === "0x") {
|
||||
msg = [];
|
||||
for (var i = 2, l = str.length; i < l; i += 2) {
|
||||
msg.push(parseInt(str.slice(i, i + 2), 16));
|
||||
}
|
||||
} else {
|
||||
msg = str;
|
||||
}
|
||||
return update(Keccak(bits, bits), msg);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
keccak256: keccak(256),
|
||||
keccak512: keccak(512),
|
||||
keccak256s: keccak(256),
|
||||
keccak512s: keccak(512)
|
||||
};
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
Account: require("./account.js"),
|
||||
Nat: require("./nat.js"),
|
||||
Bytes: require("./bytes.js"),
|
||||
Hash: require("./hash.js"),
|
||||
RLP: require("./rlp.js"),
|
||||
Api: require("./api.js"),
|
||||
Provider: require("./provider.js"),
|
||||
Desubits: require("./desubits.js"),
|
||||
Passphrase: require("./passphrase.js")
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
var merge = function merge(a) {
|
||||
return function (b) {
|
||||
var c = {};
|
||||
for (var key in a) {
|
||||
c[key] = a[key];
|
||||
}for (var _key in b) {
|
||||
c[_key] = b[_key];
|
||||
}return c;
|
||||
};
|
||||
};
|
||||
|
||||
var remove = function remove(removeKey) {
|
||||
return function (a) {
|
||||
var b = {};
|
||||
for (var key in a) {
|
||||
if (key !== removeKey) b[key] = a[key];
|
||||
}return b;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
merge: merge,
|
||||
remove: remove
|
||||
};
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
var BN = require("bn.js");
|
||||
var Bytes = require("./bytes");
|
||||
|
||||
var fromBN = function fromBN(bn) {
|
||||
return "0x" + bn.toString("hex");
|
||||
};
|
||||
|
||||
var toBN = function toBN(str) {
|
||||
return new BN(str.slice(2), 16);
|
||||
};
|
||||
|
||||
var fromString = function fromString(str) {
|
||||
var bn = "0x" + (str.slice(0, 2) === "0x" ? new BN(str.slice(2), 16) : new BN(str, 10)).toString("hex");
|
||||
return bn === "0x0" ? "0x" : bn;
|
||||
};
|
||||
|
||||
var toEther = function toEther(wei) {
|
||||
return toNumber(div(wei, fromString("10000000000"))) / 100000000;
|
||||
};
|
||||
|
||||
var fromEther = function fromEther(eth) {
|
||||
return mul(fromNumber(Math.floor(eth * 100000000)), fromString("10000000000"));
|
||||
};
|
||||
|
||||
var toString = function toString(a) {
|
||||
return toBN(a).toString(10);
|
||||
};
|
||||
|
||||
var fromNumber = function fromNumber(a) {
|
||||
return typeof a === "string" ? /^0x/.test(a) ? a : "0x" + a : "0x" + new BN(a).toString("hex");
|
||||
};
|
||||
|
||||
var toNumber = function toNumber(a) {
|
||||
return toBN(a).toNumber();
|
||||
};
|
||||
|
||||
var toUint256 = function toUint256(a) {
|
||||
return Bytes.pad(32, a);
|
||||
};
|
||||
|
||||
var bin = function bin(method) {
|
||||
return function (a, b) {
|
||||
return fromBN(toBN(a)[method](toBN(b)));
|
||||
};
|
||||
};
|
||||
|
||||
var add = bin("add");
|
||||
var mul = bin("mul");
|
||||
var div = bin("div");
|
||||
var sub = bin("sub");
|
||||
|
||||
module.exports = {
|
||||
toString: toString,
|
||||
fromString: fromString,
|
||||
toNumber: toNumber,
|
||||
fromNumber: fromNumber,
|
||||
toEther: toEther,
|
||||
fromEther: fromEther,
|
||||
toUint256: toUint256,
|
||||
add: add,
|
||||
mul: mul,
|
||||
div: div,
|
||||
sub: sub
|
||||
};
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
var Hash = require("./hash");
|
||||
var Bytes = require("./bytes");
|
||||
var Desubits = require("./desubits");
|
||||
|
||||
// Bytes -> Bytes
|
||||
var bytesAddChecksum = function bytesAddChecksum(bytes) {
|
||||
var hash = Hash.keccak256(bytes);
|
||||
var sum = Bytes.slice(0, 1, hash);
|
||||
return Bytes.concat(bytes, sum);
|
||||
};
|
||||
|
||||
// Bytes -> Bool
|
||||
var bytesChecksum = function bytesChecksum(bytes) {
|
||||
var length = Bytes.length(bytes);
|
||||
var prefix = Bytes.slice(0, length - 1, bytes);
|
||||
return bytesAddChecksum(prefix) === bytes;
|
||||
};
|
||||
|
||||
// () ~> Passphrase
|
||||
var create = function create() {
|
||||
var bytes = bytesAddChecksum(Bytes.random(11));
|
||||
var seed = Desubits.fromBytes(bytes);
|
||||
var passphrase = seed.replace(/([a-z]{8})/g, "$1 ");
|
||||
return passphrase;
|
||||
};
|
||||
|
||||
// Passphrase -> Bytes
|
||||
var toBytes = function toBytes(passphrase) {
|
||||
var seed = passphrase.replace(/ /g, "");
|
||||
var bytes = Desubits.toBytes(passphrase);
|
||||
return bytes;
|
||||
};
|
||||
|
||||
// Passphrase -> Bool
|
||||
var checksum = function checksum(passphrase) {
|
||||
return bytesChecksum(toBytes(passphrase));
|
||||
};
|
||||
|
||||
// Passphrase -> Bytes
|
||||
var toMasterKey = function toMasterKey(passphrase) {
|
||||
var hash = Hash.keccak256;
|
||||
var bytes = toBytes(passphrase);
|
||||
for (var i = 0, l = Math.pow(2, 12); i < l; ++i) {
|
||||
bytes = hash(bytes);
|
||||
}return bytes;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
create: create,
|
||||
checksum: checksum,
|
||||
toMasterKey: toMasterKey
|
||||
};
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
var njsp = require("nano-json-stream-parser");
|
||||
var request = require("xhr-request-promise");
|
||||
|
||||
var EthereumProvider = function EthereumProvider(url, intercept) {
|
||||
intercept = intercept || function () {};
|
||||
|
||||
var api = {};
|
||||
var onResponse = {};
|
||||
var callbacks = {};
|
||||
var nextId = 0;
|
||||
var send = void 0;
|
||||
|
||||
var makeSender = function makeSender(send) {
|
||||
var P = function P(fn) {
|
||||
return function () {
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
return fn.apply(undefined, _toConsumableArray(args.concat(function (err, res) {
|
||||
return err ? reject(err) : resolve(res);
|
||||
})));
|
||||
});
|
||||
};
|
||||
};
|
||||
var sender = function sender(intercept) {
|
||||
return function (method, params, callback) {
|
||||
var intercepted = intercept(method, params, P(sender(function () {})));
|
||||
if (intercepted) {
|
||||
intercepted.then(function (response) {
|
||||
return callback(null, response);
|
||||
});
|
||||
} else {
|
||||
send(method, params, callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
return sender(intercept);
|
||||
};
|
||||
|
||||
var parseResponse = njsp(function (json) {
|
||||
onResponse[json.id] && onResponse[json.id](null, json.result);
|
||||
});
|
||||
|
||||
var genPayload = function genPayload(method, params) {
|
||||
return {
|
||||
jsonrpc: "2.0",
|
||||
id: ++nextId,
|
||||
method: method,
|
||||
params: params
|
||||
};
|
||||
};
|
||||
|
||||
api.on = function (name, callback) {
|
||||
callbacks[name] = callback;
|
||||
};
|
||||
|
||||
if (/^ws/.test(url)) {
|
||||
var WebSocket = require("w" + "s");
|
||||
var ws = new WebSocket(url);
|
||||
api.send = makeSender(function (method, params, callback) {
|
||||
var intercepted = intercept(method, params, P(send(function () {})));
|
||||
if (intercepted) {
|
||||
intercepted.then(function (response) {
|
||||
return callback(null, response);
|
||||
});
|
||||
} else {
|
||||
var payload = genPayload(method, params);
|
||||
onResponse[payload.id] = callback;
|
||||
ws.send(JSON.stringify(payload));
|
||||
}
|
||||
});
|
||||
ws.on("message", parseResponse);
|
||||
ws.on("open", function () {
|
||||
return callbacks.connect && callbacks.connect(eth);
|
||||
});
|
||||
ws.on("close", function () {
|
||||
return callbacks.disconnect && callbacks.disconnect();
|
||||
});
|
||||
} else if (/^http/.test(url)) {
|
||||
api.send = makeSender(function (method, params, callback) {
|
||||
request(url, {
|
||||
method: "POST",
|
||||
contentType: "application/json-rpc",
|
||||
body: JSON.stringify(genPayload(method, params)) }).then(function (answer) {
|
||||
var resp = JSON.parse(answer);
|
||||
if (resp.error) {
|
||||
callback(resp.error.message);
|
||||
} else {
|
||||
callback(null, resp.result);
|
||||
}
|
||||
}).catch(function (err) {
|
||||
return callback("Couldn't connect to Ethereum node.");
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
callbacks.connect && callbacks.connect();
|
||||
}, 1);
|
||||
} else {
|
||||
throw "IPC not supported yet.";
|
||||
}
|
||||
|
||||
return api;
|
||||
};
|
||||
|
||||
module.exports = EthereumProvider;
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// The RLP format
|
||||
// Serialization and deserialization for the BytesTree type, under the following grammar:
|
||||
// | First byte | Meaning |
|
||||
// | ---------- | -------------------------------------------------------------------------- |
|
||||
// | 0 to 127 | HEX(leaf) |
|
||||
// | 128 to 183 | HEX(length_of_leaf + 128) + HEX(leaf) |
|
||||
// | 184 to 191 | HEX(length_of_length_of_leaf + 128 + 55) + HEX(length_of_leaf) + HEX(leaf) |
|
||||
// | 192 to 247 | HEX(length_of_node + 192) + HEX(node) |
|
||||
// | 248 to 255 | HEX(length_of_length_of_node + 128 + 55) + HEX(length_of_node) + HEX(node) |
|
||||
|
||||
var encode = function encode(tree) {
|
||||
var padEven = function padEven(str) {
|
||||
return str.length % 2 === 0 ? str : "0" + str;
|
||||
};
|
||||
|
||||
var uint = function uint(num) {
|
||||
return padEven(num.toString(16));
|
||||
};
|
||||
|
||||
var length = function length(len, add) {
|
||||
return len < 56 ? uint(add + len) : uint(add + uint(len).length / 2 + 55) + uint(len);
|
||||
};
|
||||
|
||||
var dataTree = function dataTree(tree) {
|
||||
if (typeof tree === "string") {
|
||||
var hex = tree.slice(2);
|
||||
var pre = hex.length != 2 || hex >= "80" ? length(hex.length / 2, 128) : "";
|
||||
return pre + hex;
|
||||
} else {
|
||||
var _hex = tree.map(dataTree).join("");
|
||||
var _pre = length(_hex.length / 2, 192);
|
||||
return _pre + _hex;
|
||||
}
|
||||
};
|
||||
|
||||
return "0x" + dataTree(tree);
|
||||
};
|
||||
|
||||
var decode = function decode(hex) {
|
||||
var i = 2;
|
||||
|
||||
var parseTree = function parseTree() {
|
||||
if (i >= hex.length) throw "";
|
||||
var head = hex.slice(i, i + 2);
|
||||
return head < "80" ? (i += 2, "0x" + head) : head < "c0" ? parseHex() : parseList();
|
||||
};
|
||||
|
||||
var parseLength = function parseLength() {
|
||||
var len = parseInt(hex.slice(i, i += 2), 16) % 64;
|
||||
return len < 56 ? len : parseInt(hex.slice(i, i += (len - 55) * 2), 16);
|
||||
};
|
||||
|
||||
var parseHex = function parseHex() {
|
||||
var len = parseLength();
|
||||
return "0x" + hex.slice(i, i += len * 2);
|
||||
};
|
||||
|
||||
var parseList = function parseList() {
|
||||
var lim = parseLength() * 2 + i;
|
||||
var list = [];
|
||||
while (i < lim) {
|
||||
list.push(parseTree());
|
||||
}return list;
|
||||
};
|
||||
|
||||
try {
|
||||
return parseTree();
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { encode: encode, decode: decode };
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
var F = require("forall");
|
||||
var A = require("./array");
|
||||
var B = require("./bytes");
|
||||
var Account = require("./account");
|
||||
|
||||
F.Bytes = F(F.Type, {
|
||||
form: "a JavaScript String starting with a `0x`, followed by an even number of low-case hex chars (i.e., `0123456789abcdef`)",
|
||||
rand: function rand() {
|
||||
return "0x" + A.generate((Math.random() * 16 | 0) * 2, function () {
|
||||
return (Math.random() * 16 | 0).toString(16);
|
||||
}).join("");
|
||||
},
|
||||
test: function test(value) {
|
||||
return typeof value === "string" && /^0x([0-9a-f][0-9a-f])*$/.test(value);
|
||||
}
|
||||
}).__name("Bytes").__desc("any arbitrary data");
|
||||
|
||||
F.NBytes = function (bytes) {
|
||||
return F(F.Type, {
|
||||
form: "a JavaScript String starting with a `0x`, followed by " + bytes * 2 + " low-case hex chars (i.e., `0123456789abcdef`)",
|
||||
test: function test(value) {
|
||||
return F.Bytes.test(value) && value.length === bytes * 2 + 2;
|
||||
},
|
||||
rand: function rand() {
|
||||
return "0x" + A.generate(bytes * 2, function () {
|
||||
return (Math.random() * 16 | 0).toString(16);
|
||||
}).join("");
|
||||
}
|
||||
}).__name("NBytes(" + bytes + ")").__desc("any arbitrary data of exactly " + bytes + "-byte" + (bytes > 1 ? "s" : ""));
|
||||
};
|
||||
|
||||
F.Nat = F(F.Type, {
|
||||
form: "a JavaScript String starting with a `0x`, followed by at least one low-case hex char different from 0, followed by any number of low-case hex chars (i.e., `0123456789abcdef`)",
|
||||
test: function test(value) {
|
||||
return typeof value === "string" && /^0x[1-9a-f]([0-9a-f])*$/.test(value);
|
||||
},
|
||||
rand: function rand() {
|
||||
return "0x" + (Math.random() * Math.pow(2, 50) | 0).toString(16);
|
||||
}
|
||||
}).__name("Nat").__desc("an arbitrarily long non-negative integer number");
|
||||
|
||||
F.Address = F(F.Type, {
|
||||
form: "a JavaScript String starting with a `0x`, followed by 40 hex chars (i.e., `0123456789abcdefABCDEF`), with the nth hex being uppercase iff the nth hex of the keccak256 of the lowercase address in ASCII is > 7",
|
||||
test: function test(address) {
|
||||
return (/^(0x)?[0-9a-f]{40}$/i.test(address) && Account.toChecksum(address.toLowerCase()) === address
|
||||
);
|
||||
},
|
||||
rand: function rand() {
|
||||
return F.Account.rand().address;
|
||||
}
|
||||
}).__name("Address").__desc("an Ethereum public address");
|
||||
|
||||
F.Hash = F(F.Type, {
|
||||
form: F.NBytes(32).form,
|
||||
test: F.NBytes(32).test,
|
||||
rand: F.NBytes(32).rand
|
||||
}).__name("Hash").__desc("a Keccak-256 hash");
|
||||
|
||||
F.PrivateKey = F(F.Type, {
|
||||
form: F.NBytes(32).form,
|
||||
test: F.NBytes(32).test,
|
||||
rand: F.NBytes(32).rand
|
||||
}).__name("PrivateKey").__desc("an Ethereum private key");
|
||||
|
||||
F.Account = function () {
|
||||
var base = F.Struct({
|
||||
address: F.Address,
|
||||
privateKey: F.PrivateKey
|
||||
});
|
||||
return F(F.Type, {
|
||||
form: base.form,
|
||||
test: base.test,
|
||||
rand: function rand() {
|
||||
return Account.create("");
|
||||
}
|
||||
});
|
||||
}().__name("Account").__desc("an Ethereum account");
|
||||
|
||||
F.BytesTree = F(F.Type, {
|
||||
form: "either " + F.Bytes.form + ", or a tree of nested JavaScript Arrays of BytesTrees",
|
||||
test: function test(value) {
|
||||
return F.Bytes.test(value) || value instanceof Array && value.reduce(function (r, v) {
|
||||
return F.BytesTree.test(v) && r;
|
||||
}, true);
|
||||
},
|
||||
rand: function rand() {
|
||||
var list = [];
|
||||
while (Math.random() < 0.8) {
|
||||
if (Math.random() < 0.8) list.push(F.Bytes.rand());else list.push(F.BytesTree.rand());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}).__name("BytesTree").__desc("a tree of arbitrary binary data");
|
||||
|
||||
module.exports = F;
|
||||
Reference in new issue
Block a user