ethereumjs/ethereumjs-util

Most of the string manipulation methods are provided by ethjs-util

更多的字符串处理方法可以看ethjs-util

addHexPrefix

index.js:563-569

Adds "0x" to a given String if it does not already start with "0x"

在没有"0x"前缀的十六进制字符串前面添加前缀

Parameters

  • str String

Returns String

baToJSON

index.js:613-623

Converts a Buffer or Array to JSON

BufferArray转成JSON

Parameters

  • ba (Buffer | Array)

Returns (Array | String | null)

BN

index.js:62-62

BN

Type: Function

大数

bufferToHex

index.js:194-197

Converts a Buffer into a hex String

将 Buffer转成16进制的String

Parameters

  • buf Buffer

Returns String

bufferToInt

index.js:185-187

Converts a Buffer to a Number

Buffer转成Number

Parameters

  • buf Buffer

  • Throws any If the input number exceeds 53 bits.

Returns Number

defineProperties

index.js:635-728

Defines properties on a Object. It make the assumption that underlying data is binary.

定义对象的属性。假设下面的数据都为二进制数

Parameters

  • self Object the Object to define properties on 定义属性的对象
  • fields 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

ECDSA public key recovery from signature

从签名r,s,v和消息hash得到公钥

Parameters

  • msgHash Buffer
  • v Number
  • r Buffer
  • s Buffer
  • chainId Number?

Returns Buffer publicKey

ecsign

index.js:351-359

ECDSA sign签名,返回r,s,v

Parameters

  • msgHash Buffer
  • privateKey Buffer
  • chainId Number根据chainId是否设置来决定v=v+2 * chainId+35(chainId不为0)还是v= v+27(为0或undefined)

Returns Object

fromRpcSig

index.js:421-440

Convert signature format of the eth_sign RPC method to signature parameters

将eth_sign RPC方法的签名格式转换为签名参数,即将65字节的格式转成分开的r,s,v

NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053

即r,v,s签名中的v = v +27

Parameters

  • sig String

Returns Object

toRpcSig

index.js:401-413

Convert signature parameters into the format of eth_sign RPC method

将签名参数转成符合eth_sign RPC方法的格式,即将r,s,v转成65字节的格式

Parameters

  • v Number
  • r Buffer
  • s Buffer
  • chainId Number?

Returns String sig

fromSigned

index.js:204-206

Interprets a Buffer as a signed integer and returns a BN. Assumes 256-bit numbers.

将Buffer转成一个签名整数并返回BN大数对象,假设为一个256位的数字

Parameters

  • num Buffer

Returns BN

generateAddress

index.js:507-521

Generates an address of a newly created contract

为新创建的合约生成一个address(合约即交易,它的address都可以通过合约部署者的账户address及其nonce生成)

Parameters

  • from Buffer the address which is creating this new address合约部署者账户address
  • nonce Buffer the nonce of the from account 账户的nonce(即下一笔交易数)

Returns Buffer

generateAddress2

index.js:530-546

Generates an address for a contract created using CREATE2

使用CREATE2为合约的创建生成一个address

Parameters

  • from Buffer the address which is creating this new address
  • salt Buffer a salt
  • initCode Buffer the init code of the contract being created 合约的encode

Returns Buffer

hashPersonalMessage

index.js:369-372

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.

返回消息的keccak-256散列,以eth_sign RPC调用使用的头作为前缀。可以将此函数的输出输入ecsign,以生成与给定消息的eth_sign调用相同的签名,也可以将该函数的输出与签名一起输入ecrecovery,以恢复用于生成签名的公钥。

Parameters

  • message

Returns Buffer hash

importPublic

index.js:336-342

Converts a public key to the Ethereum format.

将公钥转成以太坊的格式

Parameters

  • publicKey Buffer

Returns Buffer

isPrecompiled

index.js:553-556

Returns true if the supplied address belongs to a precompiled account (Byzantium)

如果提供的地址属于预编译帐户,则返回true

Parameters

  • address (Buffer | String)

Returns Boolean

isValidAddress

index.js:456-458

Checks if the address is a valid. Accepts checksummed addresses too

检查地址是否有效,接受校验和地址

Parameters

  • address String

Returns Boolean

isValidChecksumAddress

index.js:497-499

Checks if the address is a valid checksummed address

查看地址是否是有效的校验和地址

Parameters

  • address Buffer

Returns Boolean

isValidPrivate

index.js:279-281

Checks if the private key satisfies the rules of the curve secp256k1.

查看私钥是否满足曲线secp256k1的规则

Parameters

  • privateKey Buffer

Returns Boolean

isValidPublic

index.js:290-301

Checks if the public key satisfies the rules of the curve secp256k1 and the requirements of Ethereum.

查看公钥是否满足曲线secp256k1的规则和以太坊的需求

Parameters

  • publicKey Buffer The two points of an uncompressed key, unless sanitize is enabled
  • sanitize Boolean Accept public keys in other formats (optional, default false)

Returns Boolean

keccak

index.js:223-228

Creates Keccak hash of the input

生成输入的Keccak hash散列值

Parameters

  • a (Buffer | Array | String | Number) the input data
  • bits Number the Keccak width (optional, default 256)设置返回的hash值的长度

Returns Buffer

keccak256

index.js:235-237

Creates Keccak-256 hash of the input, alias for keccak(a, 256)

生成输入的256比特Keccak hash散列值,返回hash值的长度为256bits.

与keccak(a, 256)等价,因为keccak默认为256,所以keccak256(s)==keccak(s)

Parameters

  • a (Buffer | Array | String | Number) the input data

Returns Buffer

privateToAddress

index.js:447-449

Returns the ethereum address of a given private key

根据私钥得到以太坊地址

Parameters

  • privateKey Buffer A private key must be 256 bits wide

Returns Buffer

pubToAddress

index.js:310-318

Returns the ethereum address of a given public key. Accepts "Ethereum public keys" and SEC1 encoded keys.

根据公钥得到以太坊地址,接受以太坊公钥和SEC1加密密钥

Parameters

  • pubKey Buffer The two points of an uncompressed key, unless sanitize is enabled
  • sanitize Boolean Accept public keys in other formats (optional, default false)

Returns Buffer

ripemd160

index.js:255-263

Creates RIPEMD160 hash of the input

生成输入的RIPEMD160 hash散列值

Parameters

  • a (Buffer | Array | String | Number) the input data
  • padded Boolean whether it should be padded to 256 bits or not设置为true,则当返回的hash值长度不为256时左填充0

Returns Buffer

rlp

index.js:68-68

rlp编码

Type: Function

rlphash

index.js:270-272

Creates SHA-3 hash of the RLP encoded version of the input

生成输入的RLP编码的SHA-3 hash散列值

Parameters

  • a (Buffer | Array | String | Number) the input data

Returns Buffer

secp256k1

index.js:74-74

secp256k1

Type: Object

setLengthRight

index.js:131-133

Right Pads an Array or Buffer with leading zeros till it has length bytes. Or it truncates the beginning if it exceeds.

使用0右填充Array or Buffer直至长度满足length,或是当长度超过的时候进行截断。

⚠️setLengthRight其实就是调用了setLengthLeft(msg, length, true)

Parameters

  • msg (Buffer | Array) the value to pad
  • length Number the number of bytes the output should be

Returns (Buffer | Array)

setLengthLeft

index.js:106-122

Left Pads an Array or Buffer with leading zeros till it has length bytes. Or it truncates the beginning if it exceeds.

使用0左填充Array or Buffer直至长度满足length,或是当长度超过的时候进行截断

Parameters

  • msg (Buffer | Array) the value to pad
  • length Number the number of bytes the output should be
  • right Boolean whether to start padding form the left or right (optional, default false)right = true就相当于右填充

Returns (Buffer | Array)

sha256

index.js:244-247

Creates SHA256 hash of the input

创建输入的SHA256 hash散列值

Parameters

  • a (Buffer | Array | String | Number) the input data

Returns Buffer

toBuffer

index.js:153-177

Attempts to turn a value into a Buffer. As input it supports BufferStringNumber, null/undefined, BN and other objects with a toArray() method.

将值转成Buffer,值输入支持BufferStringNumber, null/undefined, BN和具有toArray()方法的对象

Parameters

  • v any the value

toChecksumAddress

index.js:476-490

Returns a checksummed address

将address转成校验和地址

Parameters

  • address String

Returns String

toUnsigned

index.js:213-215

Converts a BN to an unsigned integer and returns it as a Buffer. Assumes 256-bit numbers.

将BN转成无符号整数并将其返回成Buffer,是256比特的数字

Parameters

  • num BN

Returns Buffer

unpad

index.js:140-148

Trims leading zeros from a Buffer or an Array

BufferArray前面的0删掉

Parameters

  • a (Buffer | Array | String)

Returns (Buffer | Array | String)

isValidSignature

index.js:582-606

Validate ECDSA signature

是否是有效的签名

Parameters

  • v Buffer
  • r Buffer
  • s Buffer
  • homestead Boolean (optional, default true)
  • chainId Number?

Returns Boolean

isZeroAddress

index.js:466-469

Checks if a given address is a zero address

查看给定的address是否是0x0000...000地址

Parameters

  • address String

Returns Boolean

KECCAK256_NULL

index.js:32-32

Keccak-256 hash of null (a Buffer)

Buffer类型的null的Keccak-256 hash散列值

Type: Buffer

KECCAK256_NULL_S

index.js:26-26

Keccak-256 hash of null (a String)

String类型的null的Keccak-256 hash散列值

Type: String

KECCAK256_RLP

index.js:56-56

Keccak-256 hash of the RLP of null (a Buffer)

Buffer类型的RLP编码格式的null的Keccak-256 hash散列值

Type: Buffer

KECCAK256_RLP_S

index.js:50-50

Keccak-256 hash of the RLP of null (a String)

Type: String

String类型的RLP编码格式的null的Keccak-256 hash散列值

KECCAK256_RLP_ARRAY

index.js:44-44

Keccak-256 of an RLP of an empty array (a Buffer)

Buffer类型的RLP编码格式的空数组的Keccak-256 hash散列值

Type: Buffer

KECCAK256_RLP_ARRAY_S

index.js:38-38

Keccak-256 of an RLP of an empty array (a String)

String类型的RLP编码格式的空数组的Keccak-256 hash散列值

Type: String

MAX_INTEGER

index.js:14-14

the max integer that this VM can handle (a BN)

设置虚拟机能够处理的最大整数

Type: BN

privateToPublic

index.js:325-329

Returns the ethereum public key of a given private key

根据私钥得到以太坊的公钥

Parameters

  • privateKey Buffer A private key must be 256 bits wide

Returns Buffer

TWO_POW256

index.js:20-20

2^256 (a BN)

得到2的256次幂的值

Type: BN

zeroAddress

index.js:91-95

Returns a zero address

返回0x000...000地址

Returns String

zeros

index.js:82-84

Returns a buffer filled with 0s

返回布满0的buffer

Parameters

  • bytes Number the number of bytes the buffer should be

Returns Buffer

实现代码:

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 = 20const 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)//将msg的所有数据复制到buf,其实就相当于右填充return buf}return msg.slice(0, length)} else {if (msg.length < length) {msg.copy(buf, length - msg.length)//将msg的所有数据复制到buf,从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 Bufferv = 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 = 256return 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 secp256k1return 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 hashreturn 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 pointsreturn 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 + 27return 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 Bitcoinreturn 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 updatedif (sig.length !== 65) {throw new Error('Invalid signature length')}let v = sig[64]// support both versions of `eth_sign` responsesif (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 darenonce = null} else {nonce = Buffer.from(nonce.toArray())}// Only take the lower 160bits of the hashreturn 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 {Buffer} v* @param {Buffer} r* @param {Buffer} s* @param {Boolean} [homestead=true]* @param {Number} [chainId]* @return {Boolean}*/exports.isValidSignature = function (v, r, s, homestead, chainId) {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 ((homestead === false) && (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 aliasif (field.alias) {Object.defineProperty(self, field.alias, {enumerable: false,configurable: true,set: setter,get: getter})}})// if the constuctor is passed dataif (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 buffersdata.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
}

转载于:https://www.cnblogs.com/wanghui-garcia/p/9924174.html

ethereumjs/ethereumjs-util相关推荐

  1. ethereumjs/ethereumjs-vm-4-tests

    根据代码发现还要了解的模块有: ethereumjs/merkle-patricia-tree -对应数据存储的数据结构 ethereumjs-blockchain -- 区块链 ethereumjs ...

  2. ethereumjs/ethereumjs-vm-2-API文档

    https://github.com/ethereumjs/ethereumjs-vm/blob/master/docs/index.md vm.runBlockchain Processes blo ...

  3. ethereumjs/ethereumjs-icap

    https://github.com/ethereumjs/ethereumjs-icap ethereumjs-icap 安装: npm install ethereumjs-icap --save ...

  4. ethereumjs/ethereumjs-block-2-api

    https://github.com/ethereumjs/ethereumjs-block/blob/master/docs/index.md 详细的调用代码可见本博客的ethereumjs/eth ...

  5. ethereumjs/ethereumjs-common-3-test

    查看test能够让你更好滴了解其API文档的使用 ethereumjs-common/tests/chains.js const tape = require('tape') const Common ...

  6. ethereumjs/ethereumjs-account-2-test

    ethereumjs-account/test/index.js const Account = require('../index.js') const tape = require('tape') ...

  7. Android报错:java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;如何解决

    原因是使用了java标准库里的java.util.Base64这个类,编译时不会报错,但运行时直接崩溃了. 解决方法是用android自带的Base64类替换,直接import android.uti ...

  8. java vector search_java.util.Vector.retainAll()方法实例

    全屏 retainAll(Collection> c)方法用于仅保留此向量包含在指定Collection的元素.换言之,删除这个向量的所有元素未包含在指定Collection. 声明 以下是ja ...

  9. android.util.AndroidRuntimeException: requestFeature() must be called before adding content

    问题 Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding co ...

最新文章

  1. extern “C“
  2. MySQL存储过程使用游标循环数据列表
  3. matlab激光散斑散射半径测量,激光散斑测量2011412225741
  4. 分布式——ACID原则 CAP理论
  5. Java多线程及并发
  6. 《大数据管理概论》一2.5 知识融合技术
  7. 向iGoogle中添加Google日历及其他小工具
  8. 西电计算机网络ppt,《西安电子科技大学》PPT课件
  9. omnigraffle所有模板免费下载网站
  10. ARP协议,ARP攻击的原理,网络执法官的具体实现
  11. php 同比增长率上期未0,同比增长率计算时,上期值为0怎么计算?
  12. linux脚本 加密失效,shell脚本加密(使用shc)
  13. Network--名词解释
  14. SDUT 第十届校赛H menhera酱那惨不忍睹的数学 【二分图 || 网络流】
  15. 女人健身操必知的健康常识
  16. css信号强度显示,纯css实现wifi信号图标及强弱/链接/加密状态
  17. 同济高等数学第三章之经典错误知识点笔记
  18. 十字路口的交通灯控制电路
  19. GBASE 8s中loadunload
  20. php json_encode unicode,phpjson_encode总是返回unicode字符u.问题解决

热门文章

  1. Provisioning Services 7.8 入门系列教程之十四 UEFI支持和BOOTPTAB 编辑器
  2. (CodeForces 548B 暴力) Mike and Fun
  3. VB6 通过winsock控件数组实现客户端和服务器多对一通信
  4. 功能:人脉(People Hub)2-群发短信(创建组)
  5. org.apache.struts2.dispatcher.FilterDispatcher的四个功能
  6. [译] ES6+ 中的 JavaScript 工厂函数(第八部分)
  7. 认知学习法-学习笔记
  8. Microsoft.Data.ConnectionUI.DataConnectionDialog
  9. LM_Sensors on Cent OS 5.4 How To Get And Install The Coretemp Module
  10. vc 6.0常见编译错误及改正方法