PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/@metamask/eth-sig-util/dist
Просмотр файла: ethereumjs-abi-utils.js
"use strict";
/* eslint jsdoc/require-description: 0 */
/* eslint jsdoc/require-returns: 0 */
/* eslint jsdoc/match-description: 0 */
/* eslint jsdoc/require-param-description: 0 */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.rawEncode = exports.parseNumber = exports.solidityPack = void 0;
const util_1 = require("@ethereumjs/util");
const bn_js_1 = __importDefault(require("bn.js"));
const ethjs_util_1 = require("ethjs-util");
const utils_1 = require("./utils");
//
// Methods borrowed and somewhat adapted from ethereumjs-abi@0.6.8:
// https://npmfs.com/package/ethereumjs-abi/0.6.8/lib/index.js
//
/**
* Packs non-standard encoded values packed according to their respective type in types in a buffer.
*
* @param types - Array of types of each value to encode.
* @param values - Array of values to encode.
* @returns A buffer containing the packed values.
*/
function solidityPack(types, values) {
if (types.length !== values.length) {
throw new Error('Number of types are not matching the values');
}
const ret = [];
for (let i = 0; i < types.length; i++) {
const type = elementaryName(types[i]);
const value = values[i];
ret.push(solidityHexValue(type, value, null));
}
return Buffer.concat(ret);
}
exports.solidityPack = solidityPack;
/**
* Checks if a value is an array (represented as a string).
*
* @param type - The value to check whether it is an array.
* @returns A boolean indicating whether the passed value is an array.
*/
function isArray(type) {
return type.endsWith(']');
}
/**
* Parse array type for packing solidity values.
*
* @param type - A string that may be an array to parse.
* @returns A parsed value from the array.
*/
function parseTypeArray(type) {
const tmp = type.match(/(.*)\[(.*?)\]$/u);
if (tmp) {
return tmp[2] === '' ? 'dynamic' : parseInt(tmp[2], 10);
}
return null;
}
/**
* Parse N from type<N>.
*
* @param type - Value to parse.
* @returns Parsed value.
*/
function parseTypeN(type) {
const match = /^\D+(\d+)$/u.exec(type);
if (match === null) {
throw new Error(`Invalid parseTypeN input "${type}".`);
}
return parseInt(match[1], 10);
}
/**
* Parse a number for determining a solidity hexvalue.
*
* @param arg - Number to parse.
* @returns Parsed value.
*/
function parseNumber(arg) {
const type = typeof arg;
if (type === 'string') {
if ((0, util_1.isHexPrefixed)(arg)) {
return new bn_js_1.default((0, ethjs_util_1.stripHexPrefix)(arg), 16);
}
return new bn_js_1.default(arg, 10);
}
else if (type === 'number') {
return new bn_js_1.default(arg);
}
else if ((arg && Object.prototype.hasOwnProperty.call(arg, 'toArray')) ||
bn_js_1.default.isBN(arg)) {
return arg;
}
throw new Error('Argument is not a number');
}
exports.parseNumber = parseNumber;
/**
* Get solidity hex value from type, value and bitsize inputs for packing these values in a buffer.
*
* @param type - The type of the value to encode.
* @param value - The value to encode.
* @param bitsize - The bitsize of the value to encode.
* @returns The encoded soldity hex value.
*/
function solidityHexValue(type, value, bitsize) {
// pass in bitsize = null if use default bitsize
if (isArray(type)) {
const subType = type.replace(/\[.*?\]/u, '');
if (!isArray(subType)) {
const arraySize = parseTypeArray(type);
if (arraySize !== 'dynamic' &&
arraySize !== 0 &&
arraySize !== null &&
value.length > arraySize) {
throw new Error(`Elements exceed array size: ${arraySize}`);
}
}
const arrayValues = value.map((v) => solidityHexValue(subType, v, 256));
return Buffer.concat(arrayValues);
}
else if (type === 'bytes') {
return value;
}
else if (type === 'string') {
return Buffer.from(value, 'utf8');
}
else if (type === 'bool') {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
bitsize = bitsize || 8;
const padding = Array(bitsize / 4).join('0');
return Buffer.from(value ? `${padding}1` : `${padding}0`, 'hex');
}
else if (type === 'address') {
let bytesize = 20;
if (bitsize) {
bytesize = bitsize / 8;
}
return (0, util_1.setLengthLeft)((0, util_1.toBuffer)(value), bytesize);
}
else if (type.startsWith('bytes')) {
const size = parseTypeN(type);
if (size < 1 || size > 32) {
throw new Error(`Invalid bytes<N> width: ${size}`);
}
if (typeof value === 'number') {
value = (0, utils_1.normalize)(value);
}
return (0, util_1.setLengthRight)((0, util_1.toBuffer)(value), size);
}
else if (type.startsWith('uint')) {
const size = parseTypeN(type);
if (size % 8 || size < 8 || size > 256) {
throw new Error(`Invalid uint<N> width: ${size}`);
}
const num = parseNumber(value);
if (num.bitLength() > size) {
throw new Error(`Supplied uint exceeds width: ${size} vs ${num.bitLength()}`);
}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
bitsize = bitsize || size;
return num.toArrayLike(Buffer, 'be', bitsize / 8);
}
else if (type.startsWith('int')) {
const size = parseTypeN(type);
if (size % 8 || size < 8 || size > 256) {
throw new Error(`Invalid int<N> width: ${size}`);
}
const num = parseNumber(value);
if (num.bitLength() > size) {
throw new Error(`Supplied int exceeds width: ${size} vs ${num.bitLength()}`);
}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
bitsize = bitsize || size;
return num.toTwos(size).toArrayLike(Buffer, 'be', bitsize / 8);
}
// FIXME: support all other types
throw new Error(`Unsupported or invalid type: ${JSON.stringify(type)}`);
}
/**
* Gets the correct solidity type name.
*
* @param name - The type name for which we want the corresponding solidity type name.
* @returns The solidity type name for the input value.
*/
function elementaryName(name) {
if (name.startsWith('int[')) {
return `int256${name.slice(3)}`;
}
else if (name === 'int') {
return 'int256';
}
else if (name.startsWith('uint[')) {
return `uint256${name.slice(4)}`;
}
else if (name === 'uint') {
return 'uint256';
}
else if (name.startsWith('fixed[')) {
return `fixed128x128${name.slice(5)}`;
}
else if (name === 'fixed') {
return 'fixed128x128';
}
else if (name.startsWith('ufixed[')) {
return `ufixed128x128${name.slice(6)}`;
}
else if (name === 'ufixed') {
return 'ufixed128x128';
}
return name;
}
/**
* @param types
* @param values
*/
function rawEncode(types, values) {
const output = [];
const data = [];
let headLength = 0;
types.forEach((type) => {
if (isArray(type)) {
const size = parseTypeArray(type);
// eslint-disable-next-line no-negated-condition
if (size !== 'dynamic' && size !== null) {
headLength += 32 * size;
}
else {
headLength += 32;
}
}
else {
headLength += 32;
}
});
for (let i = 0; i < types.length; i++) {
const type = elementaryName(types[i]);
const value = values[i];
const cur = encodeSingle(type, value);
// Use the head/tail method for storing dynamic data
if (isDynamic(type)) {
output.push(encodeSingle('uint256', headLength));
data.push(cur);
headLength += cur.length;
}
else {
output.push(cur);
}
}
return Buffer.concat(output.concat(data));
}
exports.rawEncode = rawEncode;
// Encodes a single item (can be dynamic array)
// @returns: Buffer
/**
* @param type
* @param arg
*/
function encodeSingle(type, arg) {
if (type === 'address') {
return encodeSingle('uint160', parseNumber(arg));
}
else if (type === 'bool') {
return encodeSingle('uint8', arg ? 1 : 0);
}
else if (type === 'string') {
return encodeSingle('bytes', Buffer.from(arg, 'utf8'));
}
else if (isArray(type)) {
// this part handles fixed-length ([2]) and variable length ([]) arrays
// NOTE: we catch here all calls to arrays, that simplifies the rest
if (typeof arg.length === 'undefined') {
throw new Error('Not an array?');
}
const size = parseTypeArray(type);
if (size !== 'dynamic' &&
size !== 0 &&
size !== null &&
arg.length > size) {
throw new Error(`Elements exceed array size: ${size}`);
}
const ret = [];
type = type.slice(0, type.lastIndexOf('['));
if (typeof arg === 'string') {
arg = JSON.parse(arg);
}
// TODO: if this is array, should do for-of
for (const i in arg) {
if (Object.prototype.hasOwnProperty.call(arg, i)) {
ret.push(encodeSingle(type, arg[i]));
}
}
if (size === 'dynamic') {
const length = encodeSingle('uint256', arg.length);
ret.unshift(length);
}
return Buffer.concat(ret);
}
else if (type === 'bytes') {
arg = Buffer.from(arg);
let ret = Buffer.concat([encodeSingle('uint256', arg.length), arg]);
if (arg.length % 32 !== 0) {
ret = Buffer.concat([ret, (0, util_1.zeros)(32 - (arg.length % 32))]);
}
return ret;
}
else if (type.startsWith('bytes')) {
const size = parseTypeN(type);
if (size < 1 || size > 32) {
throw new Error(`Invalid bytes<N> width: ${size}`);
}
// TODO: fix types here
const nArg = typeof arg === 'number' ? (0, utils_1.normalize)(arg) : arg;
return (0, util_1.setLengthRight)((0, util_1.toBuffer)(nArg), 32);
}
else if (type.startsWith('uint')) {
const size = parseTypeN(type);
if (size % 8 || size < 8 || size > 256) {
throw new Error(`Invalid uint<N> width: ${size}`);
}
const num = parseNumber(arg);
if (num.bitLength() > size) {
throw new Error(`Supplied uint exceeds width: ${size} vs ${num.bitLength()}`);
}
if (num.isNeg()) {
throw new Error('Supplied uint is negative');
}
return num.toArrayLike(Buffer, 'be', 32);
}
else if (type.startsWith('int')) {
const size = parseTypeN(type);
if (size % 8 || size < 8 || size > 256) {
throw new Error(`Invalid int<N> width: ${size}`);
}
const num = parseNumber(arg);
if (num.bitLength() > size) {
throw new Error(`Supplied int exceeds width: ${size} vs ${num.bitLength()}`);
}
return num.toTwos(256).toArrayLike(Buffer, 'be', 32);
}
else if (type.startsWith('ufixed')) {
const size = parseTypeNxM(type);
const num = parseNumber(arg);
if (num.isNeg()) {
throw new Error('Supplied ufixed is negative');
}
return encodeSingle('uint256', num.mul(new bn_js_1.default(2).pow(new bn_js_1.default(size[1]))));
}
else if (type.startsWith('fixed')) {
const size = parseTypeNxM(type);
return encodeSingle('int256', parseNumber(arg).mul(new bn_js_1.default(2).pow(new bn_js_1.default(size[1]))));
}
throw new Error(`Unsupported or invalid type: ${JSON.stringify(type)}`);
}
// Is a type dynamic?
/**
* @param type
*/
function isDynamic(type) {
// FIXME: handle all types? I don't think anything is missing now
return (type === 'string' || type === 'bytes' || parseTypeArray(type) === 'dynamic');
}
// Parse N,M from type<N>x<M>
/**
* @param type
*/
function parseTypeNxM(type) {
const match = /^\D+(\d+)x(\d+)$/u.exec(type);
if (match === null || match.length < 1) {
throw new Error(`Invalid parseTypeNxM input "${type}".`);
}
return [parseInt(match[1], 10), parseInt(match[2], 10)];
}
//# sourceMappingURL=ethereumjs-abi-utils.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!