UNPKG

check-ethereum-scanner

Version:

Safety checks for new Ethereum tokens

180 lines (157 loc) 4.24 kB
const A = require("./array.js"); const at = (bytes, index) => parseInt(bytes.slice(index * 2 + 2, index * 2 + 4), 16); const random = bytes => { let rnd; 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."; let hex = "0x"; for (let i = 0; i < bytes; ++i) hex += ("00" + rnd[i].toString(16)).slice(-2); return hex; }; const length = a => (a.length - 2) / 2; const flatten = (a) => "0x" + a.reduce((r,s) => r + s.slice(2), ""); const slice = (i,j,bs) => "0x" + bs.slice(i*2+2,j*2+2); const reverse = hex => { let rev = "0x"; for (let i = 0, l = length(hex); i < l; ++i) { rev += hex.slice((l-i)*2, (l-i+1)*2); } return rev; } const pad = (l,hex) => hex.length === l*2+2 ? hex : pad(l,"0x"+"0"+hex.slice(2)); const padRight = (l,hex) => hex.length === l*2+2 ? hex : padRight(l,hex+"0"); const toArray = hex => { let arr = []; for (let i = 2, l = hex.length; i < l; i += 2) arr.push(parseInt(hex.slice(i, i + 2), 16)); return arr; } const fromArray = arr => { let hex = "0x"; for (let i = 0, l = arr.length; i < l; ++i) { let b = arr[i]; hex += (b < 16 ? "0" : "") + b.toString(16); } return hex; } const toUint8Array = hex => new Uint8Array(toArray(hex)); const fromUint8Array = arr => fromArray([].slice.call(arr, 0)); const fromNumber = num => { let hex = num.toString(16); return hex.length % 2 === 0 ? "0x" + hex : "0x0" + hex ; }; const toNumber = hex => parseInt(hex.slice(2), 16); const concat = (a, b) => a.concat(b.slice(2)); const fromNat = bn => bn === "0x0" ? "0x" : bn.length % 2 === 0 ? bn : "0x0" + bn.slice(2); const toNat = bn => bn[2] === "0" ? "0x" + bn.slice(3) : bn; const fromAscii = ascii => { let hex = "0x"; for (let i = 0; i < ascii.length; ++i) hex += ("00" + ascii.charCodeAt(i).toString(16)).slice(-2); return hex; }; const toAscii = hex => { let ascii = ""; for (let 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 const fromString = s => { const makeByte = uint8 => { const b = uint8.toString(16); return b.length < 2 ? "0" + b : b; }; let bytes = "0x"; for (let ci = 0; ci != s.length; ci++) { let 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; let 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; }; const toString = (bytes) => { let s = ''; let i = 0; let l = length(bytes); while (i < l) { let 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, length, concat, flatten, slice, reverse, pad, padRight, fromAscii, toAscii, fromString, toString, fromNumber, toNumber, fromNat, toNat, fromArray, toArray, fromUint8Array, toUint8Array }