aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Coleman <ian@iancoleman.io>2019-09-12 15:29:10 +1000
committerIan Coleman <ian@iancoleman.io>2019-09-12 15:29:10 +1000
commitdedb054fd81ca42aec2ed8caf20ba999ef1c4b44 (patch)
treec5fa4f342def3073c5088471103216e1fd61419b
parent079635cba1587d1b68ebe02bc0a1af38f09d16be (diff)
downloadBIP39-dedb054fd81ca42aec2ed8caf20ba999ef1c4b44.tar.gz
BIP39-dedb054fd81ca42aec2ed8caf20ba999ef1c4b44.tar.zst
BIP39-dedb054fd81ca42aec2ed8caf20ba999ef1c4b44.zip
Add ethereumjs-util to libs directory
-rw-r--r--libs/ethereumjs-util/index.js736
-rw-r--r--libs/ethereumjs-util/package.json125
-rw-r--r--libs/ethereumjs-util/readme.md4
3 files changed, 865 insertions, 0 deletions
diff --git a/libs/ethereumjs-util/index.js b/libs/ethereumjs-util/index.js
new file mode 100644
index 0000000..b17b7ae
--- /dev/null
+++ b/libs/ethereumjs-util/index.js
@@ -0,0 +1,736 @@
1const createKeccakHash = require('keccak')
2const secp256k1 = require('secp256k1')
3const assert = require('assert')
4const rlp = require('rlp')
5const BN = require('bn.js')
6const createHash = require('create-hash')
7const Buffer = require('safe-buffer').Buffer
8Object.assign(exports, require('ethjs-util'))
9
10/**
11 * the max integer that this VM can handle (a ```BN```)
12 * @var {BN} MAX_INTEGER
13 */
14exports.MAX_INTEGER = new BN('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)
15
16/**
17 * 2^256 (a ```BN```)
18 * @var {BN} TWO_POW256
19 */
20exports.TWO_POW256 = new BN('10000000000000000000000000000000000000000000000000000000000000000', 16)
21
22/**
23 * Keccak-256 hash of null (a ```String```)
24 * @var {String} KECCAK256_NULL_S
25 */
26exports.KECCAK256_NULL_S = 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
27
28/**
29 * Keccak-256 hash of null (a ```Buffer```)
30 * @var {Buffer} KECCAK256_NULL
31 */
32exports.KECCAK256_NULL = Buffer.from(exports.KECCAK256_NULL_S, 'hex')
33
34/**
35 * Keccak-256 of an RLP of an empty array (a ```String```)
36 * @var {String} KECCAK256_RLP_ARRAY_S
37 */
38exports.KECCAK256_RLP_ARRAY_S = '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347'
39
40/**
41 * Keccak-256 of an RLP of an empty array (a ```Buffer```)
42 * @var {Buffer} KECCAK256_RLP_ARRAY
43 */
44exports.KECCAK256_RLP_ARRAY = Buffer.from(exports.KECCAK256_RLP_ARRAY_S, 'hex')
45
46/**
47 * Keccak-256 hash of the RLP of null (a ```String```)
48 * @var {String} KECCAK256_RLP_S
49 */
50exports.KECCAK256_RLP_S = '56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
51
52/**
53 * Keccak-256 hash of the RLP of null (a ```Buffer```)
54 * @var {Buffer} KECCAK256_RLP
55 */
56exports.KECCAK256_RLP = Buffer.from(exports.KECCAK256_RLP_S, 'hex')
57
58/**
59 * [`BN`](https://github.com/indutny/bn.js)
60 * @var {Function}
61 */
62exports.BN = BN
63
64/**
65 * [`rlp`](https://github.com/ethereumjs/rlp)
66 * @var {Function}
67 */
68exports.rlp = rlp
69
70/**
71 * [`secp256k1`](https://github.com/cryptocoinjs/secp256k1-node/)
72 * @var {Object}
73 */
74exports.secp256k1 = secp256k1
75
76/**
77 * Returns a buffer filled with 0s
78 * @method zeros
79 * @param {Number} bytes the number of bytes the buffer should be
80 * @return {Buffer}
81 */
82exports.zeros = function (bytes) {
83 return Buffer.allocUnsafe(bytes).fill(0)
84}
85
86/**
87 * Returns a zero address
88 * @method zeroAddress
89 * @return {String}
90 */
91exports.zeroAddress = function () {
92 const addressLength = 20
93 const zeroAddress = exports.zeros(addressLength)
94 return exports.bufferToHex(zeroAddress)
95}
96
97/**
98 * Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
99 * Or it truncates the beginning if it exceeds.
100 * @method lsetLength
101 * @param {Buffer|Array} msg the value to pad
102 * @param {Number} length the number of bytes the output should be
103 * @param {Boolean} [right=false] whether to start padding form the left or right
104 * @return {Buffer|Array}
105 */
106exports.setLengthLeft = exports.setLength = function (msg, length, right) {
107 const buf = exports.zeros(length)
108 msg = exports.toBuffer(msg)
109 if (right) {
110 if (msg.length < length) {
111 msg.copy(buf)
112 return buf
113 }
114 return msg.slice(0, length)
115 } else {
116 if (msg.length < length) {
117 msg.copy(buf, length - msg.length)
118 return buf
119 }
120 return msg.slice(-length)
121 }
122}
123
124/**
125 * Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
126 * Or it truncates the beginning if it exceeds.
127 * @param {Buffer|Array} msg the value to pad
128 * @param {Number} length the number of bytes the output should be
129 * @return {Buffer|Array}
130 */
131exports.setLengthRight = function (msg, length) {
132 return exports.setLength(msg, length, true)
133}
134
135/**
136 * Trims leading zeros from a `Buffer` or an `Array`
137 * @param {Buffer|Array|String} a
138 * @return {Buffer|Array|String}
139 */
140exports.unpad = exports.stripZeros = function (a) {
141 a = exports.stripHexPrefix(a)
142 let first = a[0]
143 while (a.length > 0 && first.toString() === '0') {
144 a = a.slice(1)
145 first = a[0]
146 }
147 return a
148}
149/**
150 * 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.
151 * @param {*} v the value
152 */
153exports.toBuffer = function (v) {
154 if (!Buffer.isBuffer(v)) {
155 if (Array.isArray(v)) {
156 v = Buffer.from(v)
157 } else if (typeof v === 'string') {
158 if (exports.isHexString(v)) {
159 v = Buffer.from(exports.padToEven(exports.stripHexPrefix(v)), 'hex')
160 } else {
161 v = Buffer.from(v)
162 }
163 } else if (typeof v === 'number') {
164 v = exports.intToBuffer(v)
165 } else if (v === null || v === undefined) {
166 v = Buffer.allocUnsafe(0)
167 } else if (BN.isBN(v)) {
168 v = v.toArrayLike(Buffer)
169 } else if (v.toArray) {
170 // converts a BN to a Buffer
171 v = Buffer.from(v.toArray())
172 } else {
173 throw new Error('invalid type')
174 }
175 }
176 return v
177}
178
179/**
180 * Converts a `Buffer` to a `Number`
181 * @param {Buffer} buf
182 * @return {Number}
183 * @throws If the input number exceeds 53 bits.
184 */
185exports.bufferToInt = function (buf) {
186 return new BN(exports.toBuffer(buf)).toNumber()
187}
188
189/**
190 * Converts a `Buffer` into a hex `String`
191 * @param {Buffer} buf
192 * @return {String}
193 */
194exports.bufferToHex = function (buf) {
195 buf = exports.toBuffer(buf)
196 return '0x' + buf.toString('hex')
197}
198
199/**
200 * Interprets a `Buffer` as a signed integer and returns a `BN`. Assumes 256-bit numbers.
201 * @param {Buffer} num
202 * @return {BN}
203 */
204exports.fromSigned = function (num) {
205 return new BN(num).fromTwos(256)
206}
207
208/**
209 * Converts a `BN` to an unsigned integer and returns it as a `Buffer`. Assumes 256-bit numbers.
210 * @param {BN} num
211 * @return {Buffer}
212 */
213exports.toUnsigned = function (num) {
214 return Buffer.from(num.toTwos(256).toArray())
215}
216
217/**
218 * Creates Keccak hash of the input
219 * @param {Buffer|Array|String|Number} a the input data
220 * @param {Number} [bits=256] the Keccak width
221 * @return {Buffer}
222 */
223exports.keccak = function (a, bits) {
224 a = exports.toBuffer(a)
225 if (!bits) bits = 256
226
227 return createKeccakHash('keccak' + bits).update(a).digest()
228}
229
230/**
231 * Creates Keccak-256 hash of the input, alias for keccak(a, 256)
232 * @param {Buffer|Array|String|Number} a the input data
233 * @return {Buffer}
234 */
235exports.keccak256 = function (a) {
236 return exports.keccak(a)
237}
238
239/**
240 * Creates SHA256 hash of the input
241 * @param {Buffer|Array|String|Number} a the input data
242 * @return {Buffer}
243 */
244exports.sha256 = function (a) {
245 a = exports.toBuffer(a)
246 return createHash('sha256').update(a).digest()
247}
248
249/**
250 * Creates RIPEMD160 hash of the input
251 * @param {Buffer|Array|String|Number} a the input data
252 * @param {Boolean} padded whether it should be padded to 256 bits or not
253 * @return {Buffer}
254 */
255exports.ripemd160 = function (a, padded) {
256 a = exports.toBuffer(a)
257 const hash = createHash('rmd160').update(a).digest()
258 if (padded === true) {
259 return exports.setLength(hash, 32)
260 } else {
261 return hash
262 }
263}
264
265/**
266 * Creates SHA-3 hash of the RLP encoded version of the input
267 * @param {Buffer|Array|String|Number} a the input data
268 * @return {Buffer}
269 */
270exports.rlphash = function (a) {
271 return exports.keccak(rlp.encode(a))
272}
273
274/**
275 * Checks if the private key satisfies the rules of the curve secp256k1.
276 * @param {Buffer} privateKey
277 * @return {Boolean}
278 */
279exports.isValidPrivate = function (privateKey) {
280 return secp256k1.privateKeyVerify(privateKey)
281}
282
283/**
284 * Checks if the public key satisfies the rules of the curve secp256k1
285 * and the requirements of Ethereum.
286 * @param {Buffer} publicKey The two points of an uncompressed key, unless sanitize is enabled
287 * @param {Boolean} [sanitize=false] Accept public keys in other formats
288 * @return {Boolean}
289 */
290exports.isValidPublic = function (publicKey, sanitize) {
291 if (publicKey.length === 64) {
292 // Convert to SEC1 for secp256k1
293 return secp256k1.publicKeyVerify(Buffer.concat([ Buffer.from([4]), publicKey ]))
294 }
295
296 if (!sanitize) {
297 return false
298 }
299
300 return secp256k1.publicKeyVerify(publicKey)
301}
302
303/**
304 * Returns the ethereum address of a given public key.
305 * Accepts "Ethereum public keys" and SEC1 encoded keys.
306 * @param {Buffer} pubKey The two points of an uncompressed key, unless sanitize is enabled
307 * @param {Boolean} [sanitize=false] Accept public keys in other formats
308 * @return {Buffer}
309 */
310exports.pubToAddress = exports.publicToAddress = function (pubKey, sanitize) {
311 pubKey = exports.toBuffer(pubKey)
312 if (sanitize && (pubKey.length !== 64)) {
313 pubKey = secp256k1.publicKeyConvert(pubKey, false).slice(1)
314 }
315 assert(pubKey.length === 64)
316 // Only take the lower 160bits of the hash
317 return exports.keccak(pubKey).slice(-20)
318}
319
320/**
321 * Returns the ethereum public key of a given private key
322 * @param {Buffer} privateKey A private key must be 256 bits wide
323 * @return {Buffer}
324 */
325const privateToPublic = exports.privateToPublic = function (privateKey) {
326 privateKey = exports.toBuffer(privateKey)
327 // skip the type flag and use the X, Y points
328 return secp256k1.publicKeyCreate(privateKey, false).slice(1)
329}
330
331/**
332 * Converts a public key to the Ethereum format.
333 * @param {Buffer} publicKey
334 * @return {Buffer}
335 */
336exports.importPublic = function (publicKey) {
337 publicKey = exports.toBuffer(publicKey)
338 if (publicKey.length !== 64) {
339 publicKey = secp256k1.publicKeyConvert(publicKey, false).slice(1)
340 }
341 return publicKey
342}
343
344/**
345 * ECDSA sign
346 * @param {Buffer} msgHash
347 * @param {Buffer} privateKey
348 * @param {Number} [chainId]
349 * @return {Object}
350 */
351exports.ecsign = function (msgHash, privateKey, chainId) {
352 const sig = secp256k1.sign(msgHash, privateKey)
353
354 const ret = {}
355 ret.r = sig.signature.slice(0, 32)
356 ret.s = sig.signature.slice(32, 64)
357 ret.v = chainId ? sig.recovery + (chainId * 2 + 35) : sig.recovery + 27
358 return ret
359}
360
361/**
362 * Returns the keccak-256 hash of `message`, prefixed with the header used by the `eth_sign` RPC call.
363 * The output of this function can be fed into `ecsign` to produce the same signature as the `eth_sign`
364 * call for a given `message`, or fed to `ecrecover` along with a signature to recover the public key
365 * used to produce the signature.
366 * @param message
367 * @returns {Buffer} hash
368 */
369exports.hashPersonalMessage = function (message) {
370 const prefix = exports.toBuffer('\u0019Ethereum Signed Message:\n' + message.length.toString())
371 return exports.keccak(Buffer.concat([prefix, message]))
372}
373
374/**
375 * ECDSA public key recovery from signature
376 * @param {Buffer} msgHash
377 * @param {Number} v
378 * @param {Buffer} r
379 * @param {Buffer} s
380 * @param {Number} [chainId]
381 * @return {Buffer} publicKey
382 */
383exports.ecrecover = function (msgHash, v, r, s, chainId) {
384 const signature = Buffer.concat([exports.setLength(r, 32), exports.setLength(s, 32)], 64)
385 const recovery = calculateSigRecovery(v, chainId)
386 if (!isValidSigRecovery(recovery)) {
387 throw new Error('Invalid signature v value')
388 }
389 const senderPubKey = secp256k1.recover(msgHash, signature, recovery)
390 return secp256k1.publicKeyConvert(senderPubKey, false).slice(1)
391}
392
393/**
394 * Convert signature parameters into the format of `eth_sign` RPC method
395 * @param {Number} v
396 * @param {Buffer} r
397 * @param {Buffer} s
398 * @param {Number} [chainId]
399 * @return {String} sig
400 */
401exports.toRpcSig = function (v, r, s, chainId) {
402 let recovery = calculateSigRecovery(v, chainId)
403 if (!isValidSigRecovery(recovery)) {
404 throw new Error('Invalid signature v value')
405 }
406
407 // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin
408 return exports.bufferToHex(Buffer.concat([
409 exports.setLengthLeft(r, 32),
410 exports.setLengthLeft(s, 32),
411 exports.toBuffer(v)
412 ]))
413}
414
415/**
416 * Convert signature format of the `eth_sign` RPC method to signature parameters
417 * NOTE: all because of a bug in geth: https://github.com/ethereum/go-ethereum/issues/2053
418 * @param {String} sig
419 * @return {Object}
420 */
421exports.fromRpcSig = function (sig) {
422 sig = exports.toBuffer(sig)
423
424 // NOTE: with potential introduction of chainId this might need to be updated
425 if (sig.length !== 65) {
426 throw new Error('Invalid signature length')
427 }
428
429 let v = sig[64]
430 // support both versions of `eth_sign` responses
431 if (v < 27) {
432 v += 27
433 }
434
435 return {
436 v: v,
437 r: sig.slice(0, 32),
438 s: sig.slice(32, 64)
439 }
440}
441
442/**
443 * Returns the ethereum address of a given private key
444 * @param {Buffer} privateKey A private key must be 256 bits wide
445 * @return {Buffer}
446 */
447exports.privateToAddress = function (privateKey) {
448 return exports.publicToAddress(privateToPublic(privateKey))
449}
450
451/**
452 * Checks if the address is a valid. Accepts checksummed addresses too
453 * @param {String} address
454 * @return {Boolean}
455 */
456exports.isValidAddress = function (address) {
457 return /^0x[0-9a-fA-F]{40}$/.test(address)
458}
459
460/**
461 * Checks if a given address is a zero address
462 * @method isZeroAddress
463 * @param {String} address
464 * @return {Boolean}
465 */
466exports.isZeroAddress = function (address) {
467 const zeroAddress = exports.zeroAddress()
468 return zeroAddress === exports.addHexPrefix(address)
469}
470
471/**
472 * Returns a checksummed address
473 * @param {String} address
474 * @return {String}
475 */
476exports.toChecksumAddress = function (address) {
477 address = exports.stripHexPrefix(address).toLowerCase()
478 const hash = exports.keccak(address).toString('hex')
479 let ret = '0x'
480
481 for (let i = 0; i < address.length; i++) {
482 if (parseInt(hash[i], 16) >= 8) {
483 ret += address[i].toUpperCase()
484 } else {
485 ret += address[i]
486 }
487 }
488
489 return ret
490}
491
492/**
493 * Checks if the address is a valid checksummed address
494 * @param {Buffer} address
495 * @return {Boolean}
496 */
497exports.isValidChecksumAddress = function (address) {
498 return exports.isValidAddress(address) && (exports.toChecksumAddress(address) === address)
499}
500
501/**
502 * Generates an address of a newly created contract
503 * @param {Buffer} from the address which is creating this new address
504 * @param {Buffer} nonce the nonce of the from account
505 * @return {Buffer}
506 */
507exports.generateAddress = function (from, nonce) {
508 from = exports.toBuffer(from)
509 nonce = new BN(nonce)
510
511 if (nonce.isZero()) {
512 // in RLP we want to encode null in the case of zero nonce
513 // read the RLP documentation for an answer if you dare
514 nonce = null
515 } else {
516 nonce = Buffer.from(nonce.toArray())
517 }
518
519 // Only take the lower 160bits of the hash
520 return exports.rlphash([from, nonce]).slice(-20)
521}
522
523/**
524 * Generates an address for a contract created using CREATE2
525 * @param {Buffer} from the address which is creating this new address
526 * @param {Buffer} salt a salt
527 * @param {Buffer} initCode the init code of the contract being created
528 * @return {Buffer}
529 */
530exports.generateAddress2 = function (from, salt, initCode) {
531 from = exports.toBuffer(from)
532 salt = exports.toBuffer(salt)
533 initCode = exports.toBuffer(initCode)
534
535 assert(from.length === 20)
536 assert(salt.length === 32)
537
538 let address = exports.keccak256(Buffer.concat([
539 Buffer.from('ff', 'hex'),
540 from,
541 salt,
542 exports.keccak256(initCode)
543 ]))
544
545 return address.slice(-20)
546}
547
548/**
549 * Returns true if the supplied address belongs to a precompiled account (Byzantium)
550 * @param {Buffer|String} address
551 * @return {Boolean}
552 */
553exports.isPrecompiled = function (address) {
554 const a = exports.unpad(address)
555 return a.length === 1 && a[0] >= 1 && a[0] <= 8
556}
557
558/**
559 * Adds "0x" to a given `String` if it does not already start with "0x"
560 * @param {String} str
561 * @return {String}
562 */
563exports.addHexPrefix = function (str) {
564 if (typeof str !== 'string') {
565 return str
566 }
567
568 return exports.isHexPrefixed(str) ? str : '0x' + str
569}
570
571/**
572 * Validate ECDSA signature
573 * @method isValidSignature
574 * @param {Buffer} v
575 * @param {Buffer} r
576 * @param {Buffer} s
577 * @param {Boolean} [homestead=true]
578 * @param {Number} [chainId]
579 * @return {Boolean}
580 */
581
582exports.isValidSignature = function (v, r, s, homestead, chainId) {
583 const SECP256K1_N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16)
584 const SECP256K1_N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16)
585
586 if (r.length !== 32 || s.length !== 32) {
587 return false
588 }
589
590 if (!isValidSigRecovery(calculateSigRecovery(v, chainId))) {
591 return false
592 }
593
594 r = new BN(r)
595 s = new BN(s)
596
597 if (r.isZero() || r.gt(SECP256K1_N) || s.isZero() || s.gt(SECP256K1_N)) {
598 return false
599 }
600
601 if ((homestead === false) && (new BN(s).cmp(SECP256K1_N_DIV_2) === 1)) {
602 return false
603 }
604
605 return true
606}
607
608/**
609 * Converts a `Buffer` or `Array` to JSON
610 * @param {Buffer|Array} ba
611 * @return {Array|String|null}
612 */
613exports.baToJSON = function (ba) {
614 if (Buffer.isBuffer(ba)) {
615 return '0x' + ba.toString('hex')
616 } else if (ba instanceof Array) {
617 const array = []
618 for (let i = 0; i < ba.length; i++) {
619 array.push(exports.baToJSON(ba[i]))
620 }
621 return array
622 }
623}
624
625/**
626 * Defines properties on a `Object`. It make the assumption that underlying data is binary.
627 * @param {Object} self the `Object` to define properties on
628 * @param {Array} fields an array fields to define. Fields can contain:
629 * * `name` - the name of the properties
630 * * `length` - the number of bytes the field can have
631 * * `allowLess` - if the field can be less than the length
632 * * `allowEmpty`
633 * @param {*} data data to be validated against the definitions
634 */
635exports.defineProperties = function (self, fields, data) {
636 self.raw = []
637 self._fields = []
638
639 // attach the `toJSON`
640 self.toJSON = function (label) {
641 if (label) {
642 const obj = {}
643 self._fields.forEach((field) => {
644 obj[field] = '0x' + self[field].toString('hex')
645 })
646 return obj
647 }
648 return exports.baToJSON(this.raw)
649 }
650
651 self.serialize = function serialize () {
652 return rlp.encode(self.raw)
653 }
654
655 fields.forEach((field, i) => {
656 self._fields.push(field.name)
657 function getter () {
658 return self.raw[i]
659 }
660 function setter (v) {
661 v = exports.toBuffer(v)
662
663 if (v.toString('hex') === '00' && !field.allowZero) {
664 v = Buffer.allocUnsafe(0)
665 }
666
667 if (field.allowLess && field.length) {
668 v = exports.stripZeros(v)
669 assert(field.length >= v.length, 'The field ' + field.name + ' must not have more ' + field.length + ' bytes')
670 } else if (!(field.allowZero && v.length === 0) && field.length) {
671 assert(field.length === v.length, 'The field ' + field.name + ' must have byte length of ' + field.length)
672 }
673
674 self.raw[i] = v
675 }
676
677 Object.defineProperty(self, field.name, {
678 enumerable: true,
679 configurable: true,
680 get: getter,
681 set: setter
682 })
683
684 if (field.default) {
685 self[field.name] = field.default
686 }
687
688 // attach alias
689 if (field.alias) {
690 Object.defineProperty(self, field.alias, {
691 enumerable: false,
692 configurable: true,
693 set: setter,
694 get: getter
695 })
696 }
697 })
698
699 // if the constuctor is passed data
700 if (data) {
701 if (typeof data === 'string') {
702 data = Buffer.from(exports.stripHexPrefix(data), 'hex')
703 }
704
705 if (Buffer.isBuffer(data)) {
706 data = rlp.decode(data)
707 }
708
709 if (Array.isArray(data)) {
710 if (data.length > self._fields.length) {
711 throw (new Error('wrong number of fields in data'))
712 }
713
714 // make sure all the items are buffers
715 data.forEach((d, i) => {
716 self[self._fields[i]] = exports.toBuffer(d)
717 })
718 } else if (typeof data === 'object') {
719 const keys = Object.keys(data)
720 fields.forEach((field) => {
721 if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name]
722 if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias]
723 })
724 } else {
725 throw new Error('invalid data')
726 }
727 }
728}
729
730function calculateSigRecovery (v, chainId) {
731 return chainId ? v - (2 * chainId + 35) : v - 27
732}
733
734function isValidSigRecovery (recovery) {
735 return recovery === 0 || recovery === 1
736}
diff --git a/libs/ethereumjs-util/package.json b/libs/ethereumjs-util/package.json
new file mode 100644
index 0000000..a49746f
--- /dev/null
+++ b/libs/ethereumjs-util/package.json
@@ -0,0 +1,125 @@
1{
2 "name": "ethereumjs-util",
3 "version": "6.0.0",
4 "description": "a collection of utility functions for Ethereum",
5 "main": "dist/index.js",
6 "files": [
7 "dist"
8 ],
9 "scripts": {
10 "build": "browserify index.js -s ethUtil -o /tmp/ethereumjs-util.js",
11 "coverage": "npm run build:dist && istanbul cover _mocha",
12 "coveralls": "npm run coverage && coveralls <coverage/lcov.info",
13 "lint": "standard",
14 "prepublishOnly": "npm run test && npm run build:dist",
15 "test": "npm run lint && npm run test:node && npm run test:browser",
16 "test:browser": "npm run build:dist && karma start karma.conf.js",
17 "test:node": "npm run build:dist && istanbul test mocha -- --reporter spec",
18 "build:dist": "babel index.js --source-root ./ -d ./dist",
19 "build:docs": "documentation build ./index.js --github --sort-order='alpha' -f md > ./docs/index.md"
20 },
21 "repository": {
22 "type": "git",
23 "url": "https://github.com/ethereumjs/ethereumjs-util.git"
24 },
25 "keywords": [
26 "ethereum",
27 "utilties"
28 ],
29 "author": "mjbecze <mjbecze@gmail.com>",
30 "contributors": [
31 {
32 "name": "Tim Coulter",
33 "email": "tim@timothyjcoulter.com",
34 "url": "https://github.com/tcoulter",
35 "contributions": 1,
36 "additions": 2,
37 "deletions": 2
38 },
39 {
40 "name": "Nick Dodson",
41 "url": "https://github.com/SilentCicero",
42 "contributions": 2,
43 "additions": 26,
44 "deletions": 2
45 },
46 {
47 "name": "Mr. Chico",
48 "url": "https://github.com/MrChico",
49 "contributions": 1,
50 "additions": 11,
51 "deletions": 1
52 },
53 {
54 "name": "Dũng Trần",
55 "email": "tad88.dev@gmail.com",
56 "url": "https://github.com/tad88dev",
57 "contributions": 2,
58 "additions": 5,
59 "deletions": 5
60 },
61 {
62 "name": "Alex Beregszaszi",
63 "email": "alex@rtfs.hu",
64 "url": "https://github.com/axic",
65 "contributions": 77,
66 "additions": 1796,
67 "deletions": 642
68 },
69 {
70 "name": "Taylor Gerring",
71 "url": "https://github.com/tgerring",
72 "contributions": 1,
73 "additions": 1,
74 "deletions": 1
75 },
76 {
77 "name": "Kirill Fomichev",
78 "email": "fanatid@ya.ru",
79 "url": "https://github.com/fanatid",
80 "contributions": 8,
81 "additions": 32,
82 "deletions": 16
83 },
84 {
85 "name": "kumavis",
86 "email": "aaron@kumavis.me",
87 "url": "https://github.com/kumavis",
88 "contributions": 2,
89 "additions": 2,
90 "deletions": 2
91 },
92 {
93 "name": "Alexander Sinyagin",
94 "email": "sinyagin.alexander@gmail.com",
95 "url": "https://github.com/asinyagin",
96 "contributions": 1,
97 "additions": 3,
98 "deletions": 1
99 }
100 ],
101 "license": "MPL-2.0",
102 "bugs": {
103 "url": "https://github.com/ethereumjs/ethereumjs-util/issues"
104 },
105 "homepage": "https://github.com/ethereumjs/ethereumjs-util",
106 "dependencies": {
107 "bn.js": "^4.11.0",
108 "create-hash": "^1.1.2",
109 "ethjs-util": "^0.1.6",
110 "keccak": "^1.0.2",
111 "rlp": "^2.0.0",
112 "safe-buffer": "^5.1.1",
113 "secp256k1": "^3.0.1"
114 },
115 "devDependencies": {},
116 "standard": {
117 "globals": [
118 "describe",
119 "it"
120 ],
121 "ignore": [
122 "dist/**"
123 ]
124 }
125}
diff --git a/libs/ethereumjs-util/readme.md b/libs/ethereumjs-util/readme.md
new file mode 100644
index 0000000..2cc717a
--- /dev/null
+++ b/libs/ethereumjs-util/readme.md
@@ -0,0 +1,4 @@
1Build (will create a bundle and copy it to /tmp/ethereumjs-util.js):
2
3 npm install
4 npm run build