diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..60ddad86 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +node_modules +.vscode +package.json +dist +.nyc_output +test/testdata +docs diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ee36cb..0198ce70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,106 +1,117 @@ # Changelog + All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -(modification: no type change headlines) and this project adheres to +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +(modification: no type change headlines) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - ## [6.0.0] - 2018-10-08 -- Support for ``EIP-155`` replay protection by adding an optional ``chainId`` parameter - to ``ecsign()``, ``ecrecover()``, ``toRpcSig()`` and ``isValidSignature()``, if present the - new signature format relying on the ``chainId`` is used, see PR [#143](https://github.com/ethereumjs/ethereumjs-util/pull/143) -- New ``generateAddress2()`` for ``CREATE2`` opcode (``EIP-1014``) address creation + +- Support for `EIP-155` replay protection by adding an optional `chainId` parameter + to `ecsign()`, `ecrecover()`, `toRpcSig()` and `isValidSignature()`, if present the + new signature format relying on the `chainId` is used, see PR [#143](https://github.com/ethereumjs/ethereumjs-util/pull/143) +- New `generateAddress2()` for `CREATE2` opcode (`EIP-1014`) address creation (Constantinople HF), see PR [#146](https://github.com/ethereumjs/ethereumjs-util/pull/146) -- [BREAKING] Fixed signature to comply with Geth and Parity in ``toRpcSig()`` changing - ``v`` from 0/1 to 27/28, this changes the resulting signature buffer, see PR [#139](https://github.com/ethereumjs/ethereumjs-util/pull/139) -- [BREAKING] Remove deprecated ``sha3``-named constants and methods (see ``v5.2.0`` release), +- [BREAKING] Fixed signature to comply with Geth and Parity in `toRpcSig()` changing + `v` from 0/1 to 27/28, this changes the resulting signature buffer, see PR [#139](https://github.com/ethereumjs/ethereumjs-util/pull/139) +- [BREAKING] Remove deprecated `sha3`-named constants and methods (see `v5.2.0` release), see PR [#154](https://github.com/ethereumjs/ethereumjs-util/pull/154) [6.0.0]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.2.0...v6.0.0 ## [5.2.0] - 2018-04-27 -- Rename all ``sha3`` hash related constants and functions to ``keccak``, see + +- Rename all `sha3` hash related constants and functions to `keccak`, see [this](https://github.com/ethereum/EIPs/issues/59) EIP discussion for context (tl;dr: Ethereum uses a slightly different hash algorithm then in the official - ``SHA-3`` standard) + `SHA-3` standard) - Renamed constants: - - ``SHA3_NULL_S`` -> ``KECCAK256_NULL_S`` - - ``SHA3_NULL`` -> ``KECCAK256_NULL`` - - ``SHA3_RLP_ARRAY_S`` -> ``KECCAK256_RLP_ARRAY_S`` - - ``SHA3_RLP_ARRAY`` -> ``KECCAK256_RLP_ARRAY`` - - ``SHA3_RLP_S`` -> ``KECCAK256_RLP_S`` - - ``SHA3_RLP`` -> ``KECCAK256_RLP`` + - `SHA3_NULL_S` -> `KECCAK256_NULL_S` + - `SHA3_NULL` -> `KECCAK256_NULL` + - `SHA3_RLP_ARRAY_S` -> `KECCAK256_RLP_ARRAY_S` + - `SHA3_RLP_ARRAY` -> `KECCAK256_RLP_ARRAY` + - `SHA3_RLP_S` -> `KECCAK256_RLP_S` + - `SHA3_RLP` -> `KECCAK256_RLP` - Renamed functions: - - ``sha3()`` -> ``keccak()`` (number of bits determined in arguments) -- New ``keccak256()`` alias function for ``keccak(a, 256)`` -- The usage of the ``sha``-named versions is now ``DEPRECATED`` and the related - constants and functions will be removed on the next major release ``v6.0.0`` + - `sha3()` -> `keccak()` (number of bits determined in arguments) +- New `keccak256()` alias function for `keccak(a, 256)` +- The usage of the `sha`-named versions is now `DEPRECATED` and the related + constants and functions will be removed on the next major release `v6.0.0` [5.2.0]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.5...v5.2.0 ## [5.1.5] - 2018-02-28 -- Fix ``browserify`` issue leading to 3rd-party build problems, PR [#119](https://github.com/ethereumjs/ethereumjs-util/pull/119) + +- Fix `browserify` issue leading to 3rd-party build problems, PR [#119](https://github.com/ethereumjs/ethereumjs-util/pull/119) [5.1.5]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.4...v5.1.5 ## [5.1.4] - 2018-02-03 -- Moved to ``ES5`` Node distribution version for easier toolchain integration, PR [#114](https://github.com/ethereumjs/ethereumjs-util/pull/114) -- Updated ``isPrecompile()`` with Byzantium precompile address range, PR [#115](https://github.com/ethereumjs/ethereumjs-util/pull/115) + +- Moved to `ES5` Node distribution version for easier toolchain integration, PR [#114](https://github.com/ethereumjs/ethereumjs-util/pull/114) +- Updated `isPrecompile()` with Byzantium precompile address range, PR [#115](https://github.com/ethereumjs/ethereumjs-util/pull/115) [5.1.4]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.3...v5.1.4 ## [5.1.3] - 2018-01-03 -- ``ES6`` syntax updates -- Dropped Node ``5`` support -- Moved babel to dev dependencies, switched to ``env`` preset -- Usage of ``safe-buffer`` instead of Node ``Buffer`` -- Do not allow capital ``0X`` as valid address in ``isValidAddress()`` -- New methods ``zeroAddress()`` and ``isZeroAddress()`` + +- `ES6` syntax updates +- Dropped Node `5` support +- Moved babel to dev dependencies, switched to `env` preset +- Usage of `safe-buffer` instead of Node `Buffer` +- Do not allow capital `0X` as valid address in `isValidAddress()` +- New methods `zeroAddress()` and `isZeroAddress()` - Updated dependencies [5.1.3]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.2...v5.1.3 ## [5.1.2] - 2017-05-31 -- Add browserify for ``ES2015`` compatibility + +- Add browserify for `ES2015` compatibility - Fix hex validation [5.1.2]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.1...v5.1.2 ## [5.1.1] - 2017-02-10 -- Use hex utils from ``ethjs-util`` + +- Use hex utils from `ethjs-util` - Move secp vars into functions - Dependency updates [5.1.1]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.1.0...v5.1.1 ## [5.1.0] - 2017-02-04 -- Fix ``toRpcSig()`` function -- Updated Buffer creation (``Buffer.from``) + +- Fix `toRpcSig()` function +- Updated Buffer creation (`Buffer.from`) - Dependency updates - Fix npm error -- Use ``keccak`` package instead of ``keccakjs`` -- Helpers for ``eth_sign`` RPC call +- Use `keccak` package instead of `keccakjs` +- Helpers for `eth_sign` RPC call [5.1.0]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.0.1...v5.1.0 ## [5.0.1] - 2016-11-08 -- Fix ``bufferToHex()`` + +- Fix `bufferToHex()` [5.0.1]: https://github.com/ethereumjs/ethereumjs-util/compare/v5.0.0...v5.0.1 ## [5.0.0] - 2016-11-08 -- Added ``isValidSignature()`` (ECDSA signature validation) -- Change ``v`` param in ``ecrecover()`` from ``Buffer`` to ``int`` (breaking change!) + +- Added `isValidSignature()` (ECDSA signature validation) +- Change `v` param in `ecrecover()` from `Buffer` to `int` (breaking change!) - Fix property alias for setting with initial parameters -- Reject invalid signature lengths for ``fromRpcSig()`` -- Fix ``sha3()`` ``width`` param (byte -> bit) -- Fix overflow bug in ``bufferToInt()`` +- Reject invalid signature lengths for `fromRpcSig()` +- Fix `sha3()` `width` param (byte -> bit) +- Fix overflow bug in `bufferToInt()` [5.0.0]: https://github.com/ethereumjs/ethereumjs-util/compare/v4.5.0...v5.0.0 ## [4.5.0] - 2016-17-12 -- Introduced ``toMessageSig()`` and ``fromMessageSig()`` + +- Introduced `toMessageSig()` and `fromMessageSig()` [4.5.0]: https://github.com/ethereumjs/ethereumjs-util/compare/v4.4.1...v4.5.0 @@ -113,4 +124,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) - [4.2.0](https://github.com/ethereumjs/ethereumjs-util/compare/v4.1.0...v4.2.0) - 2016-03-18 - [4.1.0](https://github.com/ethereumjs/ethereumjs-util/compare/v4.0.0...v4.1.0) - 2016-03-08 - [4.0.0](https://github.com/ethereumjs/ethereumjs-util/compare/v3.0.0...v4.0.0) - 2016-02-02 -- [3.0.0](https://github.com/ethereumjs/ethereumjs-util/compare/v2.0.0...v3.0.0) - 2016-01-20 \ No newline at end of file +- [3.0.0](https://github.com/ethereumjs/ethereumjs-util/compare/v2.0.0...v3.0.0) - 2016-01-20 diff --git a/README.md b/README.md index 2362371c..e6f6640c 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,28 @@ # SYNOPSIS + [![NPM Package](https://img.shields.io/npm/v/ethereumjs-util.svg?style=flat-square)](https://www.npmjs.org/package/ethereumjs-util) [![Build Status](https://img.shields.io/travis/ethereumjs/ethereumjs-util.svg?branch=master&style=flat-square)](https://travis-ci.org/ethereumjs/ethereumjs-util) [![Coverage Status](https://img.shields.io/coveralls/ethereumjs/ethereumjs-util.svg?style=flat-square)](https://coveralls.io/r/ethereumjs/ethereumjs-util) -[![Gitter](https://img.shields.io/gitter/room/ethereum/ethereumjs-lib.svg?style=flat-square)](https://gitter.im/ethereum/ethereumjs-lib) or #ethereumjs on freenode - -[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) - +[![Gitter](https://img.shields.io/gitter/room/ethereum/ethereumjs-lib.svg?style=flat-square)](https://gitter.im/ethereum/ethereumjs-lib) or #ethereumjs on freenode +[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) A collection of utility functions for ethereum. It can be used in node.js or can be in the browser with browserify. # API -[./docs/](./docs/index.md) + +[./docs/](./docs/README.md) Most of the string manipulation methods are provided by [ethjs-util](https://github.com/ethjs/ethjs-util) +--- + +Additionally ethereumjs-util re-exports a few commonly-used libraries. These include: + +- `BN` ([bn.js](https://github.com/indutny/bn.js)) +- `rlp` ([rlp](https://github.com/ethereumjs/rlp)) +- `secp256k1` ([secp256k1](https://github.com/cryptocoinjs/secp256k1-node/)) + # LICENSE + MPL-2.0 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..356b125a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,920 @@ + +# ethereumjs-util + +## Index + +### Interfaces + +* [ECDSASignature](interfaces/ecdsasignature.md) + +### Variables + +* [KECCAK256_NULL](#keccak256_null) +* [KECCAK256_NULL_S](#keccak256_null_s) +* [KECCAK256_RLP](#keccak256_rlp) +* [KECCAK256_RLP_ARRAY](#keccak256_rlp_array) +* [KECCAK256_RLP_ARRAY_S](#keccak256_rlp_array_s) +* [KECCAK256_RLP_S](#keccak256_rlp_s) +* [MAX_INTEGER](#max_integer) +* [TWO_POW256](#two_pow256) +* [publicToAddress](#publictoaddress) +* [setLength](#setlength) +* [stripZeros](#stripzeros) + +### Functions + +* [addHexPrefix](#addhexprefix) +* [baToJSON](#batojson) +* [bufferToHex](#buffertohex) +* [bufferToInt](#buffertoint) +* [defineProperties](#defineproperties) +* [ecrecover](#ecrecover) +* [ecsign](#ecsign) +* [fromRpcSig](#fromrpcsig) +* [fromSigned](#fromsigned) +* [generateAddress](#generateaddress) +* [generateAddress2](#generateaddress2) +* [hashPersonalMessage](#hashpersonalmessage) +* [importPublic](#importpublic) +* [isPrecompiled](#isprecompiled) +* [isValidAddress](#isvalidaddress) +* [isValidChecksumAddress](#isvalidchecksumaddress) +* [isValidPrivate](#isvalidprivate) +* [isValidPublic](#isvalidpublic) +* [isValidSignature](#isvalidsignature) +* [isZeroAddress](#iszeroaddress) +* [keccak](#keccak) +* [keccak256](#keccak256) +* [privateToAddress](#privatetoaddress) +* [privateToPublic](#privatetopublic) +* [pubToAddress](#pubtoaddress) +* [ripemd160](#ripemd160) +* [rlphash](#rlphash) +* [setLengthLeft](#setlengthleft) +* [setLengthRight](#setlengthright) +* [sha256](#sha256) +* [toBuffer](#tobuffer) +* [toChecksumAddress](#tochecksumaddress) +* [toRpcSig](#torpcsig) +* [toUnsigned](#tounsigned) +* [unpad](#unpad) +* [zeroAddress](#zeroaddress) +* [zeros](#zeros) + +--- + +## Variables + + + +### `` KECCAK256_NULL + +**● KECCAK256_NULL**: *`Buffer`* = Buffer.from(KECCAK256_NULL_S, 'hex') + +*Defined in [index.ts:42](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L42)* + +Keccak-256 hash of null + +___ + + +### `` KECCAK256_NULL_S + +**● KECCAK256_NULL_S**: *`string`* = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + +*Defined in [index.ts:36](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L36)* + +Keccak-256 hash of null + +___ + + +### `` KECCAK256_RLP + +**● KECCAK256_RLP**: *`Buffer`* = Buffer.from(KECCAK256_RLP_S, 'hex') + +*Defined in [index.ts:64](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L64)* + +Keccak-256 hash of the RLP of null + +___ + + +### `` KECCAK256_RLP_ARRAY + +**● KECCAK256_RLP_ARRAY**: *`Buffer`* = Buffer.from(KECCAK256_RLP_ARRAY_S, 'hex') + +*Defined in [index.ts:53](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L53)* + +Keccak-256 of an RLP of an empty array + +___ + + +### `` KECCAK256_RLP_ARRAY_S + +**● KECCAK256_RLP_ARRAY_S**: *`string`* = "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + +*Defined in [index.ts:47](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L47)* + +Keccak-256 of an RLP of an empty array + +___ + + +### `` KECCAK256_RLP_S + +**● KECCAK256_RLP_S**: *`string`* = "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + +*Defined in [index.ts:58](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L58)* + +Keccak-256 hash of the RLP of null + +___ + + +### `` MAX_INTEGER + +**● MAX_INTEGER**: *`BN`* = new BN( + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + 16, +) + +*Defined in [index.ts:20](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L20)* + +The max integer that this VM can handle + +___ + + +### `` TWO_POW256 + +**● TWO_POW256**: *`BN`* = new BN( + '10000000000000000000000000000000000000000000000000000000000000000', + 16, +) + +*Defined in [index.ts:28](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L28)* + +2^256 + +___ + + +### `` publicToAddress + +**● publicToAddress**: *[pubToAddress]()* = pubToAddress + +*Defined in [index.ts:315](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L315)* + +___ + + +### `` setLength + +**● setLength**: *[setLengthLeft]()* = setLengthLeft + +*Defined in [index.ts:123](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L123)* + +___ + + +### `` stripZeros + +**● stripZeros**: *[unpad]()* = unpad + +*Defined in [index.ts:150](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L150)* + +___ + +## Functions + + + +### `` addHexPrefix + +▸ **addHexPrefix**(str: *`string`*): `string` + +*Defined in [index.ts:532](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L532)* + +Adds "0x" to a given `String` if it does not already start with "0x". + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| str | `string` | + +**Returns:** `string` + +___ + + +### `` baToJSON + +▸ **baToJSON**(ba: *`any`*): `undefined` | `string` | `any`[] + +*Defined in [index.ts:584](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L584)* + +Converts a `Buffer` or `Array` to JSON. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| ba | `any` | (Buffer|Array) | + +**Returns:** `undefined` | `string` | `any`[] +(Array|String|null) + +___ + + +### `` bufferToHex + +▸ **bufferToHex**(buf: *`Buffer`*): `string` + +*Defined in [index.ts:195](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L195)* + +Converts a `Buffer` into a hex `String`. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| buf | `Buffer` | \`Buffer\` object to convert | + +**Returns:** `string` + +___ + + +### `` bufferToInt + +▸ **bufferToInt**(buf: *`Buffer`*): `number` + +*Defined in [index.ts:187](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L187)* + +Converts a `Buffer` to a `Number`. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| buf | `Buffer` | \`Buffer\` object to convert | + +**Returns:** `number` + +___ + + +### `` defineProperties + +▸ **defineProperties**(self: *`any`*, fields: *`any`*, data: *`any`*): `void` + +*Defined in [index.ts:606](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L606)* + +Defines properties on a `Object`. It make the assumption that underlying data is binary. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| self | `any` | the \`Object\` to define properties on | +| fields | `any` | an array fields to define. Fields can contain:* \`name\` - the name of the properties* \`length\` - the number of bytes the field can have* \`allowLess\` - if the field can be less than the length* \`allowEmpty\` | +| data | `any` | data to be validated against the definitions | + +**Returns:** `void` + +___ + + +### `` ecrecover + +▸ **ecrecover**(msgHash: *`Buffer`*, v: *`number`*, r: *`Buffer`*, s: *`Buffer`*, chainId?: *`undefined` | `number`*): `Buffer` + +*Defined in [index.ts:373](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L373)* + +ECDSA public key recovery from signature. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| msgHash | `Buffer` | +| v | `number` | +| r | `Buffer` | +| s | `Buffer` | +| `Optional` chainId | `undefined` | `number` | + +**Returns:** `Buffer` +Recovered public key + +___ + + +### `` ecsign + +▸ **ecsign**(msgHash: *`Buffer`*, privateKey: *`Buffer`*, chainId?: *`undefined` | `number`*): [ECDSASignature](interfaces/ecdsasignature.md) + +*Defined in [index.ts:341](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L341)* + +Returns the ECDSA signature of a message hash. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| msgHash | `Buffer` | +| privateKey | `Buffer` | +| `Optional` chainId | `undefined` | `number` | + +**Returns:** [ECDSASignature](interfaces/ecdsasignature.md) + +___ + + +### `` fromRpcSig + +▸ **fromRpcSig**(sig: *`string`*): [ECDSASignature](interfaces/ecdsasignature.md) + +*Defined in [index.ts:407](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L407)* + +Convert signature format of the `eth_sign` RPC method to signature parameters NOTE: all because of a bug in geth: [https://github.com/ethereum/go-ethereum/issues/2053](https://github.com/ethereum/go-ethereum/issues/2053) + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| sig | `string` | + +**Returns:** [ECDSASignature](interfaces/ecdsasignature.md) + +___ + + +### `` fromSigned + +▸ **fromSigned**(num: *`Buffer`*): `BN` + +*Defined in [index.ts:204](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L204)* + +Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| num | `Buffer` | Signed integer value | + +**Returns:** `BN` + +___ + + +### `` generateAddress + +▸ **generateAddress**(from: *`Buffer`*, nonce: *`Buffer`*): `Buffer` + +*Defined in [index.ts:482](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L482)* + +Generates an address of a newly created contract. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| from | `Buffer` | The address which is creating this new address | +| nonce | `Buffer` | The nonce of the from account | + +**Returns:** `Buffer` + +___ + + +### `` generateAddress2 + +▸ **generateAddress2**(from: *`Buffer` | `string`*, salt: *`Buffer` | `string`*, initCode: *`Buffer` | `string`*): `Buffer` + +*Defined in [index.ts:502](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L502)* + +Generates an address for a contract created using CREATE2. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| from | `Buffer` | `string` | The address which is creating this new address | +| salt | `Buffer` | `string` | A salt | +| initCode | `Buffer` | `string` | The init code of the contract being created | + +**Returns:** `Buffer` + +___ + + +### `` hashPersonalMessage + +▸ **hashPersonalMessage**(message: *`any`*): `Buffer` + +*Defined in [index.ts:364](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L364)* + +Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call. The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign` call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key used to produce the signature. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| message | `any` | + +**Returns:** `Buffer` + +___ + + +### `` importPublic + +▸ **importPublic**(publicKey: *`Buffer`*): `Buffer` + +*Defined in [index.ts:330](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L330)* + +Converts a public key to the Ethereum format. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| publicKey | `Buffer` | + +**Returns:** `Buffer` + +___ + + +### `` isPrecompiled + +▸ **isPrecompiled**(address: *`Buffer` | `string`*): `boolean` + +*Defined in [index.ts:524](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L524)* + +Returns true if the supplied address belongs to a precompiled account (Byzantium). + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| address | `Buffer` | `string` | + +**Returns:** `boolean` + +___ + + +### `` isValidAddress + +▸ **isValidAddress**(address: *`string`*): `boolean` + +*Defined in [index.ts:439](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L439)* + +Checks if the address is a valid. Accepts checksummed addresses too. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| address | `string` | + +**Returns:** `boolean` + +___ + + +### `` isValidChecksumAddress + +▸ **isValidChecksumAddress**(address: *`string`*): `boolean` + +*Defined in [index.ts:473](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L473)* + +Checks if the address is a valid checksummed address. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| address | `string` | + +**Returns:** `boolean` + +___ + + +### `` isValidPrivate + +▸ **isValidPrivate**(privateKey: *`Buffer`*): `boolean` + +*Defined in [index.ts:277](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L277)* + +Checks if the private key satisfies the rules of the curve secp256k1. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| privateKey | `Buffer` | + +**Returns:** `boolean` + +___ + + +### `` isValidPublic + +▸ **isValidPublic**(publicKey: *`Buffer`*, sanitize?: *`boolean`*): `boolean` + +*Defined in [index.ts:287](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L287)* + +Checks if the public key satisfies the rules of the curve secp256k1 and the requirements of Ethereum. + +**Parameters:** + +| Name | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| publicKey | `Buffer` | - | The two points of an uncompressed key, unless sanitize is enabled | +| `Default value` sanitize | `boolean` | false | Accept public keys in other formats | + +**Returns:** `boolean` + +___ + + +### `` isValidSignature + +▸ **isValidSignature**(v: *`number`*, r: *`Buffer`*, s: *`Buffer`*, homesteadOrLater?: *`boolean`*, chainId?: *`undefined` | `number`*): `boolean` + +*Defined in [index.ts:544](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L544)* + +Validate a ECDSA signature. + +**Parameters:** + +| Name | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| v | `number` | - | +| r | `Buffer` | - | +| s | `Buffer` | - | +| `Default value` homesteadOrLater | `boolean` | true | Indicates whether this is being used on either the homestead hardfork or a later one | +| `Optional` chainId | `undefined` | `number` | - | + +**Returns:** `boolean` + +___ + + +### `` isZeroAddress + +▸ **isZeroAddress**(address: *`string`*): `boolean` + +*Defined in [index.ts:446](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L446)* + +Checks if a given address is a zero address. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| address | `string` | + +**Returns:** `boolean` + +___ + + +### `` keccak + +▸ **keccak**(a: *`any`*, bits?: *`number`*): `Buffer` + +*Defined in [index.ts:221](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L221)* + +Creates Keccak hash of the input + +**Parameters:** + +| Name | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| a | `any` | - | The input data (Buffer|Array|String|Number) | +| `Default value` bits | `number` | 256 | The Keccak width | + +**Returns:** `Buffer` + +___ + + +### `` keccak256 + +▸ **keccak256**(a: *`any`*): `Buffer` + +*Defined in [index.ts:234](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L234)* + +Creates Keccak-256 hash of the input, alias for keccak(a, 256). + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| a | `any` | The input data (Buffer|Array|String|Number) | + +**Returns:** `Buffer` + +___ + + +### `` privateToAddress + +▸ **privateToAddress**(privateKey: *`Buffer`*): `Buffer` + +*Defined in [index.ts:432](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L432)* + +Returns the ethereum address of a given private key. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| privateKey | `Buffer` | A private key must be 256 bits wide | + +**Returns:** `Buffer` + +___ + + +### `` privateToPublic + +▸ **privateToPublic**(privateKey: *`Buffer`*): `Buffer` + +*Defined in [index.ts:321](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L321)* + +Returns the ethereum public key of a given private key. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| privateKey | `Buffer` | A private key must be 256 bits wide | + +**Returns:** `Buffer` + +___ + + +### `` pubToAddress + +▸ **pubToAddress**(pubKey: *`Buffer`*, sanitize?: *`boolean`*): `Buffer` + +*Defined in [index.ts:306](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L306)* + +Returns the ethereum address of a given public key. Accepts "Ethereum public keys" and SEC1 encoded keys. + +**Parameters:** + +| Name | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| pubKey | `Buffer` | - | The two points of an uncompressed key, unless sanitize is enabled | +| `Default value` sanitize | `boolean` | false | Accept public keys in other formats | + +**Returns:** `Buffer` + +___ + + +### `` ripemd160 + +▸ **ripemd160**(a: *`any`*, padded: *`boolean`*): `Buffer` + +*Defined in [index.ts:254](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L254)* + +Creates RIPEMD160 hash of the input. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| a | `any` | The input data (Buffer|Array|String|Number) | +| padded | `boolean` | Whether it should be padded to 256 bits or not | + +**Returns:** `Buffer` + +___ + + +### `` rlphash + +▸ **rlphash**(a: *`rlp.Input`*): `Buffer` + +*Defined in [index.ts:270](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L270)* + +Creates SHA-3 hash of the RLP encoded version of the input. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| a | `rlp.Input` | The input data | + +**Returns:** `Buffer` + +___ + + +### `` setLengthLeft + +▸ **setLengthLeft**(msg: *`any`*, length: *`number`*, right?: *`boolean`*): `any` + +*Defined in [index.ts:106](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L106)* + +Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. Or it truncates the beginning if it exceeds. + +**Parameters:** + +| Name | Type | Default value | Description | +| ------ | ------ | ------ | ------ | +| msg | `any` | - | the value to pad (Buffer|Array) | +| length | `number` | - | the number of bytes the output should be | +| `Default value` right | `boolean` | false | whether to start padding form the left or right | + +**Returns:** `any` +(Buffer|Array) + +___ + + +### `` setLengthRight + +▸ **setLengthRight**(msg: *`any`*, length: *`number`*): `any` + +*Defined in [index.ts:132](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L132)* + +Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. Or it truncates the beginning if it exceeds. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| msg | `any` | the value to pad (Buffer|Array) | +| length | `number` | the number of bytes the output should be | + +**Returns:** `any` +(Buffer|Array) + +___ + + +### `` sha256 + +▸ **sha256**(a: *`any`*): `Buffer` + +*Defined in [index.ts:242](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L242)* + +Creates SHA256 hash of the input. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| a | `any` | The input data (Buffer|Array|String|Number) | + +**Returns:** `Buffer` + +___ + + +### `` toBuffer + +▸ **toBuffer**(v: *`any`*): `Buffer` + +*Defined in [index.ts:156](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L156)* + +Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| v | `any` | the value | + +**Returns:** `Buffer` + +___ + + +### `` toChecksumAddress + +▸ **toChecksumAddress**(address: *`string`*): `string` + +*Defined in [index.ts:454](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L454)* + +Returns a checksummed address. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| address | `string` | + +**Returns:** `string` + +___ + + +### `` toRpcSig + +▸ **toRpcSig**(v: *`number`*, r: *`Buffer`*, s: *`Buffer`*, chainId?: *`undefined` | `number`*): `string` + +*Defined in [index.ts:393](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L393)* + +Convert signature parameters into the format of `eth_sign` RPC method. + +**Parameters:** + +| Name | Type | +| ------ | ------ | +| v | `number` | +| r | `Buffer` | +| s | `Buffer` | +| `Optional` chainId | `undefined` | `number` | + +**Returns:** `string` +Signature + +___ + + +### `` toUnsigned + +▸ **toUnsigned**(num: *`BN`*): `Buffer` + +*Defined in [index.ts:212](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L212)* + +Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| num | `BN` | | + +**Returns:** `Buffer` + +___ + + +### `` unpad + +▸ **unpad**(a: *`any`*): `any` + +*Defined in [index.ts:141](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L141)* + +Trims leading zeros from a `Buffer` or an `Array`. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| a | `any` | (Buffer|Array|String) | + +**Returns:** `any` +(Buffer|Array|String) + +___ + + +### `` zeroAddress + +▸ **zeroAddress**(): `string` + +*Defined in [index.ts:92](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L92)* + +Returns a zero address. + +**Returns:** `string` + +___ + + +### `` zeros + +▸ **zeros**(bytes: *`number`*): `Buffer` + +*Defined in [index.ts:85](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L85)* + +Returns a buffer filled with 0s. + +**Parameters:** + +| Name | Type | Description | +| ------ | ------ | ------ | +| bytes | `number` | the number of bytes the buffer should be | + +**Returns:** `Buffer` + +___ + diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 57818976..00000000 --- a/docs/index.md +++ /dev/null @@ -1,615 +0,0 @@ - - -### Table of Contents - -- [addHexPrefix](#addhexprefix) -- [baToJSON](#batojson) -- [BN](#bn) -- [bufferToHex](#buffertohex) -- [bufferToInt](#buffertoint) -- [defineProperties](#defineproperties) -- [ecrecover](#ecrecover) -- [ecsign](#ecsign) -- [fromRpcSig](#fromrpcsig) -- [fromSigned](#fromsigned) -- [generateAddress](#generateaddress) -- [generateAddress2](#generateaddress2) -- [hashPersonalMessage](#hashpersonalmessage) -- [importPublic](#importpublic) -- [isPrecompiled](#isprecompiled) -- [isValidAddress](#isvalidaddress) -- [isValidChecksumAddress](#isvalidchecksumaddress) -- [isValidPrivate](#isvalidprivate) -- [isValidPublic](#isvalidpublic) -- [keccak](#keccak) -- [keccak256](#keccak256) -- [privateToAddress](#privatetoaddress) -- [pubToAddress](#pubtoaddress) -- [ripemd160](#ripemd160) -- [rlp](#rlp) -- [rlphash](#rlphash) -- [secp256k1](#secp256k1) -- [setLengthRight](#setlengthright) -- [sha256](#sha256) -- [toBuffer](#tobuffer) -- [toChecksumAddress](#tochecksumaddress) -- [toRpcSig](#torpcsig) -- [toUnsigned](#tounsigned) -- [unpad](#unpad) -- [isValidSignature](#isvalidsignature) -- [isZeroAddress](#iszeroaddress) -- [KECCAK256_NULL](#keccak256_null) -- [KECCAK256_NULL_S](#keccak256_null_s) -- [KECCAK256_RLP](#keccak256_rlp) -- [KECCAK256_RLP_ARRAY](#keccak256_rlp_array) -- [KECCAK256_RLP_ARRAY_S](#keccak256_rlp_array_s) -- [KECCAK256_RLP_S](#keccak256_rlp_s) -- [setLengthLeft](#setLengthLeft) -- [MAX_INTEGER](#max_integer) -- [privateToPublic](#privatetopublic) -- [TWO_POW256](#two_pow256) -- [zeroAddress](#zeroaddress) -- [zeros](#zeros) - -## addHexPrefix - -[index.js:563-569](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L563-L569 "Source code on GitHub") - -Adds "0x" to a given `String` if it does not already start with "0x" - -**Parameters** - -- `str` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -## baToJSON - -[index.js:613-623](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L613-L623 "Source code on GitHub") - -Converts a `Buffer` or `Array` to JSON - -**Parameters** - -- `ba` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** - -Returns **([Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** - -## BN - -[index.js:62-62](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L62-L62 "Source code on GitHub") - -[`BN`](https://github.com/indutny/bn.js) - -Type: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) - -## bufferToHex - -[index.js:194-197](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L194-L197 "Source code on GitHub") - -Converts a `Buffer` into a hex `String` - -**Parameters** - -- `buf` **[Buffer](https://nodejs.org/api/buffer.html)** - -Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -## bufferToInt - -[index.js:185-187](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L185-L187 "Source code on GitHub") - -Converts a `Buffer` to a `Number` - -**Parameters** - -- `buf` **[Buffer](https://nodejs.org/api/buffer.html)** - - -- Throws **any** If the input number exceeds 53 bits. - -Returns **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** - -## defineProperties - -[index.js:635-728](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L635-L728 "Source code on GitHub") - -Defines properties on a `Object`. It make the assumption that underlying data is binary. - -**Parameters** - -- `self` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** the `Object` to define properties on -- `fields` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** an array fields to define. Fields can contain:- `name` - the name of the properties - - `length` - the number of bytes the field can have - - `allowLess` - if the field can be less than the length - - `allowEmpty` -- `data` **any** data to be validated against the definitions - -## ecrecover - -[index.js:383-391](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L383-L391 "Source code on GitHub") - -ECDSA public key recovery from signature - -**Parameters** - -- `msgHash` **[Buffer](https://nodejs.org/api/buffer.html)** -- `v` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `r` **[Buffer](https://nodejs.org/api/buffer.html)** -- `s` **[Buffer](https://nodejs.org/api/buffer.html)** -- `chainId` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** publicKey - -## ecsign - -[index.js:351-359](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L351-L359 "Source code on GitHub") - -ECDSA sign - -**Parameters** - -- `msgHash` **[Buffer](https://nodejs.org/api/buffer.html)** -- `privateKey` **[Buffer](https://nodejs.org/api/buffer.html)** -- `chainId` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** - -## fromRpcSig - -[index.js:421-440](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L421-L440 "Source code on GitHub") - -Convert signature format of the `eth_sign` RPC method to signature parameters -NOTE: all because of a bug in geth: - -**Parameters** - -- `sig` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** - -## fromSigned - -[index.js:204-206](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L204-L206 "Source code on GitHub") - -Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers. - -**Parameters** - -- `num` **[Buffer](https://nodejs.org/api/buffer.html)** - -Returns **BN** - -## generateAddress - -[index.js:507-521](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L507-L521 "Source code on GitHub") - -Generates an address of a newly created contract - -**Parameters** - -- `from` **[Buffer](https://nodejs.org/api/buffer.html)** the address which is creating this new address -- `nonce` **[Buffer](https://nodejs.org/api/buffer.html)** the nonce of the from account - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## generateAddress2 - -[index.js:530-546](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L530-L546 "Source code on GitHub") - -Generates an address for a contract created using CREATE2 - -**Parameters** - -- `from` **[Buffer](https://nodejs.org/api/buffer.html)** the address which is creating this new address -- `salt` **[Buffer](https://nodejs.org/api/buffer.html)** a salt -- `initCode` **[Buffer](https://nodejs.org/api/buffer.html)** the init code of the contract being created - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## hashPersonalMessage - -[index.js:369-372](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L369-L372 "Source code on GitHub") - -Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call. -The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign` -call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key -used to produce the signature. - -**Parameters** - -- `message` - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** hash - -## importPublic - -[index.js:336-342](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L336-L342 "Source code on GitHub") - -Converts a public key to the Ethereum format. - -**Parameters** - -- `publicKey` **[Buffer](https://nodejs.org/api/buffer.html)** - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## isPrecompiled - -[index.js:553-556](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L553-L556 "Source code on GitHub") - -Returns true if the supplied address belongs to a precompiled account (Byzantium) - -**Parameters** - -- `address` **([Buffer](https://nodejs.org/api/buffer.html) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## isValidAddress - -[index.js:456-458](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L456-L458 "Source code on GitHub") - -Checks if the address is a valid. Accepts checksummed addresses too - -**Parameters** - -- `address` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## isValidChecksumAddress - -[index.js:497-499](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L497-L499 "Source code on GitHub") - -Checks if the address is a valid checksummed address - -**Parameters** - -- `address` **[Buffer](https://nodejs.org/api/buffer.html)** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## isValidPrivate - -[index.js:279-281](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L279-L281 "Source code on GitHub") - -Checks if the private key satisfies the rules of the curve secp256k1. - -**Parameters** - -- `privateKey` **[Buffer](https://nodejs.org/api/buffer.html)** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## isValidPublic - -[index.js:290-301](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L290-L301 "Source code on GitHub") - -Checks if the public key satisfies the rules of the curve secp256k1 -and the requirements of Ethereum. - -**Parameters** - -- `publicKey` **[Buffer](https://nodejs.org/api/buffer.html)** The two points of an uncompressed key, unless sanitize is enabled -- `sanitize` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Accept public keys in other formats (optional, default `false`) - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## keccak - -[index.js:223-228](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L223-L228 "Source code on GitHub") - -Creates Keccak hash of the input - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** the input data -- `bits` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the Keccak width (optional, default `256`) - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## keccak256 - -[index.js:235-237](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L235-L237 "Source code on GitHub") - -Creates Keccak-256 hash of the input, alias for keccak(a, 256) - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** the input data - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## privateToAddress - -[index.js:447-449](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L447-L449 "Source code on GitHub") - -Returns the ethereum address of a given private key - -**Parameters** - -- `privateKey` **[Buffer](https://nodejs.org/api/buffer.html)** A private key must be 256 bits wide - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## pubToAddress - -[index.js:310-318](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L310-L318 "Source code on GitHub") - -Returns the ethereum address of a given public key. -Accepts "Ethereum public keys" and SEC1 encoded keys. - -**Parameters** - -- `pubKey` **[Buffer](https://nodejs.org/api/buffer.html)** The two points of an uncompressed key, unless sanitize is enabled -- `sanitize` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Accept public keys in other formats (optional, default `false`) - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## ripemd160 - -[index.js:255-263](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L255-L263 "Source code on GitHub") - -Creates RIPEMD160 hash of the input - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** the input data -- `padded` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether it should be padded to 256 bits or not - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## rlp - -[index.js:68-68](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L68-L68 "Source code on GitHub") - -[`rlp`](https://github.com/ethereumjs/rlp) - -Type: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) - -## rlphash - -[index.js:270-272](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L270-L272 "Source code on GitHub") - -Creates SHA-3 hash of the RLP encoded version of the input - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** the input data - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## secp256k1 - -[index.js:74-74](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L74-L74 "Source code on GitHub") - -[`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/) - -Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) - -## setLengthRight - -[index.js:131-133](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L131-L133 "Source code on GitHub") - -Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. -Or it truncates the beginning if it exceeds. - -**Parameters** - -- `msg` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** the value to pad -- `length` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of bytes the output should be - -Returns **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** - -## sha256 - -[index.js:244-247](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L244-L247 "Source code on GitHub") - -Creates SHA256 hash of the input - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number))** the input data - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## toBuffer - -[index.js:153-177](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L153-L177 "Source code on GitHub") - -Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method. - -**Parameters** - -- `v` **any** the value - -## toChecksumAddress - -[index.js:476-490](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L476-L490 "Source code on GitHub") - -Returns a checksummed address - -**Parameters** - -- `address` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -## toRpcSig - -[index.js:401-413](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L401-L413 "Source code on GitHub") - -Convert signature parameters into the format of `eth_sign` RPC method - -**Parameters** - -- `v` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `r` **[Buffer](https://nodejs.org/api/buffer.html)** -- `s` **[Buffer](https://nodejs.org/api/buffer.html)** -- `chainId` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** - -Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** sig - -## toUnsigned - -[index.js:213-215](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L213-L215 "Source code on GitHub") - -Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers. - -**Parameters** - -- `num` **BN** - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## unpad - -[index.js:140-148](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L140-L148 "Source code on GitHub") - -Trims leading zeros from a `Buffer` or an `Array` - -**Parameters** - -- `a` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** - -Returns **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** - -## isValidSignature - -[index.js:582-606](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L582-L606 "Source code on GitHub") - -Validate ECDSA signature - -**Parameters** - -- `v` **[Buffer](https://nodejs.org/api/buffer.html)** -- `r` **[Buffer](https://nodejs.org/api/buffer.html)** -- `s` **[Buffer](https://nodejs.org/api/buffer.html)** -- `homestead` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** (optional, default `true`) -- `chainId` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## isZeroAddress - -[index.js:466-469](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L466-L469 "Source code on GitHub") - -Checks if a given address is a zero address - -**Parameters** - -- `address` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -## KECCAK256_NULL - -[index.js:32-32](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L32-L32 "Source code on GitHub") - -Keccak-256 hash of null (a `Buffer`) - -Type: [Buffer](https://nodejs.org/api/buffer.html) - -## KECCAK256_NULL_S - -[index.js:26-26](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L26-L26 "Source code on GitHub") - -Keccak-256 hash of null (a `String`) - -Type: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) - -## KECCAK256_RLP - -[index.js:56-56](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L56-L56 "Source code on GitHub") - -Keccak-256 hash of the RLP of null (a `Buffer`) - -Type: [Buffer](https://nodejs.org/api/buffer.html) - -## KECCAK256_RLP_ARRAY - -[index.js:44-44](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L44-L44 "Source code on GitHub") - -Keccak-256 of an RLP of an empty array (a `Buffer`) - -Type: [Buffer](https://nodejs.org/api/buffer.html) - -## KECCAK256_RLP_ARRAY_S - -[index.js:38-38](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L38-L38 "Source code on GitHub") - -Keccak-256 of an RLP of an empty array (a `String`) - -Type: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) - -## KECCAK256_RLP_S - -[index.js:50-50](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L50-L50 "Source code on GitHub") - -Keccak-256 hash of the RLP of null (a `String`) - -Type: [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) - -## setLengthLeft - -[index.js:106-122](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L106-L122 "Source code on GitHub") - -Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. -Or it truncates the beginning if it exceeds. - -**Parameters** - -- `msg` **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** the value to pad -- `length` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of bytes the output should be -- `right` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** whether to start padding form the left or right (optional, default `false`) - -Returns **([Buffer](https://nodejs.org/api/buffer.html) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** - -## MAX_INTEGER - -[index.js:14-14](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L14-L14 "Source code on GitHub") - -the max integer that this VM can handle (a `BN`) - -Type: BN - -## privateToPublic - -[index.js:325-329](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L325-L329 "Source code on GitHub") - -Returns the ethereum public key of a given private key - -**Parameters** - -- `privateKey` **[Buffer](https://nodejs.org/api/buffer.html)** A private key must be 256 bits wide - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** - -## TWO_POW256 - -[index.js:20-20](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L20-L20 "Source code on GitHub") - -2^256 (a `BN`) - -Type: BN - -## zeroAddress - -[index.js:91-95](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L91-L95 "Source code on GitHub") - -Returns a zero address - -Returns **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -## zeros - -[index.js:82-84](https://github.com/ethereumjs/ethereumjs-util/blob/9396416913125711e526a05591e3ce8471c3a528/index.js#L82-L84 "Source code on GitHub") - -Returns a buffer filled with 0s - -**Parameters** - -- `bytes` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the number of bytes the buffer should be - -Returns **[Buffer](https://nodejs.org/api/buffer.html)** diff --git a/docs/interfaces/ecdsasignature.md b/docs/interfaces/ecdsasignature.md new file mode 100644 index 00000000..7e03e810 --- /dev/null +++ b/docs/interfaces/ecdsasignature.md @@ -0,0 +1,48 @@ +[ethereumjs-util](../README.md) > [ECDSASignature](../interfaces/ecdsasignature.md) + +# Interface: ECDSASignature + +## Hierarchy + +**ECDSASignature** + +## Index + +### Properties + +* [r](ecdsasignature.md#r) +* [s](ecdsasignature.md#s) +* [v](ecdsasignature.md#v) + +--- + +## Properties + + + +### r + +**● r**: *`Buffer`* + +*Defined in [index.ts:13](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L13)* + +___ + + +### s + +**● s**: *`Buffer`* + +*Defined in [index.ts:14](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L14)* + +___ + + +### v + +**● v**: *`number`* + +*Defined in [index.ts:12](https://github.com/ethereumjs/ethereumjs-util/blob/dd56e02/src/index.ts#L12)* + +___ + diff --git a/index.js b/index.js deleted file mode 100644 index 9bd6a2a6..00000000 --- a/index.js +++ /dev/null @@ -1,737 +0,0 @@ -const createKeccakHash = require('keccak') -const secp256k1 = require('secp256k1') -const assert = require('assert') -const rlp = require('rlp') -const BN = require('bn.js') -const createHash = require('create-hash') -const Buffer = require('safe-buffer').Buffer -Object.assign(exports, require('ethjs-util')) - -/** - * the max integer that this VM can handle (a ```BN```) - * @var {BN} MAX_INTEGER - */ -exports.MAX_INTEGER = new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16) - -/** - * 2^256 (a ```BN```) - * @var {BN} TWO_POW256 - */ -exports.TWO_POW256 = new BN('10000000000000000000000000000000000000000000000000000000000000000', 16) - -/** - * Keccak-256 hash of null (a ```String```) - * @var {String} KECCAK256_NULL_S - */ -exports.KECCAK256_NULL_S = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' - -/** - * Keccak-256 hash of null (a ```Buffer```) - * @var {Buffer} KECCAK256_NULL - */ -exports.KECCAK256_NULL = Buffer.from(exports.KECCAK256_NULL_S, 'hex') - -/** - * Keccak-256 of an RLP of an empty array (a ```String```) - * @var {String} KECCAK256_RLP_ARRAY_S - */ -exports.KECCAK256_RLP_ARRAY_S = '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347' - -/** - * Keccak-256 of an RLP of an empty array (a ```Buffer```) - * @var {Buffer} KECCAK256_RLP_ARRAY - */ -exports.KECCAK256_RLP_ARRAY = Buffer.from(exports.KECCAK256_RLP_ARRAY_S, 'hex') - -/** - * Keccak-256 hash of the RLP of null (a ```String```) - * @var {String} KECCAK256_RLP_S - */ -exports.KECCAK256_RLP_S = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' - -/** - * Keccak-256 hash of the RLP of null (a ```Buffer```) - * @var {Buffer} KECCAK256_RLP - */ -exports.KECCAK256_RLP = Buffer.from(exports.KECCAK256_RLP_S, 'hex') - -/** - * [`BN`](https://github.com/indutny/bn.js) - * @var {Function} - */ -exports.BN = BN - -/** - * [`rlp`](https://github.com/ethereumjs/rlp) - * @var {Function} - */ -exports.rlp = rlp - -/** - * [`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/) - * @var {Object} - */ -exports.secp256k1 = secp256k1 - -/** - * Returns a buffer filled with 0s - * @method zeros - * @param {Number} bytes the number of bytes the buffer should be - * @return {Buffer} - */ -exports.zeros = function (bytes) { - return Buffer.allocUnsafe(bytes).fill(0) -} - -/** - * Returns a zero address - * @method zeroAddress - * @return {String} - */ -exports.zeroAddress = function () { - const addressLength = 20 - const zeroAddress = exports.zeros(addressLength) - return exports.bufferToHex(zeroAddress) -} - -/** - * Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. - * Or it truncates the beginning if it exceeds. - * @method setLengthLeft - * @param {Buffer|Array} msg the value to pad - * @param {Number} length the number of bytes the output should be - * @param {Boolean} [right=false] whether to start padding form the left or right - * @return {Buffer|Array} - */ -exports.setLengthLeft = exports.setLength = function (msg, length, right) { - const buf = exports.zeros(length) - msg = exports.toBuffer(msg) - if (right) { - if (msg.length < length) { - msg.copy(buf) - return buf - } - return msg.slice(0, length) - } else { - if (msg.length < length) { - msg.copy(buf, length - msg.length) - return buf - } - return msg.slice(-length) - } -} - -/** - * Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. - * Or it truncates the beginning if it exceeds. - * @param {Buffer|Array} msg the value to pad - * @param {Number} length the number of bytes the output should be - * @return {Buffer|Array} - */ -exports.setLengthRight = function (msg, length) { - return exports.setLength(msg, length, true) -} - -/** - * Trims leading zeros from a `Buffer` or an `Array` - * @param {Buffer|Array|String} a - * @return {Buffer|Array|String} - */ -exports.unpad = exports.stripZeros = function (a) { - a = exports.stripHexPrefix(a) - let first = a[0] - while (a.length > 0 && first.toString() === '0') { - a = a.slice(1) - first = a[0] - } - return a -} -/** - * Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method. - * @param {*} v the value - */ -exports.toBuffer = function (v) { - if (!Buffer.isBuffer(v)) { - if (Array.isArray(v)) { - v = Buffer.from(v) - } else if (typeof v === 'string') { - if (exports.isHexString(v)) { - v = Buffer.from(exports.padToEven(exports.stripHexPrefix(v)), 'hex') - } else { - v = Buffer.from(v) - } - } else if (typeof v === 'number') { - v = exports.intToBuffer(v) - } else if (v === null || v === undefined) { - v = Buffer.allocUnsafe(0) - } else if (BN.isBN(v)) { - v = v.toArrayLike(Buffer) - } else if (v.toArray) { - // converts a BN to a Buffer - v = Buffer.from(v.toArray()) - } else { - throw new Error('invalid type') - } - } - return v -} - -/** - * Converts a `Buffer` to a `Number` - * @param {Buffer} buf - * @return {Number} - * @throws If the input number exceeds 53 bits. - */ -exports.bufferToInt = function (buf) { - return new BN(exports.toBuffer(buf)).toNumber() -} - -/** - * Converts a `Buffer` into a hex `String` - * @param {Buffer} buf - * @return {String} - */ -exports.bufferToHex = function (buf) { - buf = exports.toBuffer(buf) - return '0x' + buf.toString('hex') -} - -/** - * Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers. - * @param {Buffer} num - * @return {BN} - */ -exports.fromSigned = function (num) { - return new BN(num).fromTwos(256) -} - -/** - * Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers. - * @param {BN} num - * @return {Buffer} - */ -exports.toUnsigned = function (num) { - return Buffer.from(num.toTwos(256).toArray()) -} - -/** - * Creates Keccak hash of the input - * @param {Buffer|Array|String|Number} a the input data - * @param {Number} [bits=256] the Keccak width - * @return {Buffer} - */ -exports.keccak = function (a, bits) { - a = exports.toBuffer(a) - if (!bits) bits = 256 - - return createKeccakHash('keccak' + bits).update(a).digest() -} - -/** - * Creates Keccak-256 hash of the input, alias for keccak(a, 256) - * @param {Buffer|Array|String|Number} a the input data - * @return {Buffer} - */ -exports.keccak256 = function (a) { - return exports.keccak(a) -} - -/** - * Creates SHA256 hash of the input - * @param {Buffer|Array|String|Number} a the input data - * @return {Buffer} - */ -exports.sha256 = function (a) { - a = exports.toBuffer(a) - return createHash('sha256').update(a).digest() -} - -/** - * Creates RIPEMD160 hash of the input - * @param {Buffer|Array|String|Number} a the input data - * @param {Boolean} padded whether it should be padded to 256 bits or not - * @return {Buffer} - */ -exports.ripemd160 = function (a, padded) { - a = exports.toBuffer(a) - const hash = createHash('rmd160').update(a).digest() - if (padded === true) { - return exports.setLength(hash, 32) - } else { - return hash - } -} - -/** - * Creates SHA-3 hash of the RLP encoded version of the input - * @param {Buffer|Array|String|Number} a the input data - * @return {Buffer} - */ -exports.rlphash = function (a) { - return exports.keccak(rlp.encode(a)) -} - -/** - * Checks if the private key satisfies the rules of the curve secp256k1. - * @param {Buffer} privateKey - * @return {Boolean} - */ -exports.isValidPrivate = function (privateKey) { - return secp256k1.privateKeyVerify(privateKey) -} - -/** - * Checks if the public key satisfies the rules of the curve secp256k1 - * and the requirements of Ethereum. - * @param {Buffer} publicKey The two points of an uncompressed key, unless sanitize is enabled - * @param {Boolean} [sanitize=false] Accept public keys in other formats - * @return {Boolean} - */ -exports.isValidPublic = function (publicKey, sanitize) { - if (publicKey.length === 64) { - // Convert to SEC1 for secp256k1 - return secp256k1.publicKeyVerify(Buffer.concat([ Buffer.from([4]), publicKey ])) - } - - if (!sanitize) { - return false - } - - return secp256k1.publicKeyVerify(publicKey) -} - -/** - * Returns the ethereum address of a given public key. - * Accepts "Ethereum public keys" and SEC1 encoded keys. - * @param {Buffer} pubKey The two points of an uncompressed key, unless sanitize is enabled - * @param {Boolean} [sanitize=false] Accept public keys in other formats - * @return {Buffer} - */ -exports.pubToAddress = exports.publicToAddress = function (pubKey, sanitize) { - pubKey = exports.toBuffer(pubKey) - if (sanitize && (pubKey.length !== 64)) { - pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1) - } - assert(pubKey.length === 64) - // Only take the lower 160bits of the hash - return exports.keccak(pubKey).slice(-20) -} - -/** - * Returns the ethereum public key of a given private key - * @param {Buffer} privateKey A private key must be 256 bits wide - * @return {Buffer} - */ -const privateToPublic = exports.privateToPublic = function (privateKey) { - privateKey = exports.toBuffer(privateKey) - // skip the type flag and use the X, Y points - return secp256k1.publicKeyCreate(privateKey, false).slice(1) -} - -/** - * Converts a public key to the Ethereum format. - * @param {Buffer} publicKey - * @return {Buffer} - */ -exports.importPublic = function (publicKey) { - publicKey = exports.toBuffer(publicKey) - if (publicKey.length !== 64) { - publicKey = secp256k1.publicKeyConvert(publicKey, false).slice(1) - } - return publicKey -} - -/** - * ECDSA sign - * @param {Buffer} msgHash - * @param {Buffer} privateKey - * @param {Number} [chainId] - * @return {Object} - */ -exports.ecsign = function (msgHash, privateKey, chainId) { - const sig = secp256k1.sign(msgHash, privateKey) - - const ret = {} - ret.r = sig.signature.slice(0, 32) - ret.s = sig.signature.slice(32, 64) - ret.v = chainId ? sig.recovery + (chainId * 2 + 35) : sig.recovery + 27 - return ret -} - -/** - * Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call. - * The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign` - * call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key - * used to produce the signature. - * @param message - * @returns {Buffer} hash - */ -exports.hashPersonalMessage = function (message) { - const prefix = exports.toBuffer('\u0019Ethereum Signed Message:\n' + message.length.toString()) - return exports.keccak(Buffer.concat([prefix, message])) -} - -/** - * ECDSA public key recovery from signature - * @param {Buffer} msgHash - * @param {Number} v - * @param {Buffer} r - * @param {Buffer} s - * @param {Number} [chainId] - * @return {Buffer} publicKey - */ -exports.ecrecover = function (msgHash, v, r, s, chainId) { - const signature = Buffer.concat([exports.setLength(r, 32), exports.setLength(s, 32)], 64) - const recovery = calculateSigRecovery(v, chainId) - if (!isValidSigRecovery(recovery)) { - throw new Error('Invalid signature v value') - } - const senderPubKey = secp256k1.recover(msgHash, signature, recovery) - return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) -} - -/** - * Convert signature parameters into the format of `eth_sign` RPC method - * @param {Number} v - * @param {Buffer} r - * @param {Buffer} s - * @param {Number} [chainId] - * @return {String} sig - */ -exports.toRpcSig = function (v, r, s, chainId) { - let recovery = calculateSigRecovery(v, chainId) - if (!isValidSigRecovery(recovery)) { - throw new Error('Invalid signature v value') - } - - // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin - return exports.bufferToHex(Buffer.concat([ - exports.setLengthLeft(r, 32), - exports.setLengthLeft(s, 32), - exports.toBuffer(v) - ])) -} - -/** - * Convert signature format of the `eth_sign` RPC method to signature parameters - * NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053 - * @param {String} sig - * @return {Object} - */ -exports.fromRpcSig = function (sig) { - sig = exports.toBuffer(sig) - - // NOTE: with potential introduction of chainId this might need to be updated - if (sig.length !== 65) { - throw new Error('Invalid signature length') - } - - let v = sig[64] - // support both versions of `eth_sign` responses - if (v < 27) { - v += 27 - } - - return { - v: v, - r: sig.slice(0, 32), - s: sig.slice(32, 64) - } -} - -/** - * Returns the ethereum address of a given private key - * @param {Buffer} privateKey A private key must be 256 bits wide - * @return {Buffer} - */ -exports.privateToAddress = function (privateKey) { - return exports.publicToAddress(privateToPublic(privateKey)) -} - -/** - * Checks if the address is a valid. Accepts checksummed addresses too - * @param {String} address - * @return {Boolean} - */ -exports.isValidAddress = function (address) { - return /^0x[0-9a-fA-F]{40}$/.test(address) -} - -/** - * Checks if a given address is a zero address - * @method isZeroAddress - * @param {String} address - * @return {Boolean} - */ -exports.isZeroAddress = function (address) { - const zeroAddress = exports.zeroAddress() - return zeroAddress === exports.addHexPrefix(address) -} - -/** - * Returns a checksummed address - * @param {String} address - * @return {String} - */ -exports.toChecksumAddress = function (address) { - address = exports.stripHexPrefix(address).toLowerCase() - const hash = exports.keccak(address).toString('hex') - let ret = '0x' - - for (let i = 0; i < address.length; i++) { - if (parseInt(hash[i], 16) >= 8) { - ret += address[i].toUpperCase() - } else { - ret += address[i] - } - } - - return ret -} - -/** - * Checks if the address is a valid checksummed address - * @param {Buffer} address - * @return {Boolean} - */ -exports.isValidChecksumAddress = function (address) { - return exports.isValidAddress(address) && (exports.toChecksumAddress(address) === address) -} - -/** - * Generates an address of a newly created contract - * @param {Buffer} from the address which is creating this new address - * @param {Buffer} nonce the nonce of the from account - * @return {Buffer} - */ -exports.generateAddress = function (from, nonce) { - from = exports.toBuffer(from) - nonce = new BN(nonce) - - if (nonce.isZero()) { - // in RLP we want to encode null in the case of zero nonce - // read the RLP documentation for an answer if you dare - nonce = null - } else { - nonce = Buffer.from(nonce.toArray()) - } - - // Only take the lower 160bits of the hash - return exports.rlphash([from, nonce]).slice(-20) -} - -/** - * Generates an address for a contract created using CREATE2 - * @param {Buffer} from the address which is creating this new address - * @param {Buffer} salt a salt - * @param {Buffer} initCode the init code of the contract being created - * @return {Buffer} - */ -exports.generateAddress2 = function (from, salt, initCode) { - from = exports.toBuffer(from) - salt = exports.toBuffer(salt) - initCode = exports.toBuffer(initCode) - - assert(from.length === 20) - assert(salt.length === 32) - - let address = exports.keccak256(Buffer.concat([ - Buffer.from('ff', 'hex'), - from, - salt, - exports.keccak256(initCode) - ])) - - return address.slice(-20) -} - -/** - * Returns true if the supplied address belongs to a precompiled account (Byzantium) - * @param {Buffer|String} address - * @return {Boolean} - */ -exports.isPrecompiled = function (address) { - const a = exports.unpad(address) - return a.length === 1 && a[0] >= 1 && a[0] <= 8 -} - -/** - * Adds "0x" to a given `String` if it does not already start with "0x" - * @param {String} str - * @return {String} - */ -exports.addHexPrefix = function (str) { - if (typeof str !== 'string') { - return str - } - - return exports.isHexPrefixed(str) ? str : '0x' + str -} - -/** - * Validate ECDSA signature - * @method isValidSignature - * @param {Number} v - * @param {Buffer} r - * @param {Buffer} s - * @param {Boolean} [homesteadOrLater=true] Indicates whether this is being used on either the homestead hardfork or a later one - * @param {Number} [chainId] - * @return {Boolean} - */ - -exports.isValidSignature = function (v, r, s, homesteadOrLater, chainId) { - homesteadOrLater = homesteadOrLater === undefined ? true : homesteadOrLater - const SECP256K1_N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16) - const SECP256K1_N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16) - - if (r.length !== 32 || s.length !== 32) { - return false - } - - if (!isValidSigRecovery(calculateSigRecovery(v, chainId))) { - return false - } - - r = new BN(r) - s = new BN(s) - - if (r.isZero() || r.gt(SECP256K1_N) || s.isZero() || s.gt(SECP256K1_N)) { - return false - } - - if (homesteadOrLater && (new BN(s).cmp(SECP256K1_N_DIV_2) === 1)) { - return false - } - - return true -} - -/** - * Converts a `Buffer` or `Array` to JSON - * @param {Buffer|Array} ba - * @return {Array|String|null} - */ -exports.baToJSON = function (ba) { - if (Buffer.isBuffer(ba)) { - return '0x' + ba.toString('hex') - } else if (ba instanceof Array) { - const array = [] - for (let i = 0; i < ba.length; i++) { - array.push(exports.baToJSON(ba[i])) - } - return array - } -} - -/** - * Defines properties on a `Object`. It make the assumption that underlying data is binary. - * @param {Object} self the `Object` to define properties on - * @param {Array} fields an array fields to define. Fields can contain: - * * `name` - the name of the properties - * * `length` - the number of bytes the field can have - * * `allowLess` - if the field can be less than the length - * * `allowEmpty` - * @param {*} data data to be validated against the definitions - */ -exports.defineProperties = function (self, fields, data) { - self.raw = [] - self._fields = [] - - // attach the `toJSON` - self.toJSON = function (label) { - if (label) { - const obj = {} - self._fields.forEach((field) => { - obj[field] = '0x' + self[field].toString('hex') - }) - return obj - } - return exports.baToJSON(this.raw) - } - - self.serialize = function serialize () { - return rlp.encode(self.raw) - } - - fields.forEach((field, i) => { - self._fields.push(field.name) - function getter () { - return self.raw[i] - } - function setter (v) { - v = exports.toBuffer(v) - - if (v.toString('hex') === '00' && !field.allowZero) { - v = Buffer.allocUnsafe(0) - } - - if (field.allowLess && field.length) { - v = exports.stripZeros(v) - assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes') - } else if (!(field.allowZero && v.length === 0) && field.length) { - assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length) - } - - self.raw[i] = v - } - - Object.defineProperty(self, field.name, { - enumerable: true, - configurable: true, - get: getter, - set: setter - }) - - if (field.default) { - self[field.name] = field.default - } - - // attach alias - if (field.alias) { - Object.defineProperty(self, field.alias, { - enumerable: false, - configurable: true, - set: setter, - get: getter - }) - } - }) - - // if the constuctor is passed data - if (data) { - if (typeof data === 'string') { - data = Buffer.from(exports.stripHexPrefix(data), 'hex') - } - - if (Buffer.isBuffer(data)) { - data = rlp.decode(data) - } - - if (Array.isArray(data)) { - if (data.length > self._fields.length) { - throw (new Error('wrong number of fields in data')) - } - - // make sure all the items are buffers - data.forEach((d, i) => { - self[self._fields[i]] = exports.toBuffer(d) - }) - } else if (typeof data === 'object') { - const keys = Object.keys(data) - fields.forEach((field) => { - if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] - if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] - }) - } else { - throw new Error('invalid data') - } - } -} - -function calculateSigRecovery (v, chainId) { - return chainId ? v - (2 * chainId + 35) : v - 27 -} - -function isValidSigRecovery (recovery) { - return recovery === 0 || recovery === 1 -} diff --git a/package.json b/package.json index 96b0ecc9..3914b71a 100644 --- a/package.json +++ b/package.json @@ -3,19 +3,26 @@ "version": "6.0.0", "description": "a collection of utility functions for Ethereum", "main": "dist/index.js", + "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { - "coverage": "npm run build:dist && istanbul cover _mocha", + "build": "ethereumjs-config-build", + "prepublishOnly": "npm run test && npm run build", + "coverage": "npm run build && istanbul cover _mocha", "coveralls": "npm run coverage && coveralls ./docs/index.md" + "test:browser": "npm run build && karma start karma.conf.js", + "test:node": "npm run build && istanbul test mocha -- --reporter spec", + "tsc": "ethereumjs-config-tsc", + "tslint": "ethereumjs-config-tslint", + "tslint:fix": "ethereumjs-config-tslint-fix" }, "repository": { "type": "git", @@ -85,13 +92,17 @@ "secp256k1": "^3.0.1" }, "devDependencies": { + "@ethereumjs/config-prettier": "^1.1.0", + "@ethereumjs/config-tsc": "^1.1.0", + "@ethereumjs/config-tslint": "^1.1.0", + "@types/bn.js": "^4.11.3", + "@types/node": "^10.12.18", "babel-cli": "^6.26.0", "babel-preset-env": "^1.6.1", "babelify": "^8.0.0", "browserify": "^14.0.0", "contributor": "^0.1.25", "coveralls": "^3.0.0", - "documentation": "^5.2.0", "istanbul": "^0.4.1", "karma": "^2.0.0", "karma-browserify": "^5.0.0", @@ -101,15 +112,11 @@ "karma-firefox-launcher": "^1.0.0", "karma-mocha": "^1.3.0", "mocha": "^4.0.0", - "standard": "^10.0.0" - }, - "standard": { - "globals": [ - "describe", - "it" - ], - "ignore": [ - "dist/**" - ] + "prettier": "^1.15.3", + "tslint": "^5.12.0", + "typedoc": "^0.14.0", + "typedoc-plugin-markdown": "^1.1.21", + "typescript": "^3.2.2", + "typestrict": "^1.0.2" } } diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 00000000..0f2e5b7a --- /dev/null +++ b/prettier.config.js @@ -0,0 +1 @@ +module.exports = require('@ethereumjs/config-prettier') diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..8c12bb34 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,714 @@ +import BN = require('bn.js') +import rlp = require('rlp') +const createKeccakHash = require('keccak') +const secp256k1 = require('secp256k1') +const assert = require('assert') +const createHash = require('create-hash') +const Buffer = require('safe-buffer').Buffer +const ethjsUtil = require('ethjs-util') +Object.assign(exports, ethjsUtil) + +export interface ECDSASignature { + v: number + r: Buffer + s: Buffer +} + +/** + * The max integer that this VM can handle + */ +export const MAX_INTEGER: BN = new BN( + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + 16, +) + +/** + * 2^256 + */ +export const TWO_POW256: BN = new BN( + '10000000000000000000000000000000000000000000000000000000000000000', + 16, +) + +/** + * Keccak-256 hash of null + */ +export const KECCAK256_NULL_S: string = + 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + +/** + * Keccak-256 hash of null + */ +export const KECCAK256_NULL: Buffer = Buffer.from(KECCAK256_NULL_S, 'hex') + +/** + * Keccak-256 of an RLP of an empty array + */ +export const KECCAK256_RLP_ARRAY_S: string = + '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347' + +/** + * Keccak-256 of an RLP of an empty array + */ +export const KECCAK256_RLP_ARRAY: Buffer = Buffer.from(KECCAK256_RLP_ARRAY_S, 'hex') + +/** + * Keccak-256 hash of the RLP of null + */ +export const KECCAK256_RLP_S: string = + '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421' + +/** + * Keccak-256 hash of the RLP of null + */ +export const KECCAK256_RLP: Buffer = Buffer.from(KECCAK256_RLP_S, 'hex') + +/** + * [`BN`](https://github.com/indutny/bn.js) + */ +export { BN } + +/** + * [`rlp`](https://github.com/ethereumjs/rlp) + */ +export { rlp } + +/** + * [`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/) + */ +export { secp256k1 } + +/** + * Returns a buffer filled with 0s. + * @param bytes the number of bytes the buffer should be + */ +export const zeros = function(bytes: number): Buffer { + return Buffer.allocUnsafe(bytes).fill(0) +} + +/** + * Returns a zero address. + */ +export const zeroAddress = function(): string { + const addressLength = 20 + const addr = zeros(addressLength) + return bufferToHex(addr) +} + +/** + * Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. + * Or it truncates the beginning if it exceeds. + * @param msg the value to pad (Buffer|Array) + * @param length the number of bytes the output should be + * @param right whether to start padding form the left or right + * @return (Buffer|Array) + */ +export const setLengthLeft = function(msg: any, length: number, right: boolean = false) { + const buf = zeros(length) + msg = toBuffer(msg) + if (right) { + if (msg.length < length) { + msg.copy(buf) + return buf + } + return msg.slice(0, length) + } else { + if (msg.length < length) { + msg.copy(buf, length - msg.length) + return buf + } + return msg.slice(-length) + } +} +export const setLength = setLengthLeft + +/** + * Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes. + * Or it truncates the beginning if it exceeds. + * @param msg the value to pad (Buffer|Array) + * @param length the number of bytes the output should be + * @return (Buffer|Array) + */ +export const setLengthRight = function(msg: any, length: number) { + return setLength(msg, length, true) +} + +/** + * Trims leading zeros from a `Buffer` or an `Array`. + * @param a (Buffer|Array|String) + * @return (Buffer|Array|String) + */ +export const unpad = function(a: any) { + a = ethjsUtil.stripHexPrefix(a) + let first = a[0] + while (a.length > 0 && first.toString() === '0') { + a = a.slice(1) + first = a[0] + } + return a +} +export const stripZeros = unpad + +/** + * Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method. + * @param v the value + */ +export const toBuffer = function(v: any): Buffer { + if (!Buffer.isBuffer(v)) { + if (Array.isArray(v)) { + v = Buffer.from(v) + } else if (typeof v === 'string') { + if (exports.isHexString(v)) { + v = Buffer.from(exports.padToEven(exports.stripHexPrefix(v)), 'hex') + } else { + v = Buffer.from(v) + } + } else if (typeof v === 'number') { + v = exports.intToBuffer(v) + } else if (v === null || v === undefined) { + v = Buffer.allocUnsafe(0) + } else if (BN.isBN(v)) { + v = v.toArrayLike(Buffer) + } else if (v.toArray) { + // converts a BN to a Buffer + v = Buffer.from(v.toArray()) + } else { + throw new Error('invalid type') + } + } + return v +} + +/** + * Converts a `Buffer` to a `Number`. + * @param buf `Buffer` object to convert + * @throws If the input number exceeds 53 bits. + */ +export const bufferToInt = function(buf: Buffer): number { + return new BN(toBuffer(buf)).toNumber() +} + +/** + * Converts a `Buffer` into a hex `String`. + * @param buf `Buffer` object to convert + */ +export const bufferToHex = function(buf: Buffer): string { + buf = toBuffer(buf) + return '0x' + buf.toString('hex') +} + +/** + * Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers. + * @param num Signed integer value + */ +export const fromSigned = function(num: Buffer): BN { + return new BN(num).fromTwos(256) +} + +/** + * Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers. + * @param num + */ +export const toUnsigned = function(num: BN): Buffer { + return Buffer.from(num.toTwos(256).toArray()) +} + +/** + * Creates Keccak hash of the input + * @param a The input data (Buffer|Array|String|Number) + * @param bits The Keccak width + */ +export const keccak = function(a: any, bits: number = 256): Buffer { + a = toBuffer(a) + if (!bits) bits = 256 + + return createKeccakHash(`keccak${bits}`) + .update(a) + .digest() +} + +/** + * Creates Keccak-256 hash of the input, alias for keccak(a, 256). + * @param a The input data (Buffer|Array|String|Number) + */ +export const keccak256 = function(a: any): Buffer { + return keccak(a) +} + +/** + * Creates SHA256 hash of the input. + * @param a The input data (Buffer|Array|String|Number) + */ +export const sha256 = function(a: any): Buffer { + a = toBuffer(a) + return createHash('sha256') + .update(a) + .digest() +} + +/** + * Creates RIPEMD160 hash of the input. + * @param a The input data (Buffer|Array|String|Number) + * @param padded Whether it should be padded to 256 bits or not + */ +export const ripemd160 = function(a: any, padded: boolean): Buffer { + a = toBuffer(a) + const hash = createHash('rmd160') + .update(a) + .digest() + if (padded === true) { + return setLength(hash, 32) + } else { + return hash + } +} + +/** + * Creates SHA-3 hash of the RLP encoded version of the input. + * @param a The input data + */ +export const rlphash = function(a: rlp.Input): Buffer { + return keccak(rlp.encode(a)) +} + +/** + * Checks if the private key satisfies the rules of the curve secp256k1. + */ +export const isValidPrivate = function(privateKey: Buffer): boolean { + return secp256k1.privateKeyVerify(privateKey) +} + +/** + * Checks if the public key satisfies the rules of the curve secp256k1 + * and the requirements of Ethereum. + * @param publicKey The two points of an uncompressed key, unless sanitize is enabled + * @param sanitize Accept public keys in other formats + */ +export const isValidPublic = function(publicKey: Buffer, sanitize: boolean = false): boolean { + if (publicKey.length === 64) { + // Convert to SEC1 for secp256k1 + return secp256k1.publicKeyVerify(Buffer.concat([Buffer.from([4]), publicKey])) + } + + if (!sanitize) { + return false + } + + return secp256k1.publicKeyVerify(publicKey) +} + +/** + * Returns the ethereum address of a given public key. + * Accepts "Ethereum public keys" and SEC1 encoded keys. + * @param pubKey The two points of an uncompressed key, unless sanitize is enabled + * @param sanitize Accept public keys in other formats + */ +export const pubToAddress = function(pubKey: Buffer, sanitize: boolean = false): Buffer { + pubKey = toBuffer(pubKey) + if (sanitize && pubKey.length !== 64) { + pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1) + } + assert(pubKey.length === 64) + // Only take the lower 160bits of the hash + return keccak(pubKey).slice(-20) +} +export const publicToAddress = pubToAddress + +/** + * Returns the ethereum public key of a given private key. + * @param privateKey A private key must be 256 bits wide + */ +export const privateToPublic = function(privateKey: Buffer): Buffer { + privateKey = toBuffer(privateKey) + // skip the type flag and use the X, Y points + return secp256k1.publicKeyCreate(privateKey, false).slice(1) +} + +/** + * Converts a public key to the Ethereum format. + */ +export const importPublic = function(publicKey: Buffer): Buffer { + publicKey = toBuffer(publicKey) + if (publicKey.length !== 64) { + publicKey = secp256k1.publicKeyConvert(publicKey, false).slice(1) + } + return publicKey +} + +/** + * Returns the ECDSA signature of a message hash. + */ +export const ecsign = function( + msgHash: Buffer, + privateKey: Buffer, + chainId?: number, +): ECDSASignature { + const sig = secp256k1.sign(msgHash, privateKey) + const recovery: number = sig.recovery + + const ret = { + r: sig.signature.slice(0, 32), + s: sig.signature.slice(32, 64), + v: chainId ? recovery + (chainId * 2 + 35) : recovery + 27, + } + + return ret +} + +/** + * Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call. + * The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign` + * call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key + * used to produce the signature. + */ +export const hashPersonalMessage = function(message: any): Buffer { + const prefix = toBuffer(`\u0019Ethereum Signed Message:\n${message.length.toString()}`) + return keccak(Buffer.concat([prefix, message])) +} + +/** + * ECDSA public key recovery from signature. + * @returns Recovered public key + */ +export const ecrecover = function( + msgHash: Buffer, + v: number, + r: Buffer, + s: Buffer, + chainId?: number, +): Buffer { + const signature = Buffer.concat([setLength(r, 32), setLength(s, 32)], 64) + const recovery = calculateSigRecovery(v, chainId) + if (!isValidSigRecovery(recovery)) { + throw new Error('Invalid signature v value') + } + const senderPubKey = secp256k1.recover(msgHash, signature, recovery) + return secp256k1.publicKeyConvert(senderPubKey, false).slice(1) +} + +/** + * Convert signature parameters into the format of `eth_sign` RPC method. + * @returns Signature + */ +export const toRpcSig = function(v: number, r: Buffer, s: Buffer, chainId?: number): string { + const recovery = calculateSigRecovery(v, chainId) + if (!isValidSigRecovery(recovery)) { + throw new Error('Invalid signature v value') + } + + // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin + return bufferToHex(Buffer.concat([setLengthLeft(r, 32), setLengthLeft(s, 32), toBuffer(v)])) +} + +/** + * Convert signature format of the `eth_sign` RPC method to signature parameters + * NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053 + */ +export const fromRpcSig = function(sig: string): ECDSASignature { + const buf: Buffer = toBuffer(sig) + + // NOTE: with potential introduction of chainId this might need to be updated + if (buf.length !== 65) { + throw new Error('Invalid signature length') + } + + let v = buf[64] + // support both versions of `eth_sign` responses + if (v < 27) { + v += 27 + } + + return { + v: v, + r: buf.slice(0, 32), + s: buf.slice(32, 64), + } +} + +/** + * Returns the ethereum address of a given private key. + * @param privateKey A private key must be 256 bits wide + */ +export const privateToAddress = function(privateKey: Buffer): Buffer { + return publicToAddress(privateToPublic(privateKey)) +} + +/** + * Checks if the address is a valid. Accepts checksummed addresses too. + */ +export const isValidAddress = function(address: string): boolean { + return /^0x[0-9a-fA-F]{40}$/.test(address) +} + +/** + * Checks if a given address is a zero address. + */ +export const isZeroAddress = function(address: string): boolean { + const zeroAddr = zeroAddress() + return zeroAddr === addHexPrefix(address) +} + +/** + * Returns a checksummed address. + */ +export const toChecksumAddress = function(address: string): string { + address = ethjsUtil.stripHexPrefix(address).toLowerCase() + const hash = keccak(address).toString('hex') + let ret = '0x' + + for (let i = 0; i < address.length; i++) { + if (parseInt(hash[i], 16) >= 8) { + ret += address[i].toUpperCase() + } else { + ret += address[i] + } + } + + return ret +} + +/** + * Checks if the address is a valid checksummed address. + */ +export const isValidChecksumAddress = function(address: string): boolean { + return isValidAddress(address) && toChecksumAddress(address) === address +} + +/** + * Generates an address of a newly created contract. + * @param from The address which is creating this new address + * @param nonce The nonce of the from account + */ +export const generateAddress = function(from: Buffer, nonce: Buffer): Buffer { + from = toBuffer(from) + const nonceBN = new BN(nonce) + + if (nonceBN.isZero()) { + // in RLP we want to encode null in the case of zero nonce + // read the RLP documentation for an answer if you dare + return rlphash([from, null]).slice(-20) + } + + // Only take the lower 160bits of the hash + return rlphash([from, Buffer.from(nonceBN.toArray())]).slice(-20) +} + +/** + * Generates an address for a contract created using CREATE2. + * @param from The address which is creating this new address + * @param salt A salt + * @param initCode The init code of the contract being created + */ +export const generateAddress2 = function( + from: Buffer | string, + salt: Buffer | string, + initCode: Buffer | string, +): Buffer { + const fromBuf = toBuffer(from) + const saltBuf = toBuffer(salt) + const initCodeBuf = toBuffer(initCode) + + assert(fromBuf.length === 20) + assert(saltBuf.length === 32) + + const address = keccak256( + Buffer.concat([Buffer.from('ff', 'hex'), fromBuf, saltBuf, keccak256(initCodeBuf)]), + ) + + return address.slice(-20) +} + +/** + * Returns true if the supplied address belongs to a precompiled account (Byzantium). + */ +export const isPrecompiled = function(address: Buffer | string): boolean { + const a = unpad(address) + return a.length === 1 && a[0] >= 1 && a[0] <= 8 +} + +/** + * Adds "0x" to a given `String` if it does not already start with "0x". + */ +export const addHexPrefix = function(str: string): string { + if (typeof str !== 'string') { + return str + } + + return ethjsUtil.isHexPrefixed(str) ? str : '0x' + str +} + +/** + * Validate a ECDSA signature. + * @param homesteadOrLater Indicates whether this is being used on either the homestead hardfork or a later one + */ +export const isValidSignature = function( + v: number, + r: Buffer, + s: Buffer, + homesteadOrLater: boolean = true, + chainId?: number, +): boolean { + const SECP256K1_N_DIV_2 = new BN( + '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', + 16, + ) + const SECP256K1_N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16) + + if (r.length !== 32 || s.length !== 32) { + return false + } + + if (!isValidSigRecovery(calculateSigRecovery(v, chainId))) { + return false + } + + const rBN: BN = new BN(r) + const sBN: BN = new BN(s) + + if (rBN.isZero() || rBN.gt(SECP256K1_N) || sBN.isZero() || sBN.gt(SECP256K1_N)) { + return false + } + + if (homesteadOrLater && sBN.cmp(SECP256K1_N_DIV_2) === 1) { + return false + } + + return true +} + +/** + * Converts a `Buffer` or `Array` to JSON. + * @param ba (Buffer|Array) + * @return (Array|String|null) + */ +export const baToJSON = function(ba: any) { + if (Buffer.isBuffer(ba)) { + return `0x${ba.toString('hex')}` + } else if (ba instanceof Array) { + const array = [] + for (let i = 0; i < ba.length; i++) { + array.push(exports.baToJSON(ba[i])) + } + return array + } +} + +/** + * Defines properties on a `Object`. It make the assumption that underlying data is binary. + * @param self the `Object` to define properties on + * @param fields an array fields to define. Fields can contain: + * * `name` - the name of the properties + * * `length` - the number of bytes the field can have + * * `allowLess` - if the field can be less than the length + * * `allowEmpty` + * @param data data to be validated against the definitions + */ +export const defineProperties = function(self: any, fields: any, data: any) { + self.raw = [] + self._fields = [] + + // attach the `toJSON` + self.toJSON = function(label: boolean = false) { + if (label) { + type Dict = { [key: string]: string } + const obj: Dict = {} + self._fields.forEach((field: string) => { + obj[field] = `0x${self[field].toString('hex')}` + }) + return obj + } + return baToJSON(self.raw) + } + + self.serialize = function serialize() { + return rlp.encode(self.raw) + } + + fields.forEach((field: any, i: number) => { + self._fields.push(field.name) + function getter() { + return self.raw[i] + } + function setter(v: any) { + v = toBuffer(v) + + if (v.toString('hex') === '00' && !field.allowZero) { + v = Buffer.allocUnsafe(0) + } + + if (field.allowLess && field.length) { + v = stripZeros(v) + assert( + field.length >= v.length, + `The field ${field.name} must not have more ${field.length} bytes`, + ) + } else if (!(field.allowZero && v.length === 0) && field.length) { + assert( + field.length === v.length, + `The field ${field.name} must have byte length of ${field.length}`, + ) + } + + self.raw[i] = v + } + + Object.defineProperty(self, field.name, { + enumerable: true, + configurable: true, + get: getter, + set: setter, + }) + + if (field.default) { + self[field.name] = field.default + } + + // attach alias + if (field.alias) { + Object.defineProperty(self, field.alias, { + enumerable: false, + configurable: true, + set: setter, + get: getter, + }) + } + }) + + // if the constuctor is passed data + if (data) { + if (typeof data === 'string') { + data = Buffer.from(ethjsUtil.stripHexPrefix(data), 'hex') + } + + if (Buffer.isBuffer(data)) { + data = rlp.decode(data) + } + + if (Array.isArray(data)) { + if (data.length > self._fields.length) { + throw new Error('wrong number of fields in data') + } + + // make sure all the items are buffers + data.forEach((d, i) => { + self[self._fields[i]] = toBuffer(d) + }) + } else if (typeof data === 'object') { + const keys = Object.keys(data) + fields.forEach((field: any) => { + if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name] + if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias] + }) + } else { + throw new Error('invalid data') + } + } +} + +function calculateSigRecovery(v: number, chainId?: number): number { + return chainId ? v - (2 * chainId + 35) : v - 27 +} + +function isValidSigRecovery(recovery: number): boolean { + return recovery === 0 || recovery === 1 +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..ddbd8a97 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@ethereumjs/config-tsc", + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/tsconfig.prod.json b/tsconfig.prod.json new file mode 100644 index 00000000..184d95b5 --- /dev/null +++ b/tsconfig.prod.json @@ -0,0 +1,7 @@ +{ + "extends": "@ethereumjs/config-tsc", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["src/**/*.ts"] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..2ba21c41 --- /dev/null +++ b/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "@ethereumjs/config-tslint" +}