UNPKG

check-ethereum-scanner

Version:

Safety checks for new Ethereum tokens

95 lines (86 loc) 3.4 kB
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;