diff --git a/contracts/test-utils/CHANGELOG.json b/contracts/test-utils/CHANGELOG.json index 52d1e62168..a5fff1105f 100644 --- a/contracts/test-utils/CHANGELOG.json +++ b/contracts/test-utils/CHANGELOG.json @@ -81,6 +81,10 @@ { "note": "Add `Numberish` type.", "pr": 2131 + }, + { + "note": "Tweaks/Upgrades to `hex_utils`, most notably `hexSlice()`", + "pr": "TODO" } ] }, diff --git a/contracts/test-utils/src/hex_utils.ts b/contracts/test-utils/src/hex_utils.ts index fef17f1e35..05b7a9c781 100644 --- a/contracts/test-utils/src/hex_utils.ts +++ b/contracts/test-utils/src/hex_utils.ts @@ -3,6 +3,7 @@ import * as crypto from 'crypto'; import * as ethUtil from 'ethereumjs-util'; import { constants } from './constants'; +import { Numberish } from './types'; const { WORD_LENGTH } = constants; const WORD_CEIL = new BigNumber(2).pow(WORD_LENGTH * 8); @@ -24,39 +25,44 @@ export function hexRandom(size: number = WORD_LENGTH): string { /** * Left-pad a hex number to a number of bytes. */ -export function hexLeftPad(n: string | BigNumber | number, size: number = WORD_LENGTH): string { +export function hexLeftPad(n: Numberish, size: number = WORD_LENGTH): string { return ethUtil.bufferToHex(ethUtil.setLengthLeft(toHex(n), size)); } /** * Right-pad a hex number to a number of bytes. */ -export function hexRightPad(n: string | BigNumber | number, size: number = WORD_LENGTH): string { +export function hexRightPad(n: Numberish, size: number = WORD_LENGTH): string { return ethUtil.bufferToHex(ethUtil.setLengthRight(toHex(n), size)); } /** * Inverts a hex word. */ -export function hexInvert(n: string | BigNumber | number, size: number = WORD_LENGTH): string { +export function hexInvert(n: Numberish, size: number = WORD_LENGTH): string { const buf = ethUtil.setLengthLeft(toHex(n), size); // tslint:disable-next-line: no-bitwise return ethUtil.bufferToHex(Buffer.from(buf.map(b => ~b))); } /** - * Slices off the desired number of bytes from a hex number. + * Slices a hex number. */ -export function hexSlice(n: string | BigNumber | number, size: number): string { - const hex = toHex(n); - return '0x'.concat(toHex(n).slice(size * 2 + 2, hex.length)); +export function hexSlice(n: Numberish, start: number, end?: number): string { + const hex = toHex(n).substr(2); + const sliceStart = start >= 0 ? start * 2 : Math.max(0, hex.length + start * 2); + let sliceEnd = hex.length; + if (end !== undefined) { + sliceEnd = end >= 0 ? end * 2 : Math.max(0, hex.length + end * 2); + } + return '0x'.concat(hex.substring(sliceStart, sliceEnd)); } /** * Convert a string, a number, or a BigNumber into a hex string. * Works with negative numbers, as well. */ -export function toHex(n: string | BigNumber | number, size: number = WORD_LENGTH): string { +export function toHex(n: Numberish, size: number = WORD_LENGTH): string { if (typeof n === 'string' && /^0x[0-9a-f]+$/i.test(n)) { // Already a hex. return n; @@ -64,7 +70,14 @@ export function toHex(n: string | BigNumber | number, size: number = WORD_LENGTH let _n = new BigNumber(n); if (_n.isNegative()) { // Perform two's-complement. - _n = new BigNumber(hexInvert(toHex(_n.abs()), size).substr(2), 16).plus(1).mod(WORD_CEIL); + // prettier-ignore + _n = new BigNumber( + hexInvert( + toHex(_n.abs()), + size, + ).substr(2), + 16, + ).plus(1).mod(WORD_CEIL); } return `0x${_n.toString(16)}`; }