ethereumjs/ethereumjs-util
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
将Buffer
或Array转成
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
BufferThrows 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 theObject
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 haveallowLess
- if the field can be less than the lengthallowEmpty
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
Bufferv
Numberr
Buffers
BufferchainId
Number?
Returns Buffer publicKey
ecsign
index.js:351-359
ECDSA sign签名,返回r,s,v
Parameters
msgHash
BufferprivateKey
BufferchainId
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
Numberr
Buffers
BufferchainId
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合约部署者账户addressnonce
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 addresssalt
Buffer a saltinitCode
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 enabledsanitize
Boolean Accept public keys in other formats (optional, defaultfalse
)
Returns Boolean
keccak
index.js:223-228
Creates Keccak hash of the input
生成输入的Keccak hash散列值
Parameters
a
(Buffer | Array | String | Number) the input databits
Number the Keccak width (optional, default256
)设置返回的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 enabledsanitize
Boolean Accept public keys in other formats (optional, defaultfalse
)
Returns Buffer
ripemd160
index.js:255-263
Creates RIPEMD160 hash of the input
生成输入的RIPEMD160 hash散列值
Parameters
a
(Buffer | Array | String | Number) the input datapadded
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 padlength
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 padlength
Number the number of bytes the output should beright
Boolean whether to start padding form the left or right (optional, defaultfalse
)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 Buffer
, String
, Number
, null/undefined, BN
and other objects with a toArray()
method.
将值转成Buffer,值输入支持Buffer
, String
, Number
, 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
将Buffer
或Array前面
的0删掉
Parameters
a
(Buffer | Array | String)
Returns (Buffer | Array | String)
isValidSignature
index.js:582-606
Validate ECDSA signature
是否是有效的签名
Parameters
v
Bufferr
Buffers
Bufferhomestead
Boolean (optional, defaulttrue
)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相关推荐
- ethereumjs/ethereumjs-vm-4-tests
根据代码发现还要了解的模块有: ethereumjs/merkle-patricia-tree -对应数据存储的数据结构 ethereumjs-blockchain -- 区块链 ethereumjs ...
- ethereumjs/ethereumjs-vm-2-API文档
https://github.com/ethereumjs/ethereumjs-vm/blob/master/docs/index.md vm.runBlockchain Processes blo ...
- ethereumjs/ethereumjs-icap
https://github.com/ethereumjs/ethereumjs-icap ethereumjs-icap 安装: npm install ethereumjs-icap --save ...
- ethereumjs/ethereumjs-block-2-api
https://github.com/ethereumjs/ethereumjs-block/blob/master/docs/index.md 详细的调用代码可见本博客的ethereumjs/eth ...
- ethereumjs/ethereumjs-common-3-test
查看test能够让你更好滴了解其API文档的使用 ethereumjs-common/tests/chains.js const tape = require('tape') const Common ...
- ethereumjs/ethereumjs-account-2-test
ethereumjs-account/test/index.js const Account = require('../index.js') const tape = require('tape') ...
- Android报错:java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;如何解决
原因是使用了java标准库里的java.util.Base64这个类,编译时不会报错,但运行时直接崩溃了. 解决方法是用android自带的Base64类替换,直接import android.uti ...
- java vector search_java.util.Vector.retainAll()方法实例
全屏 retainAll(Collection> c)方法用于仅保留此向量包含在指定Collection的元素.换言之,删除这个向量的所有元素未包含在指定Collection. 声明 以下是ja ...
- android.util.AndroidRuntimeException: requestFeature() must be called before adding content
问题 Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding co ...
最新文章
- extern “C“
- MySQL存储过程使用游标循环数据列表
- matlab激光散斑散射半径测量,激光散斑测量2011412225741
- 分布式——ACID原则 CAP理论
- Java多线程及并发
- 《大数据管理概论》一2.5 知识融合技术
- 向iGoogle中添加Google日历及其他小工具
- 西电计算机网络ppt,《西安电子科技大学》PPT课件
- omnigraffle所有模板免费下载网站
- ARP协议,ARP攻击的原理,网络执法官的具体实现
- php 同比增长率上期未0,同比增长率计算时,上期值为0怎么计算?
- linux脚本 加密失效,shell脚本加密(使用shc)
- Network--名词解释
- SDUT 第十届校赛H menhera酱那惨不忍睹的数学 【二分图 || 网络流】
- 女人健身操必知的健康常识
- css信号强度显示,纯css实现wifi信号图标及强弱/链接/加密状态
- 同济高等数学第三章之经典错误知识点笔记
- 十字路口的交通灯控制电路
- GBASE 8s中loadunload
- php json_encode unicode,phpjson_encode总是返回unicode字符u.问题解决
热门文章
- Provisioning Services 7.8 入门系列教程之十四 UEFI支持和BOOTPTAB 编辑器
- (CodeForces 548B 暴力) Mike and Fun
- VB6 通过winsock控件数组实现客户端和服务器多对一通信
- 功能:人脉(People Hub)2-群发短信(创建组)
- org.apache.struts2.dispatcher.FilterDispatcher的四个功能
- [译] ES6+ 中的 JavaScript 工厂函数(第八部分)
- 认知学习法-学习笔记
- Microsoft.Data.ConnectionUI.DataConnectionDialog
- LM_Sensors on Cent OS 5.4 How To Get And Install The Coretemp Module
- vc 6.0常见编译错误及改正方法