2018-06-28 02:59:08 +03:00
( function ( f ) { if ( typeof exports === "object" && typeof module !== "undefined" ) { module . exports = f ( ) } else if ( typeof define === "function" && define . amd ) { define ( [ ] , f ) } else { var g ; if ( typeof window !== "undefined" ) { g = window } else if ( typeof global !== "undefined" ) { g = global } else if ( typeof self !== "undefined" ) { g = self } else { g = this } g . ethers = f ( ) } } ) ( function ( ) { var define , module , exports ; return ( function ( ) { function r ( e , n , t ) { function o ( i , f ) { if ( ! n [ i ] ) { if ( ! e [ i ] ) { var c = "function" == typeof require && require ; if ( ! f && c ) return c ( i , ! 0 ) ; if ( u ) return u ( i , ! 0 ) ; var a = new Error ( "Cannot find module '" + i + "'" ) ; throw a . code = "MODULE_NOT_FOUND" , a } var p = n [ i ] = { exports : { } } ; e [ i ] [ 0 ] . call ( p . exports , function ( r ) { var n = e [ i ] [ 1 ] [ r ] ; return o ( n || r ) } , p , p . exports , r , e , n , t ) } return n [ i ] . exports } for ( var u = "function" == typeof require && require , i = 0 ; i < t . length ; i ++ ) o ( t [ i ] ) ; return o } return r } ) ( ) ( { 1 : [ function ( require , module , exports ) {
2017-05-22 03:38:41 +03:00
( function ( module , exports ) {
'use strict' ;
// Utils
function assert ( val , msg ) {
if ( ! val ) throw new Error ( msg || 'Assertion failed' ) ;
}
// Could use `inherits` module, but don't want to move from single file
// architecture yet.
function inherits ( ctor , superCtor ) {
ctor . super _ = superCtor ;
var TempCtor = function ( ) { } ;
TempCtor . prototype = superCtor . prototype ;
ctor . prototype = new TempCtor ( ) ;
ctor . prototype . constructor = ctor ;
}
// BN
function BN ( number , base , endian ) {
if ( BN . isBN ( number ) ) {
return number ;
}
this . negative = 0 ;
this . words = null ;
this . length = 0 ;
// Reduction context
this . red = null ;
if ( number !== null ) {
if ( base === 'le' || base === 'be' ) {
endian = base ;
base = 10 ;
}
this . _init ( number || 0 , base || 10 , endian || 'be' ) ;
}
}
if ( typeof module === 'object' ) {
module . exports = BN ;
} else {
exports . BN = BN ;
}
BN . BN = BN ;
BN . wordSize = 26 ;
var Buffer ;
try {
2017-11-10 03:54:28 +03:00
Buffer = require ( 'buffer' ) . Buffer ;
2017-05-22 03:38:41 +03:00
} catch ( e ) {
}
BN . isBN = function isBN ( num ) {
if ( num instanceof BN ) {
return true ;
}
return num !== null && typeof num === 'object' &&
num . constructor . wordSize === BN . wordSize && Array . isArray ( num . words ) ;
} ;
BN . max = function max ( left , right ) {
if ( left . cmp ( right ) > 0 ) return left ;
return right ;
} ;
BN . min = function min ( left , right ) {
if ( left . cmp ( right ) < 0 ) return left ;
return right ;
} ;
BN . prototype . _init = function init ( number , base , endian ) {
if ( typeof number === 'number' ) {
return this . _initNumber ( number , base , endian ) ;
}
if ( typeof number === 'object' ) {
return this . _initArray ( number , base , endian ) ;
}
if ( base === 'hex' ) {
base = 16 ;
}
assert ( base === ( base | 0 ) && base >= 2 && base <= 36 ) ;
number = number . toString ( ) . replace ( /\s+/g , '' ) ;
var start = 0 ;
if ( number [ 0 ] === '-' ) {
start ++ ;
}
if ( base === 16 ) {
this . _parseHex ( number , start ) ;
} else {
this . _parseBase ( number , base , start ) ;
}
if ( number [ 0 ] === '-' ) {
this . negative = 1 ;
}
this . strip ( ) ;
if ( endian !== 'le' ) return ;
this . _initArray ( this . toArray ( ) , base , endian ) ;
} ;
BN . prototype . _initNumber = function _initNumber ( number , base , endian ) {
if ( number < 0 ) {
this . negative = 1 ;
number = - number ;
}
if ( number < 0x4000000 ) {
this . words = [ number & 0x3ffffff ] ;
this . length = 1 ;
} else if ( number < 0x10000000000000 ) {
this . words = [
number & 0x3ffffff ,
( number / 0x4000000 ) & 0x3ffffff
] ;
this . length = 2 ;
} else {
assert ( number < 0x20000000000000 ) ; // 2 ^ 53 (unsafe)
this . words = [
number & 0x3ffffff ,
( number / 0x4000000 ) & 0x3ffffff ,
1
] ;
this . length = 3 ;
}
if ( endian !== 'le' ) return ;
// Reverse the bytes
this . _initArray ( this . toArray ( ) , base , endian ) ;
} ;
BN . prototype . _initArray = function _initArray ( number , base , endian ) {
// Perhaps a Uint8Array
assert ( typeof number . length === 'number' ) ;
if ( number . length <= 0 ) {
this . words = [ 0 ] ;
this . length = 1 ;
return this ;
}
this . length = Math . ceil ( number . length / 3 ) ;
this . words = new Array ( this . length ) ;
for ( var i = 0 ; i < this . length ; i ++ ) {
this . words [ i ] = 0 ;
}
var j , w ;
var off = 0 ;
if ( endian === 'be' ) {
for ( i = number . length - 1 , j = 0 ; i >= 0 ; i -= 3 ) {
w = number [ i ] | ( number [ i - 1 ] << 8 ) | ( number [ i - 2 ] << 16 ) ;
this . words [ j ] |= ( w << off ) & 0x3ffffff ;
this . words [ j + 1 ] = ( w >>> ( 26 - off ) ) & 0x3ffffff ;
off += 24 ;
if ( off >= 26 ) {
off -= 26 ;
j ++ ;
}
}
} else if ( endian === 'le' ) {
for ( i = 0 , j = 0 ; i < number . length ; i += 3 ) {
w = number [ i ] | ( number [ i + 1 ] << 8 ) | ( number [ i + 2 ] << 16 ) ;
this . words [ j ] |= ( w << off ) & 0x3ffffff ;
this . words [ j + 1 ] = ( w >>> ( 26 - off ) ) & 0x3ffffff ;
off += 24 ;
if ( off >= 26 ) {
off -= 26 ;
j ++ ;
}
}
}
return this . strip ( ) ;
} ;
function parseHex ( str , start , end ) {
var r = 0 ;
var len = Math . min ( str . length , end ) ;
for ( var i = start ; i < len ; i ++ ) {
var c = str . charCodeAt ( i ) - 48 ;
r <<= 4 ;
// 'a' - 'f'
if ( c >= 49 && c <= 54 ) {
r |= c - 49 + 0xa ;
// 'A' - 'F'
} else if ( c >= 17 && c <= 22 ) {
r |= c - 17 + 0xa ;
// '0' - '9'
} else {
r |= c & 0xf ;
}
}
return r ;
}
BN . prototype . _parseHex = function _parseHex ( number , start ) {
// Create possibly bigger array to ensure that it fits the number
this . length = Math . ceil ( ( number . length - start ) / 6 ) ;
this . words = new Array ( this . length ) ;
for ( var i = 0 ; i < this . length ; i ++ ) {
this . words [ i ] = 0 ;
}
var j , w ;
// Scan 24-bit chunks and add them to the number
var off = 0 ;
for ( i = number . length - 6 , j = 0 ; i >= start ; i -= 6 ) {
w = parseHex ( number , i , i + 6 ) ;
this . words [ j ] |= ( w << off ) & 0x3ffffff ;
// NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
this . words [ j + 1 ] |= w >>> ( 26 - off ) & 0x3fffff ;
off += 24 ;
if ( off >= 26 ) {
off -= 26 ;
j ++ ;
}
}
if ( i + 6 !== start ) {
w = parseHex ( number , start , i + 6 ) ;
this . words [ j ] |= ( w << off ) & 0x3ffffff ;
this . words [ j + 1 ] |= w >>> ( 26 - off ) & 0x3fffff ;
}
this . strip ( ) ;
} ;
function parseBase ( str , start , end , mul ) {
var r = 0 ;
var len = Math . min ( str . length , end ) ;
for ( var i = start ; i < len ; i ++ ) {
var c = str . charCodeAt ( i ) - 48 ;
r *= mul ;
// 'a'
if ( c >= 49 ) {
r += c - 49 + 0xa ;
// 'A'
} else if ( c >= 17 ) {
r += c - 17 + 0xa ;
// '0' - '9'
} else {
r += c ;
}
}
return r ;
}
BN . prototype . _parseBase = function _parseBase ( number , base , start ) {
// Initialize as zero
this . words = [ 0 ] ;
this . length = 1 ;
// Find length of limb in base
for ( var limbLen = 0 , limbPow = 1 ; limbPow <= 0x3ffffff ; limbPow *= base ) {
limbLen ++ ;
}
limbLen -- ;
limbPow = ( limbPow / base ) | 0 ;
var total = number . length - start ;
var mod = total % limbLen ;
var end = Math . min ( total , total - mod ) + start ;
var word = 0 ;
for ( var i = start ; i < end ; i += limbLen ) {
word = parseBase ( number , i , i + limbLen , base ) ;
this . imuln ( limbPow ) ;
if ( this . words [ 0 ] + word < 0x4000000 ) {
this . words [ 0 ] += word ;
} else {
this . _iaddn ( word ) ;
}
}
if ( mod !== 0 ) {
var pow = 1 ;
word = parseBase ( number , i , number . length , base ) ;
for ( i = 0 ; i < mod ; i ++ ) {
pow *= base ;
}
this . imuln ( pow ) ;
if ( this . words [ 0 ] + word < 0x4000000 ) {
this . words [ 0 ] += word ;
} else {
this . _iaddn ( word ) ;
}
}
} ;
BN . prototype . copy = function copy ( dest ) {
dest . words = new Array ( this . length ) ;
for ( var i = 0 ; i < this . length ; i ++ ) {
dest . words [ i ] = this . words [ i ] ;
}
dest . length = this . length ;
dest . negative = this . negative ;
dest . red = this . red ;
} ;
BN . prototype . clone = function clone ( ) {
var r = new BN ( null ) ;
this . copy ( r ) ;
return r ;
} ;
BN . prototype . _expand = function _expand ( size ) {
while ( this . length < size ) {
this . words [ this . length ++ ] = 0 ;
}
return this ;
} ;
// Remove leading `0` from `this`
BN . prototype . strip = function strip ( ) {
while ( this . length > 1 && this . words [ this . length - 1 ] === 0 ) {
this . length -- ;
}
return this . _normSign ( ) ;
} ;
BN . prototype . _normSign = function _normSign ( ) {
// -0 = 0
if ( this . length === 1 && this . words [ 0 ] === 0 ) {
this . negative = 0 ;
}
return this ;
} ;
BN . prototype . inspect = function inspect ( ) {
return ( this . red ? '<BN-R: ' : '<BN: ' ) + this . toString ( 16 ) + '>' ;
} ;
/ *
var zeros = [ ] ;
var groupSizes = [ ] ;
var groupBases = [ ] ;
var s = '' ;
var i = - 1 ;
while ( ++ i < BN . wordSize ) {
zeros [ i ] = s ;
s += '0' ;
}
groupSizes [ 0 ] = 0 ;
groupSizes [ 1 ] = 0 ;
groupBases [ 0 ] = 0 ;
groupBases [ 1 ] = 0 ;
var base = 2 - 1 ;
while ( ++ base < 36 + 1 ) {
var groupSize = 0 ;
var groupBase = 1 ;
while ( groupBase < ( 1 << BN . wordSize ) / base ) {
groupBase *= base ;
groupSize += 1 ;
}
groupSizes [ base ] = groupSize ;
groupBases [ base ] = groupBase ;
}
* /
var zeros = [
'' ,
'0' ,
'00' ,
'000' ,
'0000' ,
'00000' ,
'000000' ,
'0000000' ,
'00000000' ,
'000000000' ,
'0000000000' ,
'00000000000' ,
'000000000000' ,
'0000000000000' ,
'00000000000000' ,
'000000000000000' ,
'0000000000000000' ,
'00000000000000000' ,
'000000000000000000' ,
'0000000000000000000' ,
'00000000000000000000' ,
'000000000000000000000' ,
'0000000000000000000000' ,
'00000000000000000000000' ,
'000000000000000000000000' ,
'0000000000000000000000000'
] ;
var groupSizes = [
0 , 0 ,
25 , 16 , 12 , 11 , 10 , 9 , 8 ,
8 , 7 , 7 , 7 , 7 , 6 , 6 ,
6 , 6 , 6 , 6 , 6 , 5 , 5 ,
5 , 5 , 5 , 5 , 5 , 5 , 5 ,
5 , 5 , 5 , 5 , 5 , 5 , 5
] ;
var groupBases = [
0 , 0 ,
33554432 , 43046721 , 16777216 , 48828125 , 60466176 , 40353607 , 16777216 ,
43046721 , 10000000 , 19487171 , 35831808 , 62748517 , 7529536 , 11390625 ,
16777216 , 24137569 , 34012224 , 47045881 , 64000000 , 4084101 , 5153632 ,
6436343 , 7962624 , 9765625 , 11881376 , 14348907 , 17210368 , 20511149 ,
24300000 , 28629151 , 33554432 , 39135393 , 45435424 , 52521875 , 60466176
] ;
BN . prototype . toString = function toString ( base , padding ) {
base = base || 10 ;
padding = padding | 0 || 1 ;
var out ;
if ( base === 16 || base === 'hex' ) {
out = '' ;
var off = 0 ;
var carry = 0 ;
for ( var i = 0 ; i < this . length ; i ++ ) {
var w = this . words [ i ] ;
var word = ( ( ( w << off ) | carry ) & 0xffffff ) . toString ( 16 ) ;
carry = ( w >>> ( 24 - off ) ) & 0xffffff ;
if ( carry !== 0 || i !== this . length - 1 ) {
out = zeros [ 6 - word . length ] + word + out ;
} else {
out = word + out ;
}
off += 2 ;
if ( off >= 26 ) {
off -= 26 ;
i -- ;
}
}
if ( carry !== 0 ) {
out = carry . toString ( 16 ) + out ;
}
while ( out . length % padding !== 0 ) {
out = '0' + out ;
}
if ( this . negative !== 0 ) {
out = '-' + out ;
}
return out ;
}
if ( base === ( base | 0 ) && base >= 2 && base <= 36 ) {
// var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
var groupSize = groupSizes [ base ] ;
// var groupBase = Math.pow(base, groupSize);
var groupBase = groupBases [ base ] ;
out = '' ;
var c = this . clone ( ) ;
c . negative = 0 ;
while ( ! c . isZero ( ) ) {
var r = c . modn ( groupBase ) . toString ( base ) ;
c = c . idivn ( groupBase ) ;
if ( ! c . isZero ( ) ) {
out = zeros [ groupSize - r . length ] + r + out ;
} else {
out = r + out ;
}
}
if ( this . isZero ( ) ) {
out = '0' + out ;
}
while ( out . length % padding !== 0 ) {
out = '0' + out ;
}
if ( this . negative !== 0 ) {
out = '-' + out ;
}
return out ;
}
assert ( false , 'Base should be between 2 and 36' ) ;
} ;
BN . prototype . toNumber = function toNumber ( ) {
var ret = this . words [ 0 ] ;
if ( this . length === 2 ) {
ret += this . words [ 1 ] * 0x4000000 ;
} else if ( this . length === 3 && this . words [ 2 ] === 0x01 ) {
// NOTE: at this stage it is known that the top bit is set
ret += 0x10000000000000 + ( this . words [ 1 ] * 0x4000000 ) ;
} else if ( this . length > 2 ) {
assert ( false , 'Number can only safely store up to 53 bits' ) ;
}
return ( this . negative !== 0 ) ? - ret : ret ;
} ;
BN . prototype . toJSON = function toJSON ( ) {
return this . toString ( 16 ) ;
} ;
BN . prototype . toBuffer = function toBuffer ( endian , length ) {
assert ( typeof Buffer !== 'undefined' ) ;
return this . toArrayLike ( Buffer , endian , length ) ;
} ;
BN . prototype . toArray = function toArray ( endian , length ) {
return this . toArrayLike ( Array , endian , length ) ;
} ;
BN . prototype . toArrayLike = function toArrayLike ( ArrayType , endian , length ) {
var byteLength = this . byteLength ( ) ;
var reqLength = length || Math . max ( 1 , byteLength ) ;
assert ( byteLength <= reqLength , 'byte array longer than desired length' ) ;
assert ( reqLength > 0 , 'Requested array length <= 0' ) ;
this . strip ( ) ;
var littleEndian = endian === 'le' ;
var res = new ArrayType ( reqLength ) ;
var b , i ;
var q = this . clone ( ) ;
if ( ! littleEndian ) {
// Assume big-endian
for ( i = 0 ; i < reqLength - byteLength ; i ++ ) {
res [ i ] = 0 ;
}
for ( i = 0 ; ! q . isZero ( ) ; i ++ ) {
b = q . andln ( 0xff ) ;
q . iushrn ( 8 ) ;
res [ reqLength - i - 1 ] = b ;
}
} else {
for ( i = 0 ; ! q . isZero ( ) ; i ++ ) {
b = q . andln ( 0xff ) ;
q . iushrn ( 8 ) ;
res [ i ] = b ;
}
for ( ; i < reqLength ; i ++ ) {
res [ i ] = 0 ;
}
}
return res ;
} ;
if ( Math . clz32 ) {
BN . prototype . _countBits = function _countBits ( w ) {
return 32 - Math . clz32 ( w ) ;
} ;
} else {
BN . prototype . _countBits = function _countBits ( w ) {
var t = w ;
var r = 0 ;
if ( t >= 0x1000 ) {
r += 13 ;
t >>>= 13 ;
}
if ( t >= 0x40 ) {
r += 7 ;
t >>>= 7 ;
}
if ( t >= 0x8 ) {
r += 4 ;
t >>>= 4 ;
}
if ( t >= 0x02 ) {
r += 2 ;
t >>>= 2 ;
}
return r + t ;
} ;
}
BN . prototype . _zeroBits = function _zeroBits ( w ) {
// Short-cut
if ( w === 0 ) return 26 ;
var t = w ;
var r = 0 ;
if ( ( t & 0x1fff ) === 0 ) {
r += 13 ;
t >>>= 13 ;
}
if ( ( t & 0x7f ) === 0 ) {
r += 7 ;
t >>>= 7 ;
}
if ( ( t & 0xf ) === 0 ) {
r += 4 ;
t >>>= 4 ;
}
if ( ( t & 0x3 ) === 0 ) {
r += 2 ;
t >>>= 2 ;
}
if ( ( t & 0x1 ) === 0 ) {
r ++ ;
}
return r ;
} ;
// Return number of used bits in a BN
BN . prototype . bitLength = function bitLength ( ) {
var w = this . words [ this . length - 1 ] ;
var hi = this . _countBits ( w ) ;
return ( this . length - 1 ) * 26 + hi ;
} ;
function toBitArray ( num ) {
var w = new Array ( num . bitLength ( ) ) ;
for ( var bit = 0 ; bit < w . length ; bit ++ ) {
var off = ( bit / 26 ) | 0 ;
var wbit = bit % 26 ;
w [ bit ] = ( num . words [ off ] & ( 1 << wbit ) ) >>> wbit ;
}
return w ;
}
// Number of trailing zero bits
BN . prototype . zeroBits = function zeroBits ( ) {
if ( this . isZero ( ) ) return 0 ;
var r = 0 ;
for ( var i = 0 ; i < this . length ; i ++ ) {
var b = this . _zeroBits ( this . words [ i ] ) ;
r += b ;
if ( b !== 26 ) break ;
}
return r ;
} ;
BN . prototype . byteLength = function byteLength ( ) {
return Math . ceil ( this . bitLength ( ) / 8 ) ;
} ;
BN . prototype . toTwos = function toTwos ( width ) {
if ( this . negative !== 0 ) {
return this . abs ( ) . inotn ( width ) . iaddn ( 1 ) ;
}
return this . clone ( ) ;
} ;
BN . prototype . fromTwos = function fromTwos ( width ) {
if ( this . testn ( width - 1 ) ) {
return this . notn ( width ) . iaddn ( 1 ) . ineg ( ) ;
}
return this . clone ( ) ;
} ;
BN . prototype . isNeg = function isNeg ( ) {
return this . negative !== 0 ;
} ;
// Return negative clone of `this`
BN . prototype . neg = function neg ( ) {
return this . clone ( ) . ineg ( ) ;
} ;
BN . prototype . ineg = function ineg ( ) {
if ( ! this . isZero ( ) ) {
this . negative ^= 1 ;
}
return this ;
} ;
// Or `num` with `this` in-place
BN . prototype . iuor = function iuor ( num ) {
while ( this . length < num . length ) {
this . words [ this . length ++ ] = 0 ;
}
for ( var i = 0 ; i < num . length ; i ++ ) {
this . words [ i ] = this . words [ i ] | num . words [ i ] ;
}
return this . strip ( ) ;
} ;
BN . prototype . ior = function ior ( num ) {
assert ( ( this . negative | num . negative ) === 0 ) ;
return this . iuor ( num ) ;
} ;
// Or `num` with `this`
BN . prototype . or = function or ( num ) {
if ( this . length > num . length ) return this . clone ( ) . ior ( num ) ;
return num . clone ( ) . ior ( this ) ;
} ;
BN . prototype . uor = function uor ( num ) {
if ( this . length > num . length ) return this . clone ( ) . iuor ( num ) ;
return num . clone ( ) . iuor ( this ) ;
} ;
// And `num` with `this` in-place
BN . prototype . iuand = function iuand ( num ) {
// b = min-length(num, this)
var b ;
if ( this . length > num . length ) {
b = num ;
} else {
b = this ;
}
for ( var i = 0 ; i < b . length ; i ++ ) {
this . words [ i ] = this . words [ i ] & num . words [ i ] ;
}
this . length = b . length ;
return this . strip ( ) ;
} ;
BN . prototype . iand = function iand ( num ) {
assert ( ( this . negative | num . negative ) === 0 ) ;
return this . iuand ( num ) ;
} ;
// And `num` with `this`
BN . prototype . and = function and ( num ) {
if ( this . length > num . length ) return this . clone ( ) . iand ( num ) ;
return num . clone ( ) . iand ( this ) ;
} ;
BN . prototype . uand = function uand ( num ) {
if ( this . length > num . length ) return this . clone ( ) . iuand ( num ) ;
return num . clone ( ) . iuand ( this ) ;
} ;
// Xor `num` with `this` in-place
BN . prototype . iuxor = function iuxor ( num ) {
// a.length > b.length
var a ;
var b ;
if ( this . length > num . length ) {
a = this ;
b = num ;
} else {
a = num ;
b = this ;
}
for ( var i = 0 ; i < b . length ; i ++ ) {
this . words [ i ] = a . words [ i ] ^ b . words [ i ] ;
}
if ( this !== a ) {
for ( ; i < a . length ; i ++ ) {
this . words [ i ] = a . words [ i ] ;
}
}
this . length = a . length ;
return this . strip ( ) ;
} ;
BN . prototype . ixor = function ixor ( num ) {
assert ( ( this . negative | num . negative ) === 0 ) ;
return this . iuxor ( num ) ;
} ;
// Xor `num` with `this`
BN . prototype . xor = function xor ( num ) {
if ( this . length > num . length ) return this . clone ( ) . ixor ( num ) ;
return num . clone ( ) . ixor ( this ) ;
} ;
BN . prototype . uxor = function uxor ( num ) {
if ( this . length > num . length ) return this . clone ( ) . iuxor ( num ) ;
return num . clone ( ) . iuxor ( this ) ;
} ;
// Not ``this`` with ``width`` bitwidth
BN . prototype . inotn = function inotn ( width ) {
assert ( typeof width === 'number' && width >= 0 ) ;
var bytesNeeded = Math . ceil ( width / 26 ) | 0 ;
var bitsLeft = width % 26 ;
// Extend the buffer with leading zeroes
this . _expand ( bytesNeeded ) ;
if ( bitsLeft > 0 ) {
bytesNeeded -- ;
}
// Handle complete words
for ( var i = 0 ; i < bytesNeeded ; i ++ ) {
this . words [ i ] = ~ this . words [ i ] & 0x3ffffff ;
}
// Handle the residue
if ( bitsLeft > 0 ) {
this . words [ i ] = ~ this . words [ i ] & ( 0x3ffffff >> ( 26 - bitsLeft ) ) ;
}
// And remove leading zeroes
return this . strip ( ) ;
} ;
BN . prototype . notn = function notn ( width ) {
return this . clone ( ) . inotn ( width ) ;
} ;
// Set `bit` of `this`
BN . prototype . setn = function setn ( bit , val ) {
assert ( typeof bit === 'number' && bit >= 0 ) ;
var off = ( bit / 26 ) | 0 ;
var wbit = bit % 26 ;
this . _expand ( off + 1 ) ;
if ( val ) {
this . words [ off ] = this . words [ off ] | ( 1 << wbit ) ;
} else {
this . words [ off ] = this . words [ off ] & ~ ( 1 << wbit ) ;
}
return this . strip ( ) ;
} ;
// Add `num` to `this` in-place
BN . prototype . iadd = function iadd ( num ) {
var r ;
// negative + positive
if ( this . negative !== 0 && num . negative === 0 ) {
this . negative = 0 ;
r = this . isub ( num ) ;
this . negative ^= 1 ;
return this . _normSign ( ) ;
// positive + negative
} else if ( this . negative === 0 && num . negative !== 0 ) {
num . negative = 0 ;
r = this . isub ( num ) ;
num . negative = 1 ;
return r . _normSign ( ) ;
}
// a.length > b.length
var a , b ;
if ( this . length > num . length ) {
a = this ;
b = num ;
} else {
a = num ;
b = this ;
}
var carry = 0 ;
for ( var i = 0 ; i < b . length ; i ++ ) {
r = ( a . words [ i ] | 0 ) + ( b . words [ i ] | 0 ) + carry ;
this . words [ i ] = r & 0x3ffffff ;
carry = r >>> 26 ;
}
for ( ; carry !== 0 && i < a . length ; i ++ ) {
r = ( a . words [ i ] | 0 ) + carry ;
this . words [ i ] = r & 0x3ffffff ;
carry = r >>> 26 ;
}
this . length = a . length ;
if ( carry !== 0 ) {
this . words [ this . length ] = carry ;
this . length ++ ;
// Copy the rest of the words
} else if ( a !== this ) {
for ( ; i < a . length ; i ++ ) {
this . words [ i ] = a . words [ i ] ;
}
}
return this ;
} ;
// Add `num` to `this`
BN . prototype . add = function add ( num ) {
var res ;
if ( num . negative !== 0 && this . negative === 0 ) {
num . negative = 0 ;
res = this . sub ( num ) ;
num . negative ^= 1 ;
return res ;
} else if ( num . negative === 0 && this . negative !== 0 ) {
this . negative = 0 ;
res = num . sub ( this ) ;
this . negative = 1 ;
return res ;
}
if ( this . length > num . length ) return this . clone ( ) . iadd ( num ) ;
return num . clone ( ) . iadd ( this ) ;
} ;
// Subtract `num` from `this` in-place
BN . prototype . isub = function isub ( num ) {
// this - (-num) = this + num
if ( num . negative !== 0 ) {
num . negative = 0 ;
var r = this . iadd ( num ) ;
num . negative = 1 ;
return r . _normSign ( ) ;
// -this - num = -(this + num)
} else if ( this . negative !== 0 ) {
this . negative = 0 ;
this . iadd ( num ) ;
this . negative = 1 ;
return this . _normSign ( ) ;
}
// At this point both numbers are positive
var cmp = this . cmp ( num ) ;
// Optimization - zeroify
if ( cmp === 0 ) {
this . negative = 0 ;
this . length = 1 ;
this . words [ 0 ] = 0 ;
return this ;
}
// a > b
var a , b ;
if ( cmp > 0 ) {
a = this ;
b = num ;
} else {
a = num ;
b = this ;
}
var carry = 0 ;
for ( var i = 0 ; i < b . length ; i ++ ) {
r = ( a . words [ i ] | 0 ) - ( b . words [ i ] | 0 ) + carry ;
carry = r >> 26 ;
this . words [ i ] = r & 0x3ffffff ;
}
for ( ; carry !== 0 && i < a . length ; i ++ ) {
r = ( a . words [ i ] | 0 ) + carry ;
carry = r >> 26 ;
this . words [ i ] = r & 0x3ffffff ;
}
// Copy rest of the words
if ( carry === 0 && i < a . length && a !== this ) {
for ( ; i < a . length ; i ++ ) {
this . words [ i ] = a . words [ i ] ;
}
}
this . length = Math . max ( this . length , i ) ;
if ( a !== this ) {
this . negative = 1 ;
}
return this . strip ( ) ;
} ;
// Subtract `num` from `this`
BN . prototype . sub = function sub ( num ) {
return this . clone ( ) . isub ( num ) ;
} ;
function smallMulTo ( self , num , out ) {
out . negative = num . negative ^ self . negative ;
var len = ( self . length + num . length ) | 0 ;
out . length = len ;
len = ( len - 1 ) | 0 ;
// Peel one iteration (compiler can't do it, because of code complexity)
var a = self . words [ 0 ] | 0 ;
var b = num . words [ 0 ] | 0 ;
var r = a * b ;
var lo = r & 0x3ffffff ;
var carry = ( r / 0x4000000 ) | 0 ;
out . words [ 0 ] = lo ;
for ( var k = 1 ; k < len ; k ++ ) {
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
// note that ncarry could be >= 0x3ffffff
var ncarry = carry >>> 26 ;
var rword = carry & 0x3ffffff ;
var maxJ = Math . min ( k , num . length - 1 ) ;
for ( var j = Math . max ( 0 , k - self . length + 1 ) ; j <= maxJ ; j ++ ) {
var i = ( k - j ) | 0 ;
a = self . words [ i ] | 0 ;
b = num . words [ j ] | 0 ;
r = a * b + rword ;
ncarry += ( r / 0x4000000 ) | 0 ;
rword = r & 0x3ffffff ;
}
out . words [ k ] = rword | 0 ;
carry = ncarry | 0 ;
}
if ( carry !== 0 ) {
out . words [ k ] = carry | 0 ;
} else {
out . length -- ;
}
return out . strip ( ) ;
}
// TODO(indutny): it may be reasonable to omit it for users who don't need
// to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
// multiplication (like elliptic secp256k1).
var comb10MulTo = function comb10MulTo ( self , num , out ) {
var a = self . words ;
var b = num . words ;
var o = out . words ;
var c = 0 ;
var lo ;
var mid ;
var hi ;
var a0 = a [ 0 ] | 0 ;
var al0 = a0 & 0x1fff ;
var ah0 = a0 >>> 13 ;
var a1 = a [ 1 ] | 0 ;
var al1 = a1 & 0x1fff ;
var ah1 = a1 >>> 13 ;
var a2 = a [ 2 ] | 0 ;
var al2 = a2 & 0x1fff ;
var ah2 = a2 >>> 13 ;
var a3 = a [ 3 ] | 0 ;
var al3 = a3 & 0x1fff ;
var ah3 = a3 >>> 13 ;
var a4 = a [ 4 ] | 0 ;
var al4 = a4 & 0x1fff ;
var ah4 = a4 >>> 13 ;
var a5 = a [ 5 ] | 0 ;
var al5 = a5 & 0x1fff ;
var ah5 = a5 >>> 13 ;
var a6 = a [ 6 ] | 0 ;
var al6 = a6 & 0x1fff ;
var ah6 = a6 >>> 13 ;
var a7 = a [ 7 ] | 0 ;
var al7 = a7 & 0x1fff ;
var ah7 = a7 >>> 13 ;
var a8 = a [ 8 ] | 0 ;
var al8 = a8 & 0x1fff ;
var ah8 = a8 >>> 13 ;
var a9 = a [ 9 ] | 0 ;
var al9 = a9 & 0x1fff ;
var ah9 = a9 >>> 13 ;
var b0 = b [ 0 ] | 0 ;
var bl0 = b0 & 0x1fff ;
var bh0 = b0 >>> 13 ;
var b1 = b [ 1 ] | 0 ;
var bl1 = b1 & 0x1fff ;
var bh1 = b1 >>> 13 ;
var b2 = b [ 2 ] | 0 ;
var bl2 = b2 & 0x1fff ;
var bh2 = b2 >>> 13 ;
var b3 = b [ 3 ] | 0 ;
var bl3 = b3 & 0x1fff ;
var bh3 = b3 >>> 13 ;
var b4 = b [ 4 ] | 0 ;
var bl4 = b4 & 0x1fff ;
var bh4 = b4 >>> 13 ;
var b5 = b [ 5 ] | 0 ;
var bl5 = b5 & 0x1fff ;
var bh5 = b5 >>> 13 ;
var b6 = b [ 6 ] | 0 ;
var bl6 = b6 & 0x1fff ;
var bh6 = b6 >>> 13 ;
var b7 = b [ 7 ] | 0 ;
var bl7 = b7 & 0x1fff ;
var bh7 = b7 >>> 13 ;
var b8 = b [ 8 ] | 0 ;
var bl8 = b8 & 0x1fff ;
var bh8 = b8 >>> 13 ;
var b9 = b [ 9 ] | 0 ;
var bl9 = b9 & 0x1fff ;
var bh9 = b9 >>> 13 ;
out . negative = self . negative ^ num . negative ;
out . length = 19 ;
/* k = 0 */
lo = Math . imul ( al0 , bl0 ) ;
mid = Math . imul ( al0 , bh0 ) ;
mid = ( mid + Math . imul ( ah0 , bl0 ) ) | 0 ;
hi = Math . imul ( ah0 , bh0 ) ;
var w0 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w0 >>> 26 ) ) | 0 ;
w0 &= 0x3ffffff ;
/* k = 1 */
lo = Math . imul ( al1 , bl0 ) ;
mid = Math . imul ( al1 , bh0 ) ;
mid = ( mid + Math . imul ( ah1 , bl0 ) ) | 0 ;
hi = Math . imul ( ah1 , bh0 ) ;
lo = ( lo + Math . imul ( al0 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh1 ) ) | 0 ;
var w1 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w1 >>> 26 ) ) | 0 ;
w1 &= 0x3ffffff ;
/* k = 2 */
lo = Math . imul ( al2 , bl0 ) ;
mid = Math . imul ( al2 , bh0 ) ;
mid = ( mid + Math . imul ( ah2 , bl0 ) ) | 0 ;
hi = Math . imul ( ah2 , bh0 ) ;
lo = ( lo + Math . imul ( al1 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh2 ) ) | 0 ;
var w2 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w2 >>> 26 ) ) | 0 ;
w2 &= 0x3ffffff ;
/* k = 3 */
lo = Math . imul ( al3 , bl0 ) ;
mid = Math . imul ( al3 , bh0 ) ;
mid = ( mid + Math . imul ( ah3 , bl0 ) ) | 0 ;
hi = Math . imul ( ah3 , bh0 ) ;
lo = ( lo + Math . imul ( al2 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh3 ) ) | 0 ;
var w3 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w3 >>> 26 ) ) | 0 ;
w3 &= 0x3ffffff ;
/* k = 4 */
lo = Math . imul ( al4 , bl0 ) ;
mid = Math . imul ( al4 , bh0 ) ;
mid = ( mid + Math . imul ( ah4 , bl0 ) ) | 0 ;
hi = Math . imul ( ah4 , bh0 ) ;
lo = ( lo + Math . imul ( al3 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh4 ) ) | 0 ;
var w4 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w4 >>> 26 ) ) | 0 ;
w4 &= 0x3ffffff ;
/* k = 5 */
lo = Math . imul ( al5 , bl0 ) ;
mid = Math . imul ( al5 , bh0 ) ;
mid = ( mid + Math . imul ( ah5 , bl0 ) ) | 0 ;
hi = Math . imul ( ah5 , bh0 ) ;
lo = ( lo + Math . imul ( al4 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh5 ) ) | 0 ;
var w5 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w5 >>> 26 ) ) | 0 ;
w5 &= 0x3ffffff ;
/* k = 6 */
lo = Math . imul ( al6 , bl0 ) ;
mid = Math . imul ( al6 , bh0 ) ;
mid = ( mid + Math . imul ( ah6 , bl0 ) ) | 0 ;
hi = Math . imul ( ah6 , bh0 ) ;
lo = ( lo + Math . imul ( al5 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh6 ) ) | 0 ;
var w6 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w6 >>> 26 ) ) | 0 ;
w6 &= 0x3ffffff ;
/* k = 7 */
lo = Math . imul ( al7 , bl0 ) ;
mid = Math . imul ( al7 , bh0 ) ;
mid = ( mid + Math . imul ( ah7 , bl0 ) ) | 0 ;
hi = Math . imul ( ah7 , bh0 ) ;
lo = ( lo + Math . imul ( al6 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh7 ) ) | 0 ;
var w7 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w7 >>> 26 ) ) | 0 ;
w7 &= 0x3ffffff ;
/* k = 8 */
lo = Math . imul ( al8 , bl0 ) ;
mid = Math . imul ( al8 , bh0 ) ;
mid = ( mid + Math . imul ( ah8 , bl0 ) ) | 0 ;
hi = Math . imul ( ah8 , bh0 ) ;
lo = ( lo + Math . imul ( al7 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh8 ) ) | 0 ;
var w8 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w8 >>> 26 ) ) | 0 ;
w8 &= 0x3ffffff ;
/* k = 9 */
lo = Math . imul ( al9 , bl0 ) ;
mid = Math . imul ( al9 , bh0 ) ;
mid = ( mid + Math . imul ( ah9 , bl0 ) ) | 0 ;
hi = Math . imul ( ah9 , bh0 ) ;
lo = ( lo + Math . imul ( al8 , bl1 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh1 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl1 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh1 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al0 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al0 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah0 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah0 , bh9 ) ) | 0 ;
var w9 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w9 >>> 26 ) ) | 0 ;
w9 &= 0x3ffffff ;
/* k = 10 */
lo = Math . imul ( al9 , bl1 ) ;
mid = Math . imul ( al9 , bh1 ) ;
mid = ( mid + Math . imul ( ah9 , bl1 ) ) | 0 ;
hi = Math . imul ( ah9 , bh1 ) ;
lo = ( lo + Math . imul ( al8 , bl2 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh2 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl2 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh2 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al1 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al1 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah1 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah1 , bh9 ) ) | 0 ;
var w10 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w10 >>> 26 ) ) | 0 ;
w10 &= 0x3ffffff ;
/* k = 11 */
lo = Math . imul ( al9 , bl2 ) ;
mid = Math . imul ( al9 , bh2 ) ;
mid = ( mid + Math . imul ( ah9 , bl2 ) ) | 0 ;
hi = Math . imul ( ah9 , bh2 ) ;
lo = ( lo + Math . imul ( al8 , bl3 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh3 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl3 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh3 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al2 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al2 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah2 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah2 , bh9 ) ) | 0 ;
var w11 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w11 >>> 26 ) ) | 0 ;
w11 &= 0x3ffffff ;
/* k = 12 */
lo = Math . imul ( al9 , bl3 ) ;
mid = Math . imul ( al9 , bh3 ) ;
mid = ( mid + Math . imul ( ah9 , bl3 ) ) | 0 ;
hi = Math . imul ( ah9 , bh3 ) ;
lo = ( lo + Math . imul ( al8 , bl4 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh4 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl4 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh4 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al3 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al3 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah3 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah3 , bh9 ) ) | 0 ;
var w12 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w12 >>> 26 ) ) | 0 ;
w12 &= 0x3ffffff ;
/* k = 13 */
lo = Math . imul ( al9 , bl4 ) ;
mid = Math . imul ( al9 , bh4 ) ;
mid = ( mid + Math . imul ( ah9 , bl4 ) ) | 0 ;
hi = Math . imul ( ah9 , bh4 ) ;
lo = ( lo + Math . imul ( al8 , bl5 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh5 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl5 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh5 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al4 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al4 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah4 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah4 , bh9 ) ) | 0 ;
var w13 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w13 >>> 26 ) ) | 0 ;
w13 &= 0x3ffffff ;
/* k = 14 */
lo = Math . imul ( al9 , bl5 ) ;
mid = Math . imul ( al9 , bh5 ) ;
mid = ( mid + Math . imul ( ah9 , bl5 ) ) | 0 ;
hi = Math . imul ( ah9 , bh5 ) ;
lo = ( lo + Math . imul ( al8 , bl6 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh6 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl6 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh6 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al5 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al5 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah5 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah5 , bh9 ) ) | 0 ;
var w14 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w14 >>> 26 ) ) | 0 ;
w14 &= 0x3ffffff ;
/* k = 15 */
lo = Math . imul ( al9 , bl6 ) ;
mid = Math . imul ( al9 , bh6 ) ;
mid = ( mid + Math . imul ( ah9 , bl6 ) ) | 0 ;
hi = Math . imul ( ah9 , bh6 ) ;
lo = ( lo + Math . imul ( al8 , bl7 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh7 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl7 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh7 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al6 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al6 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah6 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah6 , bh9 ) ) | 0 ;
var w15 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w15 >>> 26 ) ) | 0 ;
w15 &= 0x3ffffff ;
/* k = 16 */
lo = Math . imul ( al9 , bl7 ) ;
mid = Math . imul ( al9 , bh7 ) ;
mid = ( mid + Math . imul ( ah9 , bl7 ) ) | 0 ;
hi = Math . imul ( ah9 , bh7 ) ;
lo = ( lo + Math . imul ( al8 , bl8 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh8 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl8 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh8 ) ) | 0 ;
lo = ( lo + Math . imul ( al7 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al7 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah7 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah7 , bh9 ) ) | 0 ;
var w16 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w16 >>> 26 ) ) | 0 ;
w16 &= 0x3ffffff ;
/* k = 17 */
lo = Math . imul ( al9 , bl8 ) ;
mid = Math . imul ( al9 , bh8 ) ;
mid = ( mid + Math . imul ( ah9 , bl8 ) ) | 0 ;
hi = Math . imul ( ah9 , bh8 ) ;
lo = ( lo + Math . imul ( al8 , bl9 ) ) | 0 ;
mid = ( mid + Math . imul ( al8 , bh9 ) ) | 0 ;
mid = ( mid + Math . imul ( ah8 , bl9 ) ) | 0 ;
hi = ( hi + Math . imul ( ah8 , bh9 ) ) | 0 ;
var w17 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w17 >>> 26 ) ) | 0 ;
w17 &= 0x3ffffff ;
/* k = 18 */
lo = Math . imul ( al9 , bl9 ) ;
mid = Math . imul ( al9 , bh9 ) ;
mid = ( mid + Math . imul ( ah9 , bl9 ) ) | 0 ;
hi = Math . imul ( ah9 , bh9 ) ;
var w18 = ( ( ( c + lo ) | 0 ) + ( ( mid & 0x1fff ) << 13 ) ) | 0 ;
c = ( ( ( hi + ( mid >>> 13 ) ) | 0 ) + ( w18 >>> 26 ) ) | 0 ;
w18 &= 0x3ffffff ;
o [ 0 ] = w0 ;
o [ 1 ] = w1 ;
o [ 2 ] = w2 ;
o [ 3 ] = w3 ;
o [ 4 ] = w4 ;
o [ 5 ] = w5 ;
o [ 6 ] = w6 ;
o [ 7 ] = w7 ;
o [ 8 ] = w8 ;
o [ 9 ] = w9 ;
o [ 10 ] = w10 ;
o [ 11 ] = w11 ;
o [ 12 ] = w12 ;
o [ 13 ] = w13 ;
o [ 14 ] = w14 ;
o [ 15 ] = w15 ;
o [ 16 ] = w16 ;
o [ 17 ] = w17 ;
o [ 18 ] = w18 ;
if ( c !== 0 ) {
o [ 19 ] = c ;
out . length ++ ;
}
return out ;
} ;
// Polyfill comb
if ( ! Math . imul ) {
comb10MulTo = smallMulTo ;
}
function bigMulTo ( self , num , out ) {
out . negative = num . negative ^ self . negative ;
out . length = self . length + num . length ;
var carry = 0 ;
var hncarry = 0 ;
for ( var k = 0 ; k < out . length - 1 ; k ++ ) {
// Sum all words with the same `i + j = k` and accumulate `ncarry`,
// note that ncarry could be >= 0x3ffffff
var ncarry = hncarry ;
hncarry = 0 ;
var rword = carry & 0x3ffffff ;
var maxJ = Math . min ( k , num . length - 1 ) ;
for ( var j = Math . max ( 0 , k - self . length + 1 ) ; j <= maxJ ; j ++ ) {
var i = k - j ;
var a = self . words [ i ] | 0 ;
var b = num . words [ j ] | 0 ;
var r = a * b ;
var lo = r & 0x3ffffff ;
ncarry = ( ncarry + ( ( r / 0x4000000 ) | 0 ) ) | 0 ;
lo = ( lo + rword ) | 0 ;
rword = lo & 0x3ffffff ;
ncarry = ( ncarry + ( lo >>> 26 ) ) | 0 ;
hncarry += ncarry >>> 26 ;
ncarry &= 0x3ffffff ;
}
out . words [ k ] = rword ;
carry = ncarry ;
ncarry = hncarry ;
}
if ( carry !== 0 ) {
out . words [ k ] = carry ;
} else {
out . length -- ;
}
return out . strip ( ) ;
}
function jumboMulTo ( self , num , out ) {
var fftm = new FFTM ( ) ;
return fftm . mulp ( self , num , out ) ;
}
BN . prototype . mulTo = function mulTo ( num , out ) {
var res ;
var len = this . length + num . length ;
if ( this . length === 10 && num . length === 10 ) {
res = comb10MulTo ( this , num , out ) ;
} else if ( len < 63 ) {
res = smallMulTo ( this , num , out ) ;
} else if ( len < 1024 ) {
res = bigMulTo ( this , num , out ) ;
} else {
res = jumboMulTo ( this , num , out ) ;
}
return res ;
} ;
// Cooley-Tukey algorithm for FFT
// slightly revisited to rely on looping instead of recursion
function FFTM ( x , y ) {
this . x = x ;
this . y = y ;
}
FFTM . prototype . makeRBT = function makeRBT ( N ) {
var t = new Array ( N ) ;
var l = BN . prototype . _countBits ( N ) - 1 ;
for ( var i = 0 ; i < N ; i ++ ) {
t [ i ] = this . revBin ( i , l , N ) ;
}
return t ;
} ;
// Returns binary-reversed representation of `x`
FFTM . prototype . revBin = function revBin ( x , l , N ) {
if ( x === 0 || x === N - 1 ) return x ;
var rb = 0 ;
for ( var i = 0 ; i < l ; i ++ ) {
rb |= ( x & 1 ) << ( l - i - 1 ) ;
x >>= 1 ;
}
return rb ;
} ;
// Performs "tweedling" phase, therefore 'emulating'
// behaviour of the recursive algorithm
FFTM . prototype . permute = function permute ( rbt , rws , iws , rtws , itws , N ) {
for ( var i = 0 ; i < N ; i ++ ) {
rtws [ i ] = rws [ rbt [ i ] ] ;
itws [ i ] = iws [ rbt [ i ] ] ;
}
} ;
FFTM . prototype . transform = function transform ( rws , iws , rtws , itws , N , rbt ) {
this . permute ( rbt , rws , iws , rtws , itws , N ) ;
for ( var s = 1 ; s < N ; s <<= 1 ) {
var l = s << 1 ;
var rtwdf = Math . cos ( 2 * Math . PI / l ) ;
var itwdf = Math . sin ( 2 * Math . PI / l ) ;
for ( var p = 0 ; p < N ; p += l ) {
var rtwdf _ = rtwdf ;
var itwdf _ = itwdf ;
for ( var j = 0 ; j < s ; j ++ ) {
var re = rtws [ p + j ] ;
var ie = itws [ p + j ] ;
var ro = rtws [ p + j + s ] ;
var io = itws [ p + j + s ] ;
var rx = rtwdf _ * ro - itwdf _ * io ;
io = rtwdf _ * io + itwdf _ * ro ;
ro = rx ;
rtws [ p + j ] = re + ro ;
itws [ p + j ] = ie + io ;
rtws [ p + j + s ] = re - ro ;
itws [ p + j + s ] = ie - io ;
/* jshint maxdepth : false */
if ( j !== l ) {
rx = rtwdf * rtwdf _ - itwdf * itwdf _ ;
itwdf _ = rtwdf * itwdf _ + itwdf * rtwdf _ ;
rtwdf _ = rx ;
}
}
}
}
} ;
FFTM . prototype . guessLen13b = function guessLen13b ( n , m ) {
var N = Math . max ( m , n ) | 1 ;
var odd = N & 1 ;
var i = 0 ;
for ( N = N / 2 | 0 ; N ; N = N >>> 1 ) {
i ++ ;
}
return 1 << i + 1 + odd ;
} ;
FFTM . prototype . conjugate = function conjugate ( rws , iws , N ) {
if ( N <= 1 ) return ;
for ( var i = 0 ; i < N / 2 ; i ++ ) {
var t = rws [ i ] ;
rws [ i ] = rws [ N - i - 1 ] ;
rws [ N - i - 1 ] = t ;
t = iws [ i ] ;
iws [ i ] = - iws [ N - i - 1 ] ;
iws [ N - i - 1 ] = - t ;
}
} ;
FFTM . prototype . normalize13b = function normalize13b ( ws , N ) {
var carry = 0 ;
for ( var i = 0 ; i < N / 2 ; i ++ ) {
var w = Math . round ( ws [ 2 * i + 1 ] / N ) * 0x2000 +
Math . round ( ws [ 2 * i ] / N ) +
carry ;
ws [ i ] = w & 0x3ffffff ;
if ( w < 0x4000000 ) {
carry = 0 ;
} else {
carry = w / 0x4000000 | 0 ;
}
}
return ws ;
} ;
FFTM . prototype . convert13b = function convert13b ( ws , len , rws , N ) {
var carry = 0 ;
for ( var i = 0 ; i < len ; i ++ ) {
carry = carry + ( ws [ i ] | 0 ) ;
rws [ 2 * i ] = carry & 0x1fff ; carry = carry >>> 13 ;
rws [ 2 * i + 1 ] = carry & 0x1fff ; carry = carry >>> 13 ;
}
// Pad with zeroes
for ( i = 2 * len ; i < N ; ++ i ) {
rws [ i ] = 0 ;
}
assert ( carry === 0 ) ;
assert ( ( carry & ~ 0x1fff ) === 0 ) ;
} ;
FFTM . prototype . stub = function stub ( N ) {
var ph = new Array ( N ) ;
for ( var i = 0 ; i < N ; i ++ ) {
ph [ i ] = 0 ;
}
return ph ;
} ;
FFTM . prototype . mulp = function mulp ( x , y , out ) {
var N = 2 * this . guessLen13b ( x . length , y . length ) ;
var rbt = this . makeRBT ( N ) ;
var _ = this . stub ( N ) ;
var rws = new Array ( N ) ;
var rwst = new Array ( N ) ;
var iwst = new Array ( N ) ;
var nrws = new Array ( N ) ;
var nrwst = new Array ( N ) ;
var niwst = new Array ( N ) ;
var rmws = out . words ;
rmws . length = N ;
this . convert13b ( x . words , x . length , rws , N ) ;
this . convert13b ( y . words , y . length , nrws , N ) ;
this . transform ( rws , _ , rwst , iwst , N , rbt ) ;
this . transform ( nrws , _ , nrwst , niwst , N , rbt ) ;
for ( var i = 0 ; i < N ; i ++ ) {
var rx = rwst [ i ] * nrwst [ i ] - iwst [ i ] * niwst [ i ] ;
iwst [ i ] = rwst [ i ] * niwst [ i ] + iwst [ i ] * nrwst [ i ] ;
rwst [ i ] = rx ;
}
this . conjugate ( rwst , iwst , N ) ;
this . transform ( rwst , iwst , rmws , _ , N , rbt ) ;
this . conjugate ( rmws , _ , N ) ;
this . normalize13b ( rmws , N ) ;
out . negative = x . negative ^ y . negative ;
out . length = x . length + y . length ;
return out . strip ( ) ;
} ;
// Multiply `this` by `num`
BN . prototype . mul = function mul ( num ) {
var out = new BN ( null ) ;
out . words = new Array ( this . length + num . length ) ;
return this . mulTo ( num , out ) ;
} ;
// Multiply employing FFT
BN . prototype . mulf = function mulf ( num ) {
var out = new BN ( null ) ;
out . words = new Array ( this . length + num . length ) ;
return jumboMulTo ( this , num , out ) ;
} ;
// In-place Multiplication
BN . prototype . imul = function imul ( num ) {
return this . clone ( ) . mulTo ( num , this ) ;
} ;
BN . prototype . imuln = function imuln ( num ) {
assert ( typeof num === 'number' ) ;
assert ( num < 0x4000000 ) ;
// Carry
var carry = 0 ;
for ( var i = 0 ; i < this . length ; i ++ ) {
var w = ( this . words [ i ] | 0 ) * num ;
var lo = ( w & 0x3ffffff ) + ( carry & 0x3ffffff ) ;
carry >>= 26 ;
carry += ( w / 0x4000000 ) | 0 ;
// NOTE: lo is 27bit maximum
carry += lo >>> 26 ;
this . words [ i ] = lo & 0x3ffffff ;
}
if ( carry !== 0 ) {
this . words [ i ] = carry ;
this . length ++ ;
}
return this ;
} ;
BN . prototype . muln = function muln ( num ) {
return this . clone ( ) . imuln ( num ) ;
} ;
// `this` * `this`
BN . prototype . sqr = function sqr ( ) {
return this . mul ( this ) ;
} ;
// `this` * `this` in-place
BN . prototype . isqr = function isqr ( ) {
return this . imul ( this . clone ( ) ) ;
} ;
// Math.pow(`this`, `num`)
BN . prototype . pow = function pow ( num ) {
var w = toBitArray ( num ) ;
if ( w . length === 0 ) return new BN ( 1 ) ;
// Skip leading zeroes
var res = this ;
for ( var i = 0 ; i < w . length ; i ++ , res = res . sqr ( ) ) {
if ( w [ i ] !== 0 ) break ;
}
if ( ++ i < w . length ) {
for ( var q = res . sqr ( ) ; i < w . length ; i ++ , q = q . sqr ( ) ) {
if ( w [ i ] === 0 ) continue ;
res = res . mul ( q ) ;
}
}
return res ;
} ;
// Shift-left in-place
BN . prototype . iushln = function iushln ( bits ) {
assert ( typeof bits === 'number' && bits >= 0 ) ;
var r = bits % 26 ;
var s = ( bits - r ) / 26 ;
var carryMask = ( 0x3ffffff >>> ( 26 - r ) ) << ( 26 - r ) ;
var i ;
if ( r !== 0 ) {
var carry = 0 ;
for ( i = 0 ; i < this . length ; i ++ ) {
var newCarry = this . words [ i ] & carryMask ;
var c = ( ( this . words [ i ] | 0 ) - newCarry ) << r ;
this . words [ i ] = c | carry ;
carry = newCarry >>> ( 26 - r ) ;
}
if ( carry ) {
this . words [ i ] = carry ;
this . length ++ ;
}
}
if ( s !== 0 ) {
for ( i = this . length - 1 ; i >= 0 ; i -- ) {
this . words [ i + s ] = this . words [ i ] ;
}
for ( i = 0 ; i < s ; i ++ ) {
this . words [ i ] = 0 ;
}
this . length += s ;
}
return this . strip ( ) ;
} ;
BN . prototype . ishln = function ishln ( bits ) {
// TODO(indutny): implement me
assert ( this . negative === 0 ) ;
return this . iushln ( bits ) ;
} ;
// Shift-right in-place
// NOTE: `hint` is a lowest bit before trailing zeroes
// NOTE: if `extended` is present - it will be filled with destroyed bits
BN . prototype . iushrn = function iushrn ( bits , hint , extended ) {
assert ( typeof bits === 'number' && bits >= 0 ) ;
var h ;
if ( hint ) {
h = ( hint - ( hint % 26 ) ) / 26 ;
} else {
h = 0 ;
}
var r = bits % 26 ;
var s = Math . min ( ( bits - r ) / 26 , this . length ) ;
var mask = 0x3ffffff ^ ( ( 0x3ffffff >>> r ) << r ) ;
var maskedWords = extended ;
h -= s ;
h = Math . max ( 0 , h ) ;
// Extended mode, copy masked part
if ( maskedWords ) {
for ( var i = 0 ; i < s ; i ++ ) {
maskedWords . words [ i ] = this . words [ i ] ;
}
maskedWords . length = s ;
}
if ( s === 0 ) {
// No-op, we should not move anything at all
} else if ( this . length > s ) {
this . length -= s ;
for ( i = 0 ; i < this . length ; i ++ ) {
this . words [ i ] = this . words [ i + s ] ;
}
} else {
this . words [ 0 ] = 0 ;
this . length = 1 ;
}
var carry = 0 ;
for ( i = this . length - 1 ; i >= 0 && ( carry !== 0 || i >= h ) ; i -- ) {
var word = this . words [ i ] | 0 ;
this . words [ i ] = ( carry << ( 26 - r ) ) | ( word >>> r ) ;
carry = word & mask ;
}
// Push carried bits as a mask
if ( maskedWords && carry !== 0 ) {
maskedWords . words [ maskedWords . length ++ ] = carry ;
}
if ( this . length === 0 ) {
this . words [ 0 ] = 0 ;
this . length = 1 ;
}
return this . strip ( ) ;
} ;
BN . prototype . ishrn = function ishrn ( bits , hint , extended ) {
// TODO(indutny): implement me
assert ( this . negative === 0 ) ;
return this . iushrn ( bits , hint , extended ) ;
} ;
// Shift-left
BN . prototype . shln = function shln ( bits ) {
return this . clone ( ) . ishln ( bits ) ;
} ;
BN . prototype . ushln = function ushln ( bits ) {
return this . clone ( ) . iushln ( bits ) ;
} ;
// Shift-right
BN . prototype . shrn = function shrn ( bits ) {
return this . clone ( ) . ishrn ( bits ) ;
} ;
BN . prototype . ushrn = function ushrn ( bits ) {
return this . clone ( ) . iushrn ( bits ) ;
} ;
// Test if n bit is set
BN . prototype . testn = function testn ( bit ) {
assert ( typeof bit === 'number' && bit >= 0 ) ;
var r = bit % 26 ;
var s = ( bit - r ) / 26 ;
var q = 1 << r ;
// Fast case: bit is much higher than all existing words
if ( this . length <= s ) return false ;
// Check bit and return
var w = this . words [ s ] ;
return ! ! ( w & q ) ;
} ;
// Return only lowers bits of number (in-place)
BN . prototype . imaskn = function imaskn ( bits ) {
assert ( typeof bits === 'number' && bits >= 0 ) ;
var r = bits % 26 ;
var s = ( bits - r ) / 26 ;
assert ( this . negative === 0 , 'imaskn works only with positive numbers' ) ;
if ( this . length <= s ) {
return this ;
}
if ( r !== 0 ) {
s ++ ;
}
this . length = Math . min ( s , this . length ) ;
if ( r !== 0 ) {
var mask = 0x3ffffff ^ ( ( 0x3ffffff >>> r ) << r ) ;
this . words [ this . length - 1 ] &= mask ;
}
return this . strip ( ) ;
} ;
// Return only lowers bits of number
BN . prototype . maskn = function maskn ( bits ) {
return this . clone ( ) . imaskn ( bits ) ;
} ;
// Add plain number `num` to `this`
BN . prototype . iaddn = function iaddn ( num ) {
assert ( typeof num === 'number' ) ;
assert ( num < 0x4000000 ) ;
if ( num < 0 ) return this . isubn ( - num ) ;
// Possible sign change
if ( this . negative !== 0 ) {
if ( this . length === 1 && ( this . words [ 0 ] | 0 ) < num ) {
this . words [ 0 ] = num - ( this . words [ 0 ] | 0 ) ;
this . negative = 0 ;
return this ;
}
this . negative = 0 ;
this . isubn ( num ) ;
this . negative = 1 ;
return this ;
}
// Add without checks
return this . _iaddn ( num ) ;
} ;
BN . prototype . _iaddn = function _iaddn ( num ) {
this . words [ 0 ] += num ;
// Carry
for ( var i = 0 ; i < this . length && this . words [ i ] >= 0x4000000 ; i ++ ) {
this . words [ i ] -= 0x4000000 ;
if ( i === this . length - 1 ) {
this . words [ i + 1 ] = 1 ;
} else {
this . words [ i + 1 ] ++ ;
}
}
this . length = Math . max ( this . length , i + 1 ) ;
return this ;
} ;
// Subtract plain number `num` from `this`
BN . prototype . isubn = function isubn ( num ) {
assert ( typeof num === 'number' ) ;
assert ( num < 0x4000000 ) ;
if ( num < 0 ) return this . iaddn ( - num ) ;
if ( this . negative !== 0 ) {
this . negative = 0 ;
this . iaddn ( num ) ;
this . negative = 1 ;
return this ;
}
this . words [ 0 ] -= num ;
if ( this . length === 1 && this . words [ 0 ] < 0 ) {
this . words [ 0 ] = - this . words [ 0 ] ;
this . negative = 1 ;
} else {
// Carry
for ( var i = 0 ; i < this . length && this . words [ i ] < 0 ; i ++ ) {
this . words [ i ] += 0x4000000 ;
this . words [ i + 1 ] -= 1 ;
}
}
return this . strip ( ) ;
} ;
BN . prototype . addn = function addn ( num ) {
return this . clone ( ) . iaddn ( num ) ;
} ;
BN . prototype . subn = function subn ( num ) {
return this . clone ( ) . isubn ( num ) ;
} ;
BN . prototype . iabs = function iabs ( ) {
this . negative = 0 ;
return this ;
} ;
BN . prototype . abs = function abs ( ) {
return this . clone ( ) . iabs ( ) ;
} ;
BN . prototype . _ishlnsubmul = function _ishlnsubmul ( num , mul , shift ) {
var len = num . length + shift ;
var i ;
this . _expand ( len ) ;
var w ;
var carry = 0 ;
for ( i = 0 ; i < num . length ; i ++ ) {
w = ( this . words [ i + shift ] | 0 ) + carry ;
var right = ( num . words [ i ] | 0 ) * mul ;
w -= right & 0x3ffffff ;
carry = ( w >> 26 ) - ( ( right / 0x4000000 ) | 0 ) ;
this . words [ i + shift ] = w & 0x3ffffff ;
}
for ( ; i < this . length - shift ; i ++ ) {
w = ( this . words [ i + shift ] | 0 ) + carry ;
carry = w >> 26 ;
this . words [ i + shift ] = w & 0x3ffffff ;
}
if ( carry === 0 ) return this . strip ( ) ;
// Subtraction overflow
assert ( carry === - 1 ) ;
carry = 0 ;
for ( i = 0 ; i < this . length ; i ++ ) {
w = - ( this . words [ i ] | 0 ) + carry ;
carry = w >> 26 ;
this . words [ i ] = w & 0x3ffffff ;
}
this . negative = 1 ;
return this . strip ( ) ;
} ;
BN . prototype . _wordDiv = function _wordDiv ( num , mode ) {
var shift = this . length - num . length ;
var a = this . clone ( ) ;
var b = num ;
// Normalize
var bhi = b . words [ b . length - 1 ] | 0 ;
var bhiBits = this . _countBits ( bhi ) ;
shift = 26 - bhiBits ;
if ( shift !== 0 ) {
b = b . ushln ( shift ) ;
a . iushln ( shift ) ;
bhi = b . words [ b . length - 1 ] | 0 ;
}
// Initialize quotient
var m = a . length - b . length ;
var q ;
if ( mode !== 'mod' ) {
q = new BN ( null ) ;
q . length = m + 1 ;
q . words = new Array ( q . length ) ;
for ( var i = 0 ; i < q . length ; i ++ ) {
q . words [ i ] = 0 ;
}
}
var diff = a . clone ( ) . _ishlnsubmul ( b , 1 , m ) ;
if ( diff . negative === 0 ) {
a = diff ;
if ( q ) {
q . words [ m ] = 1 ;
}
}
for ( var j = m - 1 ; j >= 0 ; j -- ) {
var qj = ( a . words [ b . length + j ] | 0 ) * 0x4000000 +
( a . words [ b . length + j - 1 ] | 0 ) ;
// NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
// (0x7ffffff)
qj = Math . min ( ( qj / bhi ) | 0 , 0x3ffffff ) ;
a . _ishlnsubmul ( b , qj , j ) ;
while ( a . negative !== 0 ) {
qj -- ;
a . negative = 0 ;
a . _ishlnsubmul ( b , 1 , j ) ;
if ( ! a . isZero ( ) ) {
a . negative ^= 1 ;
}
}
if ( q ) {
q . words [ j ] = qj ;
}
}
if ( q ) {
q . strip ( ) ;
}
a . strip ( ) ;
// Denormalize
if ( mode !== 'div' && shift !== 0 ) {
a . iushrn ( shift ) ;
}
return {
div : q || null ,
mod : a
} ;
} ;
// NOTE: 1) `mode` can be set to `mod` to request mod only,
// to `div` to request div only, or be absent to
// request both div & mod
// 2) `positive` is true if unsigned mod is requested
BN . prototype . divmod = function divmod ( num , mode , positive ) {
assert ( ! num . isZero ( ) ) ;
if ( this . isZero ( ) ) {
return {
div : new BN ( 0 ) ,
mod : new BN ( 0 )
} ;
}
var div , mod , res ;
if ( this . negative !== 0 && num . negative === 0 ) {
res = this . neg ( ) . divmod ( num , mode ) ;
if ( mode !== 'mod' ) {
div = res . div . neg ( ) ;
}
if ( mode !== 'div' ) {
mod = res . mod . neg ( ) ;
if ( positive && mod . negative !== 0 ) {
mod . iadd ( num ) ;
}
}
return {
div : div ,
mod : mod
} ;
}
if ( this . negative === 0 && num . negative !== 0 ) {
res = this . divmod ( num . neg ( ) , mode ) ;
if ( mode !== 'mod' ) {
div = res . div . neg ( ) ;
}
return {
div : div ,
mod : res . mod
} ;
}
if ( ( this . negative & num . negative ) !== 0 ) {
res = this . neg ( ) . divmod ( num . neg ( ) , mode ) ;
if ( mode !== 'div' ) {
mod = res . mod . neg ( ) ;
if ( positive && mod . negative !== 0 ) {
mod . isub ( num ) ;
}
}
return {
div : res . div ,
mod : mod
} ;
}
// Both numbers are positive at this point
// Strip both numbers to approximate shift value
if ( num . length > this . length || this . cmp ( num ) < 0 ) {
return {
div : new BN ( 0 ) ,
mod : this
} ;
}
// Very short reduction
if ( num . length === 1 ) {
if ( mode === 'div' ) {
return {
div : this . divn ( num . words [ 0 ] ) ,
mod : null
} ;
}
if ( mode === 'mod' ) {
return {
div : null ,
mod : new BN ( this . modn ( num . words [ 0 ] ) )
} ;
}
return {
div : this . divn ( num . words [ 0 ] ) ,
mod : new BN ( this . modn ( num . words [ 0 ] ) )
} ;
}
return this . _wordDiv ( num , mode ) ;
} ;
// Find `this` / `num`
BN . prototype . div = function div ( num ) {
return this . divmod ( num , 'div' , false ) . div ;
} ;
// Find `this` % `num`
BN . prototype . mod = function mod ( num ) {
return this . divmod ( num , 'mod' , false ) . mod ;
} ;
BN . prototype . umod = function umod ( num ) {
return this . divmod ( num , 'mod' , true ) . mod ;
} ;
// Find Round(`this` / `num`)
BN . prototype . divRound = function divRound ( num ) {
var dm = this . divmod ( num ) ;
// Fast case - exact division
if ( dm . mod . isZero ( ) ) return dm . div ;
var mod = dm . div . negative !== 0 ? dm . mod . isub ( num ) : dm . mod ;
var half = num . ushrn ( 1 ) ;
var r2 = num . andln ( 1 ) ;
var cmp = mod . cmp ( half ) ;
// Round down
if ( cmp < 0 || r2 === 1 && cmp === 0 ) return dm . div ;
// Round up
return dm . div . negative !== 0 ? dm . div . isubn ( 1 ) : dm . div . iaddn ( 1 ) ;
} ;
BN . prototype . modn = function modn ( num ) {
assert ( num <= 0x3ffffff ) ;
var p = ( 1 << 26 ) % num ;
var acc = 0 ;
for ( var i = this . length - 1 ; i >= 0 ; i -- ) {
acc = ( p * acc + ( this . words [ i ] | 0 ) ) % num ;
}
return acc ;
} ;
// In-place division by number
BN . prototype . idivn = function idivn ( num ) {
assert ( num <= 0x3ffffff ) ;
var carry = 0 ;
for ( var i = this . length - 1 ; i >= 0 ; i -- ) {
var w = ( this . words [ i ] | 0 ) + carry * 0x4000000 ;
this . words [ i ] = ( w / num ) | 0 ;
carry = w % num ;
}
return this . strip ( ) ;
} ;
BN . prototype . divn = function divn ( num ) {
return this . clone ( ) . idivn ( num ) ;
} ;
BN . prototype . egcd = function egcd ( p ) {
assert ( p . negative === 0 ) ;
assert ( ! p . isZero ( ) ) ;
var x = this ;
var y = p . clone ( ) ;
if ( x . negative !== 0 ) {
x = x . umod ( p ) ;
} else {
x = x . clone ( ) ;
}
// A * x + B * y = x
var A = new BN ( 1 ) ;
var B = new BN ( 0 ) ;
// C * x + D * y = y
var C = new BN ( 0 ) ;
var D = new BN ( 1 ) ;
var g = 0 ;
while ( x . isEven ( ) && y . isEven ( ) ) {
x . iushrn ( 1 ) ;
y . iushrn ( 1 ) ;
++ g ;
}
var yp = y . clone ( ) ;
var xp = x . clone ( ) ;
while ( ! x . isZero ( ) ) {
for ( var i = 0 , im = 1 ; ( x . words [ 0 ] & im ) === 0 && i < 26 ; ++ i , im <<= 1 ) ;
if ( i > 0 ) {
x . iushrn ( i ) ;
while ( i -- > 0 ) {
if ( A . isOdd ( ) || B . isOdd ( ) ) {
A . iadd ( yp ) ;
B . isub ( xp ) ;
}
A . iushrn ( 1 ) ;
B . iushrn ( 1 ) ;
}
}
for ( var j = 0 , jm = 1 ; ( y . words [ 0 ] & jm ) === 0 && j < 26 ; ++ j , jm <<= 1 ) ;
if ( j > 0 ) {
y . iushrn ( j ) ;
while ( j -- > 0 ) {
if ( C . isOdd ( ) || D . isOdd ( ) ) {
C . iadd ( yp ) ;
D . isub ( xp ) ;
}
C . iushrn ( 1 ) ;
D . iushrn ( 1 ) ;
}
}
if ( x . cmp ( y ) >= 0 ) {
x . isub ( y ) ;
A . isub ( C ) ;
B . isub ( D ) ;
} else {
y . isub ( x ) ;
C . isub ( A ) ;
D . isub ( B ) ;
}
}
return {
a : C ,
b : D ,
gcd : y . iushln ( g )
} ;
} ;
// This is reduced incarnation of the binary EEA
// above, designated to invert members of the
// _prime_ fields F(p) at a maximal speed
BN . prototype . _invmp = function _invmp ( p ) {
assert ( p . negative === 0 ) ;
assert ( ! p . isZero ( ) ) ;
var a = this ;
var b = p . clone ( ) ;
if ( a . negative !== 0 ) {
a = a . umod ( p ) ;
} else {
a = a . clone ( ) ;
}
var x1 = new BN ( 1 ) ;
var x2 = new BN ( 0 ) ;
var delta = b . clone ( ) ;
while ( a . cmpn ( 1 ) > 0 && b . cmpn ( 1 ) > 0 ) {
for ( var i = 0 , im = 1 ; ( a . words [ 0 ] & im ) === 0 && i < 26 ; ++ i , im <<= 1 ) ;
if ( i > 0 ) {
a . iushrn ( i ) ;
while ( i -- > 0 ) {
if ( x1 . isOdd ( ) ) {
x1 . iadd ( delta ) ;
}
x1 . iushrn ( 1 ) ;
}
}
for ( var j = 0 , jm = 1 ; ( b . words [ 0 ] & jm ) === 0 && j < 26 ; ++ j , jm <<= 1 ) ;
if ( j > 0 ) {
b . iushrn ( j ) ;
while ( j -- > 0 ) {
if ( x2 . isOdd ( ) ) {
x2 . iadd ( delta ) ;
}
x2 . iushrn ( 1 ) ;
}
}
if ( a . cmp ( b ) >= 0 ) {
a . isub ( b ) ;
x1 . isub ( x2 ) ;
} else {
b . isub ( a ) ;
x2 . isub ( x1 ) ;
}
}
var res ;
if ( a . cmpn ( 1 ) === 0 ) {
res = x1 ;
} else {
res = x2 ;
}
if ( res . cmpn ( 0 ) < 0 ) {
res . iadd ( p ) ;
}
return res ;
} ;
BN . prototype . gcd = function gcd ( num ) {
if ( this . isZero ( ) ) return num . abs ( ) ;
if ( num . isZero ( ) ) return this . abs ( ) ;
var a = this . clone ( ) ;
var b = num . clone ( ) ;
a . negative = 0 ;
b . negative = 0 ;
// Remove common factor of two
for ( var shift = 0 ; a . isEven ( ) && b . isEven ( ) ; shift ++ ) {
a . iushrn ( 1 ) ;
b . iushrn ( 1 ) ;
}
do {
while ( a . isEven ( ) ) {
a . iushrn ( 1 ) ;
}
while ( b . isEven ( ) ) {
b . iushrn ( 1 ) ;
}
var r = a . cmp ( b ) ;
if ( r < 0 ) {
// Swap `a` and `b` to make `a` always bigger than `b`
var t = a ;
a = b ;
b = t ;
} else if ( r === 0 || b . cmpn ( 1 ) === 0 ) {
break ;
}
a . isub ( b ) ;
} while ( true ) ;
return b . iushln ( shift ) ;
} ;
// Invert number in the field F(num)
BN . prototype . invm = function invm ( num ) {
return this . egcd ( num ) . a . umod ( num ) ;
} ;
BN . prototype . isEven = function isEven ( ) {
return ( this . words [ 0 ] & 1 ) === 0 ;
} ;
BN . prototype . isOdd = function isOdd ( ) {
return ( this . words [ 0 ] & 1 ) === 1 ;
} ;
// And first word and num
BN . prototype . andln = function andln ( num ) {
return this . words [ 0 ] & num ;
} ;
// Increment at the bit position in-line
BN . prototype . bincn = function bincn ( bit ) {
assert ( typeof bit === 'number' ) ;
var r = bit % 26 ;
var s = ( bit - r ) / 26 ;
var q = 1 << r ;
// Fast case: bit is much higher than all existing words
if ( this . length <= s ) {
this . _expand ( s + 1 ) ;
this . words [ s ] |= q ;
return this ;
}
// Add bit and propagate, if needed
var carry = q ;
for ( var i = s ; carry !== 0 && i < this . length ; i ++ ) {
var w = this . words [ i ] | 0 ;
w += carry ;
carry = w >>> 26 ;
w &= 0x3ffffff ;
this . words [ i ] = w ;
}
if ( carry !== 0 ) {
this . words [ i ] = carry ;
this . length ++ ;
}
return this ;
} ;
BN . prototype . isZero = function isZero ( ) {
return this . length === 1 && this . words [ 0 ] === 0 ;
} ;
BN . prototype . cmpn = function cmpn ( num ) {
var negative = num < 0 ;
if ( this . negative !== 0 && ! negative ) return - 1 ;
if ( this . negative === 0 && negative ) return 1 ;
this . strip ( ) ;
var res ;
if ( this . length > 1 ) {
res = 1 ;
} else {
if ( negative ) {
num = - num ;
}
assert ( num <= 0x3ffffff , 'Number is too big' ) ;
var w = this . words [ 0 ] | 0 ;
res = w === num ? 0 : w < num ? - 1 : 1 ;
}
if ( this . negative !== 0 ) return - res | 0 ;
return res ;
} ;
// Compare two numbers and return:
// 1 - if `this` > `num`
// 0 - if `this` == `num`
// -1 - if `this` < `num`
BN . prototype . cmp = function cmp ( num ) {
if ( this . negative !== 0 && num . negative === 0 ) return - 1 ;
if ( this . negative === 0 && num . negative !== 0 ) return 1 ;
var res = this . ucmp ( num ) ;
if ( this . negative !== 0 ) return - res | 0 ;
return res ;
} ;
// Unsigned comparison
BN . prototype . ucmp = function ucmp ( num ) {
// At this point both numbers have the same sign
if ( this . length > num . length ) return 1 ;
if ( this . length < num . length ) return - 1 ;
var res = 0 ;
for ( var i = this . length - 1 ; i >= 0 ; i -- ) {
var a = this . words [ i ] | 0 ;
var b = num . words [ i ] | 0 ;
if ( a === b ) continue ;
if ( a < b ) {
res = - 1 ;
} else if ( a > b ) {
res = 1 ;
}
break ;
}
return res ;
} ;
BN . prototype . gtn = function gtn ( num ) {
return this . cmpn ( num ) === 1 ;
} ;
BN . prototype . gt = function gt ( num ) {
return this . cmp ( num ) === 1 ;
} ;
BN . prototype . gten = function gten ( num ) {
return this . cmpn ( num ) >= 0 ;
} ;
BN . prototype . gte = function gte ( num ) {
return this . cmp ( num ) >= 0 ;
} ;
BN . prototype . ltn = function ltn ( num ) {
return this . cmpn ( num ) === - 1 ;
} ;
BN . prototype . lt = function lt ( num ) {
return this . cmp ( num ) === - 1 ;
} ;
BN . prototype . lten = function lten ( num ) {
return this . cmpn ( num ) <= 0 ;
} ;
BN . prototype . lte = function lte ( num ) {
return this . cmp ( num ) <= 0 ;
} ;
BN . prototype . eqn = function eqn ( num ) {
return this . cmpn ( num ) === 0 ;
} ;
BN . prototype . eq = function eq ( num ) {
return this . cmp ( num ) === 0 ;
} ;
//
// A reduce context, could be using montgomery or something better, depending
// on the `m` itself.
//
BN . red = function red ( num ) {
return new Red ( num ) ;
} ;
BN . prototype . toRed = function toRed ( ctx ) {
assert ( ! this . red , 'Already a number in reduction context' ) ;
assert ( this . negative === 0 , 'red works only with positives' ) ;
return ctx . convertTo ( this ) . _forceRed ( ctx ) ;
} ;
BN . prototype . fromRed = function fromRed ( ) {
assert ( this . red , 'fromRed works only with numbers in reduction context' ) ;
return this . red . convertFrom ( this ) ;
} ;
BN . prototype . _forceRed = function _forceRed ( ctx ) {
this . red = ctx ;
return this ;
} ;
BN . prototype . forceRed = function forceRed ( ctx ) {
assert ( ! this . red , 'Already a number in reduction context' ) ;
return this . _forceRed ( ctx ) ;
} ;
BN . prototype . redAdd = function redAdd ( num ) {
assert ( this . red , 'redAdd works only with red numbers' ) ;
return this . red . add ( this , num ) ;
} ;
BN . prototype . redIAdd = function redIAdd ( num ) {
assert ( this . red , 'redIAdd works only with red numbers' ) ;
return this . red . iadd ( this , num ) ;
} ;
BN . prototype . redSub = function redSub ( num ) {
assert ( this . red , 'redSub works only with red numbers' ) ;
return this . red . sub ( this , num ) ;
} ;
BN . prototype . redISub = function redISub ( num ) {
assert ( this . red , 'redISub works only with red numbers' ) ;
return this . red . isub ( this , num ) ;
} ;
BN . prototype . redShl = function redShl ( num ) {
assert ( this . red , 'redShl works only with red numbers' ) ;
return this . red . shl ( this , num ) ;
} ;
BN . prototype . redMul = function redMul ( num ) {
assert ( this . red , 'redMul works only with red numbers' ) ;
this . red . _verify2 ( this , num ) ;
return this . red . mul ( this , num ) ;
} ;
BN . prototype . redIMul = function redIMul ( num ) {
assert ( this . red , 'redMul works only with red numbers' ) ;
this . red . _verify2 ( this , num ) ;
return this . red . imul ( this , num ) ;
} ;
BN . prototype . redSqr = function redSqr ( ) {
assert ( this . red , 'redSqr works only with red numbers' ) ;
this . red . _verify1 ( this ) ;
return this . red . sqr ( this ) ;
} ;
BN . prototype . redISqr = function redISqr ( ) {
assert ( this . red , 'redISqr works only with red numbers' ) ;
this . red . _verify1 ( this ) ;
return this . red . isqr ( this ) ;
} ;
// Square root over p
BN . prototype . redSqrt = function redSqrt ( ) {
assert ( this . red , 'redSqrt works only with red numbers' ) ;
this . red . _verify1 ( this ) ;
return this . red . sqrt ( this ) ;
} ;
BN . prototype . redInvm = function redInvm ( ) {
assert ( this . red , 'redInvm works only with red numbers' ) ;
this . red . _verify1 ( this ) ;
return this . red . invm ( this ) ;
} ;
// Return negative clone of `this` % `red modulo`
BN . prototype . redNeg = function redNeg ( ) {
assert ( this . red , 'redNeg works only with red numbers' ) ;
this . red . _verify1 ( this ) ;
return this . red . neg ( this ) ;
} ;
BN . prototype . redPow = function redPow ( num ) {
assert ( this . red && ! num . red , 'redPow(normalNum)' ) ;
this . red . _verify1 ( this ) ;
return this . red . pow ( this , num ) ;
} ;
// Prime numbers with efficient reduction
var primes = {
k256 : null ,
p224 : null ,
p192 : null ,
p25519 : null
} ;
// Pseudo-Mersenne prime
function MPrime ( name , p ) {
// P = 2 ^ N - K
this . name = name ;
this . p = new BN ( p , 16 ) ;
this . n = this . p . bitLength ( ) ;
this . k = new BN ( 1 ) . iushln ( this . n ) . isub ( this . p ) ;
this . tmp = this . _tmp ( ) ;
}
MPrime . prototype . _tmp = function _tmp ( ) {
var tmp = new BN ( null ) ;
tmp . words = new Array ( Math . ceil ( this . n / 13 ) ) ;
return tmp ;
} ;
MPrime . prototype . ireduce = function ireduce ( num ) {
// Assumes that `num` is less than `P^2`
// num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
var r = num ;
var rlen ;
do {
this . split ( r , this . tmp ) ;
r = this . imulK ( r ) ;
r = r . iadd ( this . tmp ) ;
rlen = r . bitLength ( ) ;
} while ( rlen > this . n ) ;
var cmp = rlen < this . n ? - 1 : r . ucmp ( this . p ) ;
if ( cmp === 0 ) {
r . words [ 0 ] = 0 ;
r . length = 1 ;
} else if ( cmp > 0 ) {
r . isub ( this . p ) ;
} else {
r . strip ( ) ;
}
return r ;
} ;
MPrime . prototype . split = function split ( input , out ) {
input . iushrn ( this . n , 0 , out ) ;
} ;
MPrime . prototype . imulK = function imulK ( num ) {
return num . imul ( this . k ) ;
} ;
function K256 ( ) {
MPrime . call (
this ,
'k256' ,
'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f' ) ;
}
inherits ( K256 , MPrime ) ;
K256 . prototype . split = function split ( input , output ) {
// 256 = 9 * 26 + 22
var mask = 0x3fffff ;
var outLen = Math . min ( input . length , 9 ) ;
for ( var i = 0 ; i < outLen ; i ++ ) {
output . words [ i ] = input . words [ i ] ;
}
output . length = outLen ;
if ( input . length <= 9 ) {
input . words [ 0 ] = 0 ;
input . length = 1 ;
return ;
}
// Shift by 9 limbs
var prev = input . words [ 9 ] ;
output . words [ output . length ++ ] = prev & mask ;
for ( i = 10 ; i < input . length ; i ++ ) {
var next = input . words [ i ] | 0 ;
input . words [ i - 10 ] = ( ( next & mask ) << 4 ) | ( prev >>> 22 ) ;
prev = next ;
}
prev >>>= 22 ;
input . words [ i - 10 ] = prev ;
if ( prev === 0 && input . length > 10 ) {
input . length -= 10 ;
} else {
input . length -= 9 ;
}
} ;
K256 . prototype . imulK = function imulK ( num ) {
// K = 0x1000003d1 = [ 0x40, 0x3d1 ]
num . words [ num . length ] = 0 ;
num . words [ num . length + 1 ] = 0 ;
num . length += 2 ;
// bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
var lo = 0 ;
for ( var i = 0 ; i < num . length ; i ++ ) {
var w = num . words [ i ] | 0 ;
lo += w * 0x3d1 ;
num . words [ i ] = lo & 0x3ffffff ;
lo = w * 0x40 + ( ( lo / 0x4000000 ) | 0 ) ;
}
// Fast length reduction
if ( num . words [ num . length - 1 ] === 0 ) {
num . length -- ;
if ( num . words [ num . length - 1 ] === 0 ) {
num . length -- ;
}
}
return num ;
} ;
function P224 ( ) {
MPrime . call (
this ,
'p224' ,
'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001' ) ;
}
inherits ( P224 , MPrime ) ;
function P192 ( ) {
MPrime . call (
this ,
'p192' ,
'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff' ) ;
}
inherits ( P192 , MPrime ) ;
function P25519 ( ) {
// 2 ^ 255 - 19
MPrime . call (
this ,
'25519' ,
'7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed' ) ;
}
inherits ( P25519 , MPrime ) ;
P25519 . prototype . imulK = function imulK ( num ) {
// K = 0x13
var carry = 0 ;
for ( var i = 0 ; i < num . length ; i ++ ) {
var hi = ( num . words [ i ] | 0 ) * 0x13 + carry ;
var lo = hi & 0x3ffffff ;
hi >>>= 26 ;
num . words [ i ] = lo ;
carry = hi ;
}
if ( carry !== 0 ) {
num . words [ num . length ++ ] = carry ;
}
return num ;
} ;
// Exported mostly for testing purposes, use plain name instead
BN . _prime = function prime ( name ) {
// Cached version of prime
if ( primes [ name ] ) return primes [ name ] ;
var prime ;
if ( name === 'k256' ) {
prime = new K256 ( ) ;
} else if ( name === 'p224' ) {
prime = new P224 ( ) ;
} else if ( name === 'p192' ) {
prime = new P192 ( ) ;
} else if ( name === 'p25519' ) {
prime = new P25519 ( ) ;
} else {
throw new Error ( 'Unknown prime ' + name ) ;
}
primes [ name ] = prime ;
return prime ;
} ;
//
// Base reduction engine
//
function Red ( m ) {
if ( typeof m === 'string' ) {
var prime = BN . _prime ( m ) ;
this . m = prime . p ;
this . prime = prime ;
} else {
assert ( m . gtn ( 1 ) , 'modulus must be greater than 1' ) ;
this . m = m ;
this . prime = null ;
}
}
Red . prototype . _verify1 = function _verify1 ( a ) {
assert ( a . negative === 0 , 'red works only with positives' ) ;
assert ( a . red , 'red works only with red numbers' ) ;
} ;
Red . prototype . _verify2 = function _verify2 ( a , b ) {
assert ( ( a . negative | b . negative ) === 0 , 'red works only with positives' ) ;
assert ( a . red && a . red === b . red ,
'red works only with red numbers' ) ;
} ;
Red . prototype . imod = function imod ( a ) {
if ( this . prime ) return this . prime . ireduce ( a ) . _forceRed ( this ) ;
return a . umod ( this . m ) . _forceRed ( this ) ;
} ;
Red . prototype . neg = function neg ( a ) {
if ( a . isZero ( ) ) {
return a . clone ( ) ;
}
return this . m . sub ( a ) . _forceRed ( this ) ;
} ;
Red . prototype . add = function add ( a , b ) {
this . _verify2 ( a , b ) ;
var res = a . add ( b ) ;
if ( res . cmp ( this . m ) >= 0 ) {
res . isub ( this . m ) ;
}
return res . _forceRed ( this ) ;
} ;
Red . prototype . iadd = function iadd ( a , b ) {
this . _verify2 ( a , b ) ;
var res = a . iadd ( b ) ;
if ( res . cmp ( this . m ) >= 0 ) {
res . isub ( this . m ) ;
}
return res ;
} ;
Red . prototype . sub = function sub ( a , b ) {
this . _verify2 ( a , b ) ;
var res = a . sub ( b ) ;
if ( res . cmpn ( 0 ) < 0 ) {
res . iadd ( this . m ) ;
}
return res . _forceRed ( this ) ;
} ;
Red . prototype . isub = function isub ( a , b ) {
this . _verify2 ( a , b ) ;
var res = a . isub ( b ) ;
if ( res . cmpn ( 0 ) < 0 ) {
res . iadd ( this . m ) ;
}
return res ;
} ;
Red . prototype . shl = function shl ( a , num ) {
this . _verify1 ( a ) ;
return this . imod ( a . ushln ( num ) ) ;
} ;
Red . prototype . imul = function imul ( a , b ) {
this . _verify2 ( a , b ) ;
return this . imod ( a . imul ( b ) ) ;
} ;
Red . prototype . mul = function mul ( a , b ) {
this . _verify2 ( a , b ) ;
return this . imod ( a . mul ( b ) ) ;
} ;
Red . prototype . isqr = function isqr ( a ) {
return this . imul ( a , a . clone ( ) ) ;
} ;
Red . prototype . sqr = function sqr ( a ) {
return this . mul ( a , a ) ;
} ;
Red . prototype . sqrt = function sqrt ( a ) {
if ( a . isZero ( ) ) return a . clone ( ) ;
var mod3 = this . m . andln ( 3 ) ;
assert ( mod3 % 2 === 1 ) ;
// Fast case
if ( mod3 === 3 ) {
var pow = this . m . add ( new BN ( 1 ) ) . iushrn ( 2 ) ;
return this . pow ( a , pow ) ;
}
// Tonelli-Shanks algorithm (Totally unoptimized and slow)
//
// Find Q and S, that Q * 2 ^ S = (P - 1)
var q = this . m . subn ( 1 ) ;
var s = 0 ;
while ( ! q . isZero ( ) && q . andln ( 1 ) === 0 ) {
s ++ ;
q . iushrn ( 1 ) ;
}
assert ( ! q . isZero ( ) ) ;
var one = new BN ( 1 ) . toRed ( this ) ;
var nOne = one . redNeg ( ) ;
// Find quadratic non-residue
// NOTE: Max is such because of generalized Riemann hypothesis.
var lpow = this . m . subn ( 1 ) . iushrn ( 1 ) ;
var z = this . m . bitLength ( ) ;
z = new BN ( 2 * z * z ) . toRed ( this ) ;
while ( this . pow ( z , lpow ) . cmp ( nOne ) !== 0 ) {
z . redIAdd ( nOne ) ;
}
var c = this . pow ( z , q ) ;
var r = this . pow ( a , q . addn ( 1 ) . iushrn ( 1 ) ) ;
var t = this . pow ( a , q ) ;
var m = s ;
while ( t . cmp ( one ) !== 0 ) {
var tmp = t ;
for ( var i = 0 ; tmp . cmp ( one ) !== 0 ; i ++ ) {
tmp = tmp . redSqr ( ) ;
}
assert ( i < m ) ;
var b = this . pow ( c , new BN ( 1 ) . iushln ( m - i - 1 ) ) ;
r = r . redMul ( b ) ;
c = b . redSqr ( ) ;
t = t . redMul ( c ) ;
m = i ;
}
return r ;
} ;
Red . prototype . invm = function invm ( a ) {
var inv = a . _invmp ( this . m ) ;
if ( inv . negative !== 0 ) {
inv . negative = 0 ;
return this . imod ( inv ) . redNeg ( ) ;
} else {
return this . imod ( inv ) ;
}
} ;
Red . prototype . pow = function pow ( a , num ) {
2017-07-06 03:39:03 +03:00
if ( num . isZero ( ) ) return new BN ( 1 ) . toRed ( this ) ;
2017-05-22 03:38:41 +03:00
if ( num . cmpn ( 1 ) === 0 ) return a . clone ( ) ;
var windowSize = 4 ;
var wnd = new Array ( 1 << windowSize ) ;
wnd [ 0 ] = new BN ( 1 ) . toRed ( this ) ;
wnd [ 1 ] = a ;
for ( var i = 2 ; i < wnd . length ; i ++ ) {
wnd [ i ] = this . mul ( wnd [ i - 1 ] , a ) ;
}
var res = wnd [ 0 ] ;
var current = 0 ;
var currentLen = 0 ;
var start = num . bitLength ( ) % 26 ;
if ( start === 0 ) {
start = 26 ;
}
for ( i = num . length - 1 ; i >= 0 ; i -- ) {
var word = num . words [ i ] ;
for ( var j = start - 1 ; j >= 0 ; j -- ) {
var bit = ( word >> j ) & 1 ;
if ( res !== wnd [ 0 ] ) {
res = this . sqr ( res ) ;
}
if ( bit === 0 && current === 0 ) {
currentLen = 0 ;
continue ;
}
current <<= 1 ;
current |= bit ;
currentLen ++ ;
if ( currentLen !== windowSize && ( i !== 0 || j !== 0 ) ) continue ;
res = this . mul ( res , wnd [ current ] ) ;
currentLen = 0 ;
current = 0 ;
}
start = 26 ;
}
return res ;
} ;
Red . prototype . convertTo = function convertTo ( num ) {
var r = num . umod ( this . m ) ;
return r === num ? r . clone ( ) : r ;
} ;
Red . prototype . convertFrom = function convertFrom ( num ) {
var res = num . clone ( ) ;
res . red = null ;
return res ;
} ;
//
// Montgomery method engine
//
BN . mont = function mont ( num ) {
return new Mont ( num ) ;
} ;
function Mont ( m ) {
Red . call ( this , m ) ;
this . shift = this . m . bitLength ( ) ;
if ( this . shift % 26 !== 0 ) {
this . shift += 26 - ( this . shift % 26 ) ;
}
this . r = new BN ( 1 ) . iushln ( this . shift ) ;
this . r2 = this . imod ( this . r . sqr ( ) ) ;
this . rinv = this . r . _invmp ( this . m ) ;
this . minv = this . rinv . mul ( this . r ) . isubn ( 1 ) . div ( this . m ) ;
this . minv = this . minv . umod ( this . r ) ;
this . minv = this . r . sub ( this . minv ) ;
}
inherits ( Mont , Red ) ;
Mont . prototype . convertTo = function convertTo ( num ) {
return this . imod ( num . ushln ( this . shift ) ) ;
} ;
Mont . prototype . convertFrom = function convertFrom ( num ) {
var r = this . imod ( num . mul ( this . rinv ) ) ;
r . red = null ;
return r ;
} ;
Mont . prototype . imul = function imul ( a , b ) {
if ( a . isZero ( ) || b . isZero ( ) ) {
a . words [ 0 ] = 0 ;
a . length = 1 ;
return a ;
}
var t = a . imul ( b ) ;
var c = t . maskn ( this . shift ) . mul ( this . minv ) . imaskn ( this . shift ) . mul ( this . m ) ;
var u = t . isub ( c ) . iushrn ( this . shift ) ;
var res = u ;
if ( u . cmp ( this . m ) >= 0 ) {
res = u . isub ( this . m ) ;
} else if ( u . cmpn ( 0 ) < 0 ) {
res = u . iadd ( this . m ) ;
}
return res . _forceRed ( this ) ;
} ;
Mont . prototype . mul = function mul ( a , b ) {
if ( a . isZero ( ) || b . isZero ( ) ) return new BN ( 0 ) . _forceRed ( this ) ;
var t = a . mul ( b ) ;
var c = t . maskn ( this . shift ) . mul ( this . minv ) . imaskn ( this . shift ) . mul ( this . m ) ;
var u = t . isub ( c ) . iushrn ( this . shift ) ;
var res = u ;
if ( u . cmp ( this . m ) >= 0 ) {
res = u . isub ( this . m ) ;
} else if ( u . cmpn ( 0 ) < 0 ) {
res = u . iadd ( this . m ) ;
}
return res . _forceRed ( this ) ;
} ;
Mont . prototype . invm = function invm ( a ) {
// (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
var res = this . imod ( a . _invmp ( this . m ) . mul ( this . r2 ) ) ;
return res . _forceRed ( this ) ;
} ;
} ) ( typeof module === 'undefined' || module , this ) ;
2017-11-10 03:54:28 +03:00
} , { "buffer" : 2 } ] , 2 : [ function ( require , module , exports ) {
} , { } ] , 3 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
if ( typeof Object . create === 'function' ) {
// implementation from standard node.js 'util' module
module . exports = function inherits ( ctor , superCtor ) {
ctor . super _ = superCtor
ctor . prototype = Object . create ( superCtor . prototype , {
constructor : {
value : ctor ,
enumerable : false ,
writable : true ,
configurable : true
}
} ) ;
} ;
} else {
// old school shim for old browsers
module . exports = function inherits ( ctor , superCtor ) {
ctor . super _ = superCtor
var TempCtor = function ( ) { }
TempCtor . prototype = superCtor . prototype
ctor . prototype = new TempCtor ( )
ctor . prototype . constructor = ctor
}
2017-05-22 03:38:41 +03:00
}
2018-03-05 03:31:09 +03:00
} , { } ] , 4 : [ function ( require , module , exports ) {
2017-07-06 03:39:03 +03:00
( function ( process , global ) {
/ * *
* [ js - sha3 ] { @ link https : //github.com/emn178/js-sha3}
*
* @ version 0.5 . 7
* @ author Chen , Yi - Cyuan [ emn178 @ gmail . com ]
* @ copyright Chen , Yi - Cyuan 2015 - 2016
* @ license MIT
* /
/*jslint bitwise: true */
( function ( ) {
'use strict' ;
var root = typeof window === 'object' ? window : { } ;
var NODE _JS = ! root . JS _SHA3 _NO _NODE _JS && typeof process === 'object' && process . versions && process . versions . node ;
if ( NODE _JS ) {
root = global ;
}
var COMMON _JS = ! root . JS _SHA3 _NO _COMMON _JS && typeof module === 'object' && module . exports ;
var HEX _CHARS = '0123456789abcdef' . split ( '' ) ;
var SHAKE _PADDING = [ 31 , 7936 , 2031616 , 520093696 ] ;
var KECCAK _PADDING = [ 1 , 256 , 65536 , 16777216 ] ;
var PADDING = [ 6 , 1536 , 393216 , 100663296 ] ;
var SHIFT = [ 0 , 8 , 16 , 24 ] ;
var RC = [ 1 , 0 , 32898 , 0 , 32906 , 2147483648 , 2147516416 , 2147483648 , 32907 , 0 , 2147483649 ,
0 , 2147516545 , 2147483648 , 32777 , 2147483648 , 138 , 0 , 136 , 0 , 2147516425 , 0 ,
2147483658 , 0 , 2147516555 , 0 , 139 , 2147483648 , 32905 , 2147483648 , 32771 ,
2147483648 , 32770 , 2147483648 , 128 , 2147483648 , 32778 , 0 , 2147483658 , 2147483648 ,
2147516545 , 2147483648 , 32896 , 2147483648 , 2147483649 , 0 , 2147516424 , 2147483648 ] ;
var BITS = [ 224 , 256 , 384 , 512 ] ;
var SHAKE _BITS = [ 128 , 256 ] ;
var OUTPUT _TYPES = [ 'hex' , 'buffer' , 'arrayBuffer' , 'array' ] ;
var createOutputMethod = function ( bits , padding , outputType ) {
return function ( message ) {
return new Keccak ( bits , padding , bits ) . update ( message ) [ outputType ] ( ) ;
} ;
} ;
var createShakeOutputMethod = function ( bits , padding , outputType ) {
return function ( message , outputBits ) {
return new Keccak ( bits , padding , outputBits ) . update ( message ) [ outputType ] ( ) ;
} ;
} ;
var createMethod = function ( bits , padding ) {
var method = createOutputMethod ( bits , padding , 'hex' ) ;
method . create = function ( ) {
return new Keccak ( bits , padding , bits ) ;
} ;
method . update = function ( message ) {
return method . create ( ) . update ( message ) ;
} ;
for ( var i = 0 ; i < OUTPUT _TYPES . length ; ++ i ) {
var type = OUTPUT _TYPES [ i ] ;
method [ type ] = createOutputMethod ( bits , padding , type ) ;
}
return method ;
} ;
var createShakeMethod = function ( bits , padding ) {
var method = createShakeOutputMethod ( bits , padding , 'hex' ) ;
method . create = function ( outputBits ) {
return new Keccak ( bits , padding , outputBits ) ;
} ;
method . update = function ( message , outputBits ) {
return method . create ( outputBits ) . update ( message ) ;
} ;
for ( var i = 0 ; i < OUTPUT _TYPES . length ; ++ i ) {
var type = OUTPUT _TYPES [ i ] ;
method [ type ] = createShakeOutputMethod ( bits , padding , type ) ;
}
return method ;
} ;
var algorithms = [
{ name : 'keccak' , padding : KECCAK _PADDING , bits : BITS , createMethod : createMethod } ,
{ name : 'sha3' , padding : PADDING , bits : BITS , createMethod : createMethod } ,
{ name : 'shake' , padding : SHAKE _PADDING , bits : SHAKE _BITS , createMethod : createShakeMethod }
] ;
var methods = { } , methodNames = [ ] ;
for ( var i = 0 ; i < algorithms . length ; ++ i ) {
var algorithm = algorithms [ i ] ;
var bits = algorithm . bits ;
for ( var j = 0 ; j < bits . length ; ++ j ) {
var methodName = algorithm . name + '_' + bits [ j ] ;
methodNames . push ( methodName ) ;
methods [ methodName ] = algorithm . createMethod ( bits [ j ] , algorithm . padding ) ;
}
}
function Keccak ( bits , padding , outputBits ) {
this . blocks = [ ] ;
this . s = [ ] ;
this . padding = padding ;
this . outputBits = outputBits ;
this . reset = true ;
this . block = 0 ;
this . start = 0 ;
this . blockCount = ( 1600 - ( bits << 1 ) ) >> 5 ;
this . byteCount = this . blockCount << 2 ;
this . outputBlocks = outputBits >> 5 ;
this . extraBytes = ( outputBits & 31 ) >> 3 ;
for ( var i = 0 ; i < 50 ; ++ i ) {
this . s [ i ] = 0 ;
}
}
Keccak . prototype . update = function ( message ) {
var notString = typeof message !== 'string' ;
if ( notString && message . constructor === ArrayBuffer ) {
message = new Uint8Array ( message ) ;
}
var length = message . length , blocks = this . blocks , byteCount = this . byteCount ,
blockCount = this . blockCount , index = 0 , s = this . s , i , code ;
while ( index < length ) {
if ( this . reset ) {
this . reset = false ;
blocks [ 0 ] = this . block ;
for ( i = 1 ; i < blockCount + 1 ; ++ i ) {
blocks [ i ] = 0 ;
}
}
if ( notString ) {
for ( i = this . start ; index < length && i < byteCount ; ++ index ) {
blocks [ i >> 2 ] |= message [ index ] << SHIFT [ i ++ & 3 ] ;
}
} else {
for ( i = this . start ; index < length && i < byteCount ; ++ index ) {
code = message . charCodeAt ( index ) ;
if ( code < 0x80 ) {
blocks [ i >> 2 ] |= code << SHIFT [ i ++ & 3 ] ;
} else if ( code < 0x800 ) {
blocks [ i >> 2 ] |= ( 0xc0 | ( code >> 6 ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( code & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
} else if ( code < 0xd800 || code >= 0xe000 ) {
blocks [ i >> 2 ] |= ( 0xe0 | ( code >> 12 ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( ( code >> 6 ) & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( code & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
} else {
code = 0x10000 + ( ( ( code & 0x3ff ) << 10 ) | ( message . charCodeAt ( ++ index ) & 0x3ff ) ) ;
blocks [ i >> 2 ] |= ( 0xf0 | ( code >> 18 ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( ( code >> 12 ) & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( ( code >> 6 ) & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
blocks [ i >> 2 ] |= ( 0x80 | ( code & 0x3f ) ) << SHIFT [ i ++ & 3 ] ;
}
}
}
this . lastByteIndex = i ;
if ( i >= byteCount ) {
this . start = i - byteCount ;
this . block = blocks [ blockCount ] ;
for ( i = 0 ; i < blockCount ; ++ i ) {
s [ i ] ^= blocks [ i ] ;
}
f ( s ) ;
this . reset = true ;
} else {
this . start = i ;
}
}
return this ;
} ;
Keccak . prototype . finalize = function ( ) {
var blocks = this . blocks , i = this . lastByteIndex , blockCount = this . blockCount , s = this . s ;
blocks [ i >> 2 ] |= this . padding [ i & 3 ] ;
if ( this . lastByteIndex === this . byteCount ) {
blocks [ 0 ] = blocks [ blockCount ] ;
for ( i = 1 ; i < blockCount + 1 ; ++ i ) {
blocks [ i ] = 0 ;
}
}
blocks [ blockCount - 1 ] |= 0x80000000 ;
for ( i = 0 ; i < blockCount ; ++ i ) {
s [ i ] ^= blocks [ i ] ;
}
f ( s ) ;
} ;
Keccak . prototype . toString = Keccak . prototype . hex = function ( ) {
this . finalize ( ) ;
var blockCount = this . blockCount , s = this . s , outputBlocks = this . outputBlocks ,
extraBytes = this . extraBytes , i = 0 , j = 0 ;
var hex = '' , block ;
while ( j < outputBlocks ) {
for ( i = 0 ; i < blockCount && j < outputBlocks ; ++ i , ++ j ) {
block = s [ i ] ;
hex += HEX _CHARS [ ( block >> 4 ) & 0x0F ] + HEX _CHARS [ block & 0x0F ] +
HEX _CHARS [ ( block >> 12 ) & 0x0F ] + HEX _CHARS [ ( block >> 8 ) & 0x0F ] +
HEX _CHARS [ ( block >> 20 ) & 0x0F ] + HEX _CHARS [ ( block >> 16 ) & 0x0F ] +
HEX _CHARS [ ( block >> 28 ) & 0x0F ] + HEX _CHARS [ ( block >> 24 ) & 0x0F ] ;
}
if ( j % blockCount === 0 ) {
f ( s ) ;
i = 0 ;
}
}
if ( extraBytes ) {
block = s [ i ] ;
if ( extraBytes > 0 ) {
hex += HEX _CHARS [ ( block >> 4 ) & 0x0F ] + HEX _CHARS [ block & 0x0F ] ;
}
if ( extraBytes > 1 ) {
hex += HEX _CHARS [ ( block >> 12 ) & 0x0F ] + HEX _CHARS [ ( block >> 8 ) & 0x0F ] ;
}
if ( extraBytes > 2 ) {
hex += HEX _CHARS [ ( block >> 20 ) & 0x0F ] + HEX _CHARS [ ( block >> 16 ) & 0x0F ] ;
}
}
return hex ;
} ;
Keccak . prototype . arrayBuffer = function ( ) {
this . finalize ( ) ;
var blockCount = this . blockCount , s = this . s , outputBlocks = this . outputBlocks ,
extraBytes = this . extraBytes , i = 0 , j = 0 ;
var bytes = this . outputBits >> 3 ;
var buffer ;
if ( extraBytes ) {
buffer = new ArrayBuffer ( ( outputBlocks + 1 ) << 2 ) ;
} else {
buffer = new ArrayBuffer ( bytes ) ;
}
var array = new Uint32Array ( buffer ) ;
while ( j < outputBlocks ) {
for ( i = 0 ; i < blockCount && j < outputBlocks ; ++ i , ++ j ) {
array [ j ] = s [ i ] ;
}
if ( j % blockCount === 0 ) {
f ( s ) ;
}
}
if ( extraBytes ) {
array [ i ] = s [ i ] ;
buffer = buffer . slice ( 0 , bytes ) ;
}
return buffer ;
} ;
Keccak . prototype . buffer = Keccak . prototype . arrayBuffer ;
Keccak . prototype . digest = Keccak . prototype . array = function ( ) {
this . finalize ( ) ;
var blockCount = this . blockCount , s = this . s , outputBlocks = this . outputBlocks ,
extraBytes = this . extraBytes , i = 0 , j = 0 ;
var array = [ ] , offset , block ;
while ( j < outputBlocks ) {
for ( i = 0 ; i < blockCount && j < outputBlocks ; ++ i , ++ j ) {
offset = j << 2 ;
block = s [ i ] ;
array [ offset ] = block & 0xFF ;
array [ offset + 1 ] = ( block >> 8 ) & 0xFF ;
array [ offset + 2 ] = ( block >> 16 ) & 0xFF ;
array [ offset + 3 ] = ( block >> 24 ) & 0xFF ;
}
if ( j % blockCount === 0 ) {
f ( s ) ;
}
}
if ( extraBytes ) {
offset = j << 2 ;
block = s [ i ] ;
if ( extraBytes > 0 ) {
array [ offset ] = block & 0xFF ;
}
if ( extraBytes > 1 ) {
array [ offset + 1 ] = ( block >> 8 ) & 0xFF ;
}
if ( extraBytes > 2 ) {
array [ offset + 2 ] = ( block >> 16 ) & 0xFF ;
}
}
return array ;
} ;
var f = function ( s ) {
var h , l , n , c0 , c1 , c2 , c3 , c4 , c5 , c6 , c7 , c8 , c9 ,
b0 , b1 , b2 , b3 , b4 , b5 , b6 , b7 , b8 , b9 , b10 , b11 , b12 , b13 , b14 , b15 , b16 , b17 ,
b18 , b19 , b20 , b21 , b22 , b23 , b24 , b25 , b26 , b27 , b28 , b29 , b30 , b31 , b32 , b33 ,
b34 , b35 , b36 , b37 , b38 , b39 , b40 , b41 , b42 , b43 , b44 , b45 , b46 , b47 , b48 , b49 ;
for ( n = 0 ; n < 48 ; n += 2 ) {
c0 = s [ 0 ] ^ s [ 10 ] ^ s [ 20 ] ^ s [ 30 ] ^ s [ 40 ] ;
c1 = s [ 1 ] ^ s [ 11 ] ^ s [ 21 ] ^ s [ 31 ] ^ s [ 41 ] ;
c2 = s [ 2 ] ^ s [ 12 ] ^ s [ 22 ] ^ s [ 32 ] ^ s [ 42 ] ;
c3 = s [ 3 ] ^ s [ 13 ] ^ s [ 23 ] ^ s [ 33 ] ^ s [ 43 ] ;
c4 = s [ 4 ] ^ s [ 14 ] ^ s [ 24 ] ^ s [ 34 ] ^ s [ 44 ] ;
c5 = s [ 5 ] ^ s [ 15 ] ^ s [ 25 ] ^ s [ 35 ] ^ s [ 45 ] ;
c6 = s [ 6 ] ^ s [ 16 ] ^ s [ 26 ] ^ s [ 36 ] ^ s [ 46 ] ;
c7 = s [ 7 ] ^ s [ 17 ] ^ s [ 27 ] ^ s [ 37 ] ^ s [ 47 ] ;
c8 = s [ 8 ] ^ s [ 18 ] ^ s [ 28 ] ^ s [ 38 ] ^ s [ 48 ] ;
c9 = s [ 9 ] ^ s [ 19 ] ^ s [ 29 ] ^ s [ 39 ] ^ s [ 49 ] ;
h = c8 ^ ( ( c2 << 1 ) | ( c3 >>> 31 ) ) ;
l = c9 ^ ( ( c3 << 1 ) | ( c2 >>> 31 ) ) ;
s [ 0 ] ^= h ;
s [ 1 ] ^= l ;
s [ 10 ] ^= h ;
s [ 11 ] ^= l ;
s [ 20 ] ^= h ;
s [ 21 ] ^= l ;
s [ 30 ] ^= h ;
s [ 31 ] ^= l ;
s [ 40 ] ^= h ;
s [ 41 ] ^= l ;
h = c0 ^ ( ( c4 << 1 ) | ( c5 >>> 31 ) ) ;
l = c1 ^ ( ( c5 << 1 ) | ( c4 >>> 31 ) ) ;
s [ 2 ] ^= h ;
s [ 3 ] ^= l ;
s [ 12 ] ^= h ;
s [ 13 ] ^= l ;
s [ 22 ] ^= h ;
s [ 23 ] ^= l ;
s [ 32 ] ^= h ;
s [ 33 ] ^= l ;
s [ 42 ] ^= h ;
s [ 43 ] ^= l ;
h = c2 ^ ( ( c6 << 1 ) | ( c7 >>> 31 ) ) ;
l = c3 ^ ( ( c7 << 1 ) | ( c6 >>> 31 ) ) ;
s [ 4 ] ^= h ;
s [ 5 ] ^= l ;
s [ 14 ] ^= h ;
s [ 15 ] ^= l ;
s [ 24 ] ^= h ;
s [ 25 ] ^= l ;
s [ 34 ] ^= h ;
s [ 35 ] ^= l ;
s [ 44 ] ^= h ;
s [ 45 ] ^= l ;
h = c4 ^ ( ( c8 << 1 ) | ( c9 >>> 31 ) ) ;
l = c5 ^ ( ( c9 << 1 ) | ( c8 >>> 31 ) ) ;
s [ 6 ] ^= h ;
s [ 7 ] ^= l ;
s [ 16 ] ^= h ;
s [ 17 ] ^= l ;
s [ 26 ] ^= h ;
s [ 27 ] ^= l ;
s [ 36 ] ^= h ;
s [ 37 ] ^= l ;
s [ 46 ] ^= h ;
s [ 47 ] ^= l ;
h = c6 ^ ( ( c0 << 1 ) | ( c1 >>> 31 ) ) ;
l = c7 ^ ( ( c1 << 1 ) | ( c0 >>> 31 ) ) ;
s [ 8 ] ^= h ;
s [ 9 ] ^= l ;
s [ 18 ] ^= h ;
s [ 19 ] ^= l ;
s [ 28 ] ^= h ;
s [ 29 ] ^= l ;
s [ 38 ] ^= h ;
s [ 39 ] ^= l ;
s [ 48 ] ^= h ;
s [ 49 ] ^= l ;
b0 = s [ 0 ] ;
b1 = s [ 1 ] ;
b32 = ( s [ 11 ] << 4 ) | ( s [ 10 ] >>> 28 ) ;
b33 = ( s [ 10 ] << 4 ) | ( s [ 11 ] >>> 28 ) ;
b14 = ( s [ 20 ] << 3 ) | ( s [ 21 ] >>> 29 ) ;
b15 = ( s [ 21 ] << 3 ) | ( s [ 20 ] >>> 29 ) ;
b46 = ( s [ 31 ] << 9 ) | ( s [ 30 ] >>> 23 ) ;
b47 = ( s [ 30 ] << 9 ) | ( s [ 31 ] >>> 23 ) ;
b28 = ( s [ 40 ] << 18 ) | ( s [ 41 ] >>> 14 ) ;
b29 = ( s [ 41 ] << 18 ) | ( s [ 40 ] >>> 14 ) ;
b20 = ( s [ 2 ] << 1 ) | ( s [ 3 ] >>> 31 ) ;
b21 = ( s [ 3 ] << 1 ) | ( s [ 2 ] >>> 31 ) ;
b2 = ( s [ 13 ] << 12 ) | ( s [ 12 ] >>> 20 ) ;
b3 = ( s [ 12 ] << 12 ) | ( s [ 13 ] >>> 20 ) ;
b34 = ( s [ 22 ] << 10 ) | ( s [ 23 ] >>> 22 ) ;
b35 = ( s [ 23 ] << 10 ) | ( s [ 22 ] >>> 22 ) ;
b16 = ( s [ 33 ] << 13 ) | ( s [ 32 ] >>> 19 ) ;
b17 = ( s [ 32 ] << 13 ) | ( s [ 33 ] >>> 19 ) ;
b48 = ( s [ 42 ] << 2 ) | ( s [ 43 ] >>> 30 ) ;
b49 = ( s [ 43 ] << 2 ) | ( s [ 42 ] >>> 30 ) ;
b40 = ( s [ 5 ] << 30 ) | ( s [ 4 ] >>> 2 ) ;
b41 = ( s [ 4 ] << 30 ) | ( s [ 5 ] >>> 2 ) ;
b22 = ( s [ 14 ] << 6 ) | ( s [ 15 ] >>> 26 ) ;
b23 = ( s [ 15 ] << 6 ) | ( s [ 14 ] >>> 26 ) ;
b4 = ( s [ 25 ] << 11 ) | ( s [ 24 ] >>> 21 ) ;
b5 = ( s [ 24 ] << 11 ) | ( s [ 25 ] >>> 21 ) ;
b36 = ( s [ 34 ] << 15 ) | ( s [ 35 ] >>> 17 ) ;
b37 = ( s [ 35 ] << 15 ) | ( s [ 34 ] >>> 17 ) ;
b18 = ( s [ 45 ] << 29 ) | ( s [ 44 ] >>> 3 ) ;
b19 = ( s [ 44 ] << 29 ) | ( s [ 45 ] >>> 3 ) ;
b10 = ( s [ 6 ] << 28 ) | ( s [ 7 ] >>> 4 ) ;
b11 = ( s [ 7 ] << 28 ) | ( s [ 6 ] >>> 4 ) ;
b42 = ( s [ 17 ] << 23 ) | ( s [ 16 ] >>> 9 ) ;
b43 = ( s [ 16 ] << 23 ) | ( s [ 17 ] >>> 9 ) ;
b24 = ( s [ 26 ] << 25 ) | ( s [ 27 ] >>> 7 ) ;
b25 = ( s [ 27 ] << 25 ) | ( s [ 26 ] >>> 7 ) ;
b6 = ( s [ 36 ] << 21 ) | ( s [ 37 ] >>> 11 ) ;
b7 = ( s [ 37 ] << 21 ) | ( s [ 36 ] >>> 11 ) ;
b38 = ( s [ 47 ] << 24 ) | ( s [ 46 ] >>> 8 ) ;
b39 = ( s [ 46 ] << 24 ) | ( s [ 47 ] >>> 8 ) ;
b30 = ( s [ 8 ] << 27 ) | ( s [ 9 ] >>> 5 ) ;
b31 = ( s [ 9 ] << 27 ) | ( s [ 8 ] >>> 5 ) ;
b12 = ( s [ 18 ] << 20 ) | ( s [ 19 ] >>> 12 ) ;
b13 = ( s [ 19 ] << 20 ) | ( s [ 18 ] >>> 12 ) ;
b44 = ( s [ 29 ] << 7 ) | ( s [ 28 ] >>> 25 ) ;
b45 = ( s [ 28 ] << 7 ) | ( s [ 29 ] >>> 25 ) ;
b26 = ( s [ 38 ] << 8 ) | ( s [ 39 ] >>> 24 ) ;
b27 = ( s [ 39 ] << 8 ) | ( s [ 38 ] >>> 24 ) ;
b8 = ( s [ 48 ] << 14 ) | ( s [ 49 ] >>> 18 ) ;
b9 = ( s [ 49 ] << 14 ) | ( s [ 48 ] >>> 18 ) ;
s [ 0 ] = b0 ^ ( ~ b2 & b4 ) ;
s [ 1 ] = b1 ^ ( ~ b3 & b5 ) ;
s [ 10 ] = b10 ^ ( ~ b12 & b14 ) ;
s [ 11 ] = b11 ^ ( ~ b13 & b15 ) ;
s [ 20 ] = b20 ^ ( ~ b22 & b24 ) ;
s [ 21 ] = b21 ^ ( ~ b23 & b25 ) ;
s [ 30 ] = b30 ^ ( ~ b32 & b34 ) ;
s [ 31 ] = b31 ^ ( ~ b33 & b35 ) ;
s [ 40 ] = b40 ^ ( ~ b42 & b44 ) ;
s [ 41 ] = b41 ^ ( ~ b43 & b45 ) ;
s [ 2 ] = b2 ^ ( ~ b4 & b6 ) ;
s [ 3 ] = b3 ^ ( ~ b5 & b7 ) ;
s [ 12 ] = b12 ^ ( ~ b14 & b16 ) ;
s [ 13 ] = b13 ^ ( ~ b15 & b17 ) ;
s [ 22 ] = b22 ^ ( ~ b24 & b26 ) ;
s [ 23 ] = b23 ^ ( ~ b25 & b27 ) ;
s [ 32 ] = b32 ^ ( ~ b34 & b36 ) ;
s [ 33 ] = b33 ^ ( ~ b35 & b37 ) ;
s [ 42 ] = b42 ^ ( ~ b44 & b46 ) ;
s [ 43 ] = b43 ^ ( ~ b45 & b47 ) ;
s [ 4 ] = b4 ^ ( ~ b6 & b8 ) ;
s [ 5 ] = b5 ^ ( ~ b7 & b9 ) ;
s [ 14 ] = b14 ^ ( ~ b16 & b18 ) ;
s [ 15 ] = b15 ^ ( ~ b17 & b19 ) ;
s [ 24 ] = b24 ^ ( ~ b26 & b28 ) ;
s [ 25 ] = b25 ^ ( ~ b27 & b29 ) ;
s [ 34 ] = b34 ^ ( ~ b36 & b38 ) ;
s [ 35 ] = b35 ^ ( ~ b37 & b39 ) ;
s [ 44 ] = b44 ^ ( ~ b46 & b48 ) ;
s [ 45 ] = b45 ^ ( ~ b47 & b49 ) ;
s [ 6 ] = b6 ^ ( ~ b8 & b0 ) ;
s [ 7 ] = b7 ^ ( ~ b9 & b1 ) ;
s [ 16 ] = b16 ^ ( ~ b18 & b10 ) ;
s [ 17 ] = b17 ^ ( ~ b19 & b11 ) ;
s [ 26 ] = b26 ^ ( ~ b28 & b20 ) ;
s [ 27 ] = b27 ^ ( ~ b29 & b21 ) ;
s [ 36 ] = b36 ^ ( ~ b38 & b30 ) ;
s [ 37 ] = b37 ^ ( ~ b39 & b31 ) ;
s [ 46 ] = b46 ^ ( ~ b48 & b40 ) ;
s [ 47 ] = b47 ^ ( ~ b49 & b41 ) ;
s [ 8 ] = b8 ^ ( ~ b0 & b2 ) ;
s [ 9 ] = b9 ^ ( ~ b1 & b3 ) ;
s [ 18 ] = b18 ^ ( ~ b10 & b12 ) ;
s [ 19 ] = b19 ^ ( ~ b11 & b13 ) ;
s [ 28 ] = b28 ^ ( ~ b20 & b22 ) ;
s [ 29 ] = b29 ^ ( ~ b21 & b23 ) ;
s [ 38 ] = b38 ^ ( ~ b30 & b32 ) ;
s [ 39 ] = b39 ^ ( ~ b31 & b33 ) ;
s [ 48 ] = b48 ^ ( ~ b40 & b42 ) ;
s [ 49 ] = b49 ^ ( ~ b41 & b43 ) ;
s [ 0 ] ^= RC [ n ] ;
s [ 1 ] ^= RC [ n + 1 ] ;
}
} ;
if ( COMMON _JS ) {
module . exports = methods ;
} else {
for ( var i = 0 ; i < methodNames . length ; ++ i ) {
root [ methodNames [ i ] ] = methods [ methodNames [ i ] ] ;
}
}
} ) ( ) ;
2018-03-05 03:31:09 +03:00
} ) . call ( this , require ( '_process' ) , typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : { } )
} , { "_process" : 5 } ] , 5 : [ function ( require , module , exports ) {
2018-06-04 03:50:21 +03:00
// shim for using process in browser
var process = module . exports = { } ;
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout ;
var cachedClearTimeout ;
function defaultSetTimout ( ) {
throw new Error ( 'setTimeout has not been defined' ) ;
}
function defaultClearTimeout ( ) {
throw new Error ( 'clearTimeout has not been defined' ) ;
}
( function ( ) {
try {
if ( typeof setTimeout === 'function' ) {
cachedSetTimeout = setTimeout ;
} else {
cachedSetTimeout = defaultSetTimout ;
}
} catch ( e ) {
cachedSetTimeout = defaultSetTimout ;
}
try {
if ( typeof clearTimeout === 'function' ) {
cachedClearTimeout = clearTimeout ;
} else {
cachedClearTimeout = defaultClearTimeout ;
}
} catch ( e ) {
cachedClearTimeout = defaultClearTimeout ;
}
} ( ) )
function runTimeout ( fun ) {
if ( cachedSetTimeout === setTimeout ) {
//normal enviroments in sane situations
return setTimeout ( fun , 0 ) ;
}
// if setTimeout wasn't available but was latter defined
if ( ( cachedSetTimeout === defaultSetTimout || ! cachedSetTimeout ) && setTimeout ) {
cachedSetTimeout = setTimeout ;
return setTimeout ( fun , 0 ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout ( fun , 0 ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout . call ( null , fun , 0 ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout . call ( this , fun , 0 ) ;
}
}
}
function runClearTimeout ( marker ) {
if ( cachedClearTimeout === clearTimeout ) {
//normal enviroments in sane situations
return clearTimeout ( marker ) ;
}
// if clearTimeout wasn't available but was latter defined
if ( ( cachedClearTimeout === defaultClearTimeout || ! cachedClearTimeout ) && clearTimeout ) {
cachedClearTimeout = clearTimeout ;
return clearTimeout ( marker ) ;
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout ( marker ) ;
} catch ( e ) {
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout . call ( null , marker ) ;
} catch ( e ) {
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout . call ( this , marker ) ;
}
}
}
var queue = [ ] ;
var draining = false ;
var currentQueue ;
var queueIndex = - 1 ;
function cleanUpNextTick ( ) {
if ( ! draining || ! currentQueue ) {
return ;
}
draining = false ;
if ( currentQueue . length ) {
queue = currentQueue . concat ( queue ) ;
} else {
queueIndex = - 1 ;
}
if ( queue . length ) {
drainQueue ( ) ;
}
}
function drainQueue ( ) {
if ( draining ) {
return ;
}
var timeout = runTimeout ( cleanUpNextTick ) ;
draining = true ;
var len = queue . length ;
while ( len ) {
currentQueue = queue ;
queue = [ ] ;
while ( ++ queueIndex < len ) {
if ( currentQueue ) {
currentQueue [ queueIndex ] . run ( ) ;
}
}
queueIndex = - 1 ;
len = queue . length ;
}
currentQueue = null ;
draining = false ;
runClearTimeout ( timeout ) ;
}
process . nextTick = function ( fun ) {
var args = new Array ( arguments . length - 1 ) ;
if ( arguments . length > 1 ) {
for ( var i = 1 ; i < arguments . length ; i ++ ) {
args [ i - 1 ] = arguments [ i ] ;
}
}
queue . push ( new Item ( fun , args ) ) ;
if ( queue . length === 1 && ! draining ) {
runTimeout ( drainQueue ) ;
}
} ;
// v8 likes predictible objects
function Item ( fun , array ) {
this . fun = fun ;
this . array = array ;
}
Item . prototype . run = function ( ) {
this . fun . apply ( null , this . array ) ;
} ;
process . title = 'browser' ;
process . browser = true ;
process . env = { } ;
process . argv = [ ] ;
process . version = '' ; // empty string to avoid regexp issues
process . versions = { } ;
function noop ( ) { }
process . on = noop ;
process . addListener = noop ;
process . once = noop ;
process . off = noop ;
process . removeListener = noop ;
process . removeAllListeners = noop ;
process . emit = noop ;
process . prependListener = noop ;
process . prependOnceListener = noop ;
process . listeners = function ( name ) { return [ ] }
process . binding = function ( name ) {
throw new Error ( 'process.binding is not supported' ) ;
} ;
process . cwd = function ( ) { return '/' } ;
process . chdir = function ( dir ) {
throw new Error ( 'process.chdir is not supported' ) ;
} ;
process . umask = function ( ) { return 0 ; } ;
2018-03-05 03:31:09 +03:00
} , { } ] , 6 : [ function ( require , module , exports ) {
'use strict' ;
try {
module . exports . XMLHttpRequest = XMLHttpRequest ;
} catch ( error ) {
console . log ( 'Warning: XMLHttpRequest is not defined' ) ;
module . exports . XMLHttpRequest = null ;
}
} , { } ] , 7 : [ function ( require , module , exports ) {
'use strict' ;
var Provider = require ( './provider.js' ) ;
var utils = ( function ( ) {
var convert = require ( '../utils/convert.js' ) ;
return {
defineProperty : require ( '../utils/properties.js' ) . defineProperty ,
hexlify : convert . hexlify ,
hexStripZeros : convert . hexStripZeros ,
} ;
} ) ( ) ;
function getTransactionString ( transaction ) {
var result = [ ] ;
for ( var key in transaction ) {
if ( transaction [ key ] == null ) { continue ; }
var value = utils . hexlify ( transaction [ key ] ) ;
if ( { gasLimit : true , gasPrice : true , nonce : true , value : true } [ key ] ) {
value = utils . hexStripZeros ( value ) ;
}
result . push ( key + '=' + value ) ;
}
return result . join ( '&' ) ;
}
function EtherscanProvider ( network , apiKey ) {
Provider . call ( this , network ) ;
var baseUrl = null ;
switch ( this . name ) {
case 'homestead' :
baseUrl = 'https://api.etherscan.io' ;
break ;
case 'ropsten' :
2018-06-06 02:40:28 +03:00
baseUrl = 'https://api-ropsten.etherscan.io' ;
2018-03-05 03:31:09 +03:00
break ;
case 'rinkeby' :
2018-06-06 02:40:28 +03:00
baseUrl = 'https://api-rinkeby.etherscan.io' ;
2018-03-05 03:31:09 +03:00
break ;
case 'kovan' :
2018-06-06 02:40:28 +03:00
baseUrl = 'https://api-kovan.etherscan.io' ;
2018-03-05 03:31:09 +03:00
break ;
default :
throw new Error ( 'unsupported network' ) ;
}
utils . defineProperty ( this , 'baseUrl' , baseUrl ) ;
utils . defineProperty ( this , 'apiKey' , apiKey || null ) ;
}
Provider . inherits ( EtherscanProvider ) ;
utils . defineProperty ( EtherscanProvider . prototype , '_call' , function ( ) {
} ) ;
utils . defineProperty ( EtherscanProvider . prototype , '_callProxy' , function ( ) {
} ) ;
function getResult ( result ) {
2018-04-17 04:31:49 +03:00
// getLogs, getHistory have weird success responses
if ( result . status == 0 && ( result . message === 'No records found' || result . message === 'No transactions found' ) ) {
2018-03-05 03:31:09 +03:00
return result . result ;
}
if ( result . status != 1 || result . message != 'OK' ) {
var error = new Error ( 'invalid response' ) ;
error . result = JSON . stringify ( result ) ;
throw error ;
}
return result . result ;
}
function getJsonResult ( result ) {
if ( result . jsonrpc != '2.0' ) {
var error = new Error ( 'invalid response' ) ;
error . result = JSON . stringify ( result ) ;
throw error ;
}
if ( result . error ) {
var error = new Error ( result . error . message || 'unknown error' ) ;
if ( result . error . code ) { error . code = result . error . code ; }
if ( result . error . data ) { error . data = result . error . data ; }
throw error ;
}
return result . result ;
}
function checkLogTag ( blockTag ) {
if ( blockTag === 'pending' ) { throw new Error ( 'pending not supported' ) ; }
if ( blockTag === 'latest' ) { return blockTag ; }
return parseInt ( blockTag . substring ( 2 ) , 16 ) ;
}
utils . defineProperty ( EtherscanProvider . prototype , 'perform' , function ( method , params ) {
if ( ! params ) { params = { } ; }
var url = this . baseUrl ;
var apiKey = '' ;
if ( this . apiKey ) { apiKey += '&apikey=' + this . apiKey ; }
switch ( method ) {
case 'getBlockNumber' :
url += '/api?module=proxy&action=eth_blockNumber' + apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getGasPrice' :
url += '/api?module=proxy&action=eth_gasPrice' + apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getBalance' :
// Returns base-10 result
url += '/api?module=account&action=balance&address=' + params . address ;
url += '&tag=' + params . blockTag + apiKey ;
return Provider . fetchJSON ( url , null , getResult ) ;
case 'getTransactionCount' :
url += '/api?module=proxy&action=eth_getTransactionCount&address=' + params . address ;
url += '&tag=' + params . blockTag + apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getCode' :
url += '/api?module=proxy&action=eth_getCode&address=' + params . address ;
url += '&tag=' + params . blockTag + apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getStorageAt' :
url += '/api?module=proxy&action=eth_getStorageAt&address=' + params . address ;
2018-03-05 10:52:53 +03:00
url += '&position=' + params . position ;
url += '&tag=' + params . blockTag + apiKey ;
2018-03-05 03:31:09 +03:00
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'sendTransaction' :
url += '/api?module=proxy&action=eth_sendRawTransaction&hex=' + params . signedTransaction ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getBlock' :
if ( params . blockTag ) {
2018-03-05 10:52:53 +03:00
url += '/api?module=proxy&action=eth_getBlockByNumber&tag=' + params . blockTag ;
2018-03-05 03:31:09 +03:00
url += '&boolean=false' ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
}
throw new Error ( 'getBlock by blockHash not implmeneted' ) ;
case 'getTransaction' :
url += '/api?module=proxy&action=eth_getTransactionByHash&txhash=' + params . transactionHash ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getTransactionReceipt' :
url += '/api?module=proxy&action=eth_getTransactionReceipt&txhash=' + params . transactionHash ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'call' :
var transaction = getTransactionString ( params . transaction ) ;
if ( transaction ) { transaction = '&' + transaction ; }
url += '/api?module=proxy&action=eth_call' + transaction ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'estimateGas' :
var transaction = getTransactionString ( params . transaction ) ;
if ( transaction ) { transaction = '&' + transaction ; }
url += '/api?module=proxy&action=eth_estimateGas&' + transaction ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getJsonResult ) ;
case 'getLogs' :
url += '/api?module=logs&action=getLogs' ;
try {
if ( params . filter . fromBlock ) {
url += '&fromBlock=' + checkLogTag ( params . filter . fromBlock ) ;
}
if ( params . filter . toBlock ) {
url += '&toBlock=' + checkLogTag ( params . filter . toBlock ) ;
}
if ( params . filter . address ) {
url += '&address=' + params . filter . address ;
}
// @TODO: We can handle slightly more complicated logs using the logs API
if ( params . filter . topics && params . filter . topics . length > 0 ) {
if ( params . filter . topics . length > 1 ) {
throw new Error ( 'unsupported topic format' ) ;
}
var topic0 = params . filter . topics [ 0 ] ;
if ( typeof ( topic0 ) !== 'string' || topic0 . length !== 66 ) {
throw new Error ( 'unsupported topic0 format' ) ;
}
url += '&topic0=' + topic0 ;
}
} catch ( error ) {
return Promise . reject ( error ) ;
}
url += apiKey ;
2018-04-05 22:48:46 +03:00
var self = this ;
return Provider . fetchJSON ( url , null , getResult ) . then ( function ( logs ) {
var txs = { } ;
var seq = Promise . resolve ( ) ;
logs . forEach ( function ( log ) {
seq = seq . then ( function ( ) {
2018-06-28 02:59:08 +03:00
if ( log . blockHash != null ) { return null ; }
2018-04-05 22:48:46 +03:00
log . blockHash = txs [ log . transactionHash ] ;
if ( log . blockHash == null ) {
return self . getTransaction ( log . transactionHash ) . then ( function ( tx ) {
txs [ log . transactionHash ] = tx . blockHash ;
log . blockHash = tx . blockHash ;
2018-06-28 02:59:08 +03:00
return log ;
2018-04-05 22:48:46 +03:00
} ) ;
}
2018-06-28 02:59:08 +03:00
return null ;
2018-04-05 22:48:46 +03:00
} ) ;
} )
return seq . then ( function ( ) {
return logs ;
} ) ;
} ) ;
2018-03-05 03:31:09 +03:00
case 'getEtherPrice' :
if ( this . name !== 'homestead' ) { return Promise . resolve ( 0.0 ) ; }
url += '/api?module=stats&action=ethprice' ;
url += apiKey ;
return Provider . fetchJSON ( url , null , getResult ) . then ( function ( result ) {
return parseFloat ( result . ethusd ) ;
} ) ;
default :
break ;
}
return Promise . reject ( new Error ( 'not implemented - ' + method ) ) ;
} ) ;
utils . defineProperty ( EtherscanProvider . prototype , 'getHistory' , function ( addressOrName , startBlock , endBlock ) {
var url = this . baseUrl ;
var apiKey = '' ;
if ( this . apiKey ) { apiKey += '&apikey=' + this . apiKey ; }
if ( startBlock == null ) { startBlock = 0 ; }
if ( endBlock == null ) { endBlock = 99999999 ; }
return this . resolveName ( addressOrName ) . then ( function ( address ) {
url += '/api?module=account&action=txlist&address=' + address ;
2018-03-15 23:03:20 +03:00
url += '&startblock=' + startBlock ;
url += '&endblock=' + endBlock ;
2018-03-05 03:31:09 +03:00
url += '&sort=asc' ;
return Provider . fetchJSON ( url , null , getResult ) . then ( function ( result ) {
var output = [ ] ;
result . forEach ( function ( tx ) {
[ 'contractAddress' , 'to' ] . forEach ( function ( key ) {
if ( tx [ key ] == '' ) { delete tx [ key ] ; }
} ) ;
if ( tx . creates == null && tx . contractAddress != null ) {
tx . creates = tx . contractAddress ;
}
2018-05-14 22:50:25 +03:00
var item = Provider . _formatters . checkTransactionResponse ( tx ) ;
if ( tx . timeStamp ) { item . timestamp = parseInt ( tx . timeStamp ) ; }
output . push ( item ) ;
2018-03-05 03:31:09 +03:00
} ) ;
return output ;
} ) ;
} ) ;
} ) ;
module . exports = EtherscanProvider ; ;
2018-04-14 23:10:26 +03:00
} , { "../utils/convert.js" : 19 , "../utils/properties.js" : 24 , "./provider.js" : 13 } ] , 8 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
var inherits = require ( 'inherits' ) ;
var Provider = require ( './provider.js' ) ;
var utils = ( function ( ) {
return {
defineProperty : require ( '../utils/properties.js' ) . defineProperty ,
} ;
} ) ( ) ;
function FallbackProvider ( providers ) {
if ( providers . length === 0 ) { throw new Error ( 'no providers' ) ; }
var network = { } ;
[ 'chainId' , 'ensAddress' , 'name' , 'testnet' ] . forEach ( function ( key ) {
for ( var i = 1 ; i < providers . length ; i ++ ) {
if ( providers [ 0 ] [ key ] !== providers [ i ] [ key ] ) {
throw new Error ( 'incompatible providers - ' + key + ' mismatch' ) ;
}
}
network [ key ] = providers [ 0 ] [ key ] ;
} ) ;
if ( ! ( this instanceof FallbackProvider ) ) { throw new Error ( 'missing new' ) ; }
Provider . call ( this , network ) ;
providers = providers . slice ( 0 ) ;
Object . defineProperty ( this , 'providers' , {
get : function ( ) {
return providers . slice ( 0 ) ;
}
} ) ;
}
inherits ( FallbackProvider , Provider ) ;
utils . defineProperty ( FallbackProvider . prototype , 'perform' , function ( method , params ) {
var providers = this . providers ;
return new Promise ( function ( resolve , reject ) {
var firstError = null ;
function next ( ) {
if ( ! providers . length ) {
reject ( firstError ) ;
return ;
}
var provider = providers . shift ( ) ;
provider . perform ( method , params ) . then ( function ( result ) {
2018-06-28 02:59:08 +03:00
return resolve ( result ) ;
2018-03-05 03:31:09 +03:00
} , function ( error ) {
if ( ! firstError ) { firstError = error ; }
next ( ) ;
2018-06-28 02:59:08 +03:00
} ) . catch ( function ( error ) { } ) ;
2018-03-05 03:31:09 +03:00
}
next ( ) ;
} ) ;
} ) ;
module . exports = FallbackProvider ;
2018-04-14 23:10:26 +03:00
} , { "../utils/properties.js" : 24 , "./provider.js" : 13 , "inherits" : 3 } ] , 9 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2018-04-14 01:21:48 +03:00
var Provider = require ( './provider' ) ;
2018-03-05 03:31:09 +03:00
2018-04-14 01:21:48 +03:00
var EtherscanProvider = require ( './etherscan-provider' ) ;
var FallbackProvider = require ( './fallback-provider' ) ;
var IpcProvider = require ( './ipc-provider' ) ;
var InfuraProvider = require ( './infura-provider' ) ;
var JsonRpcProvider = require ( './json-rpc-provider' ) ;
var Web3Provider = require ( './web3-provider' ) ;
2018-03-05 03:31:09 +03:00
function getDefaultProvider ( network ) {
return new FallbackProvider ( [
new InfuraProvider ( network ) ,
new EtherscanProvider ( network ) ,
] ) ;
}
2018-04-14 01:21:48 +03:00
var exports = {
2018-03-05 03:31:09 +03:00
EtherscanProvider : EtherscanProvider ,
FallbackProvider : FallbackProvider ,
InfuraProvider : InfuraProvider ,
JsonRpcProvider : JsonRpcProvider ,
Web3Provider : Web3Provider ,
isProvider : Provider . isProvider ,
networks : Provider . networks ,
getDefaultProvider : getDefaultProvider ,
Provider : Provider ,
}
2018-04-14 01:21:48 +03:00
// Only available in node, so we do not include it in browsers
if ( IpcProvider ) {
exports . IpcProvider = IpcProvider ;
}
module . exports = exports ;
2018-04-14 23:10:26 +03:00
} , { "./etherscan-provider" : 7 , "./fallback-provider" : 8 , "./infura-provider" : 10 , "./ipc-provider" : 20 , "./json-rpc-provider" : 11 , "./provider" : 13 , "./web3-provider" : 14 } ] , 10 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
var Provider = require ( './provider' ) ;
var JsonRpcProvider = require ( './json-rpc-provider' ) ;
var utils = ( function ( ) {
return {
2018-04-14 01:21:48 +03:00
defineProperty : require ( '../utils/properties' ) . defineProperty
2018-03-05 03:31:09 +03:00
}
} ) ( ) ;
2018-04-14 01:21:48 +03:00
var errors = require ( '../utils/errors' ) ;
2018-03-05 03:31:09 +03:00
function InfuraProvider ( network , apiAccessToken ) {
2018-04-14 01:21:48 +03:00
errors . checkNew ( this , InfuraProvider ) ;
2018-03-05 03:31:09 +03:00
network = Provider . getNetwork ( network ) ;
var host = null ;
switch ( network . name ) {
case 'homestead' :
host = 'mainnet.infura.io' ;
break ;
case 'ropsten' :
host = 'ropsten.infura.io' ;
break ;
case 'rinkeby' :
host = 'rinkeby.infura.io' ;
break ;
case 'kovan' :
host = 'kovan.infura.io' ;
break ;
default :
throw new Error ( 'unsupported network' ) ;
}
var url = 'https://' + host + '/' + ( apiAccessToken || '' ) ;
JsonRpcProvider . call ( this , url , network ) ;
utils . defineProperty ( this , 'apiAccessToken' , apiAccessToken || null ) ;
}
JsonRpcProvider . inherits ( InfuraProvider ) ;
utils . defineProperty ( InfuraProvider . prototype , '_startPending' , function ( ) {
console . log ( 'WARNING: INFURA does not support pending filters' ) ;
} ) ;
utils . defineProperty ( InfuraProvider . prototype , '_stopPending' , function ( ) {
} ) ;
2018-04-14 01:21:48 +03:00
utils . defineProperty ( InfuraProvider . prototype , 'getSigner' , function ( address ) {
errors . throwError ( 'INFURA does not support signing' , errors . UNSUPPORTED _OPERATION , { operation : 'getSigner' } ) ;
} ) ;
utils . defineProperty ( InfuraProvider . prototype , 'listAccounts' , function ( ) {
return Promise . resolve ( [ ] ) ;
} ) ;
2018-03-05 03:31:09 +03:00
module . exports = InfuraProvider ;
2018-04-14 23:10:26 +03:00
} , { "../utils/errors" : 21 , "../utils/properties" : 24 , "./json-rpc-provider" : 11 , "./provider" : 13 } ] , 11 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC
var Provider = require ( './provider.js' ) ;
var utils = ( function ( ) {
var convert = require ( '../utils/convert' ) ;
return {
defineProperty : require ( '../utils/properties' ) . defineProperty ,
hexlify : convert . hexlify ,
isHexString : convert . isHexString ,
hexStripZeros : convert . hexStripZeros ,
2018-04-14 01:21:48 +03:00
toUtf8Bytes : require ( '../utils/utf8' ) . toUtf8Bytes ,
getAddress : require ( '../utils/address' ) . getAddress ,
2018-03-05 03:31:09 +03:00
}
} ) ( ) ;
2018-04-14 01:21:48 +03:00
var errors = require ( '../utils/errors' ) ;
2018-03-05 03:31:09 +03:00
function timer ( timeout ) {
return new Promise ( function ( resolve ) {
setTimeout ( function ( ) {
resolve ( ) ;
} , timeout ) ;
} ) ;
}
function getResult ( payload ) {
if ( payload . error ) {
var error = new Error ( payload . error . message ) ;
error . code = payload . error . code ;
error . data = payload . error . data ;
throw error ;
}
return payload . result ;
}
function getTransaction ( transaction ) {
var result = { } ;
for ( var key in transaction ) {
result [ key ] = utils . hexlify ( transaction [ key ] ) ;
}
// Some nodes (INFURA ropsten; INFURA mainnet is fine) don't like extra zeros.
[ 'gasLimit' , 'gasPrice' , 'nonce' , 'value' ] . forEach ( function ( key ) {
if ( ! result [ key ] ) { return ; }
result [ key ] = utils . hexStripZeros ( result [ key ] ) ;
} ) ;
// Transform "gasLimit" to "gas"
if ( result . gasLimit != null && result . gas == null ) {
result . gas = result . gasLimit ;
delete result . gasLimit ;
}
return result ;
}
2018-04-17 04:31:49 +03:00
function getLowerCase ( value ) {
if ( value ) { return value . toLowerCase ( ) ; }
return value ;
}
2018-04-14 01:21:48 +03:00
function JsonRpcSigner ( provider , address ) {
errors . checkNew ( this , JsonRpcSigner ) ;
utils . defineProperty ( this , 'provider' , provider ) ;
// Statically attach to a given address
if ( address ) {
utils . defineProperty ( this , 'address' , address ) ;
utils . defineProperty ( this , '_syncAddress' , true ) ;
} else {
Object . defineProperty ( this , 'address' , {
enumerable : true ,
get : function ( ) {
errors . throwError ( 'no sync sync address available; use getAddress' , errors . UNSUPPORTED _OPERATION , { operation : 'address' } ) ;
}
} ) ;
utils . defineProperty ( this , '_syncAddress' , false ) ;
}
}
utils . defineProperty ( JsonRpcSigner . prototype , 'getAddress' , function ( ) {
if ( this . _syncAddress ) { return Promise . resolve ( this . address ) ; }
return this . provider . send ( 'eth_accounts' , [ ] ) . then ( function ( accounts ) {
if ( accounts . length === 0 ) {
errors . throwError ( 'no accounts' , errors . UNSUPPORTED _OPERATION , { operation : 'getAddress' } ) ;
}
return utils . getAddress ( accounts [ 0 ] ) ;
} ) ;
} ) ;
utils . defineProperty ( JsonRpcSigner . prototype , 'getBalance' , function ( blockTag ) {
var provider = this . provider ;
return this . getAddress ( ) . then ( function ( address ) {
return provider . getBalance ( address , blockTag ) ;
} ) ;
} ) ;
utils . defineProperty ( JsonRpcSigner . prototype , 'getTransactionCount' , function ( blockTag ) {
var provider = this . provider ;
return this . getAddress ( ) . then ( function ( address ) {
return provider . getTransactionCount ( address , blockTag ) ;
} ) ;
} ) ;
utils . defineProperty ( JsonRpcSigner . prototype , 'sendTransaction' , function ( transaction ) {
var provider = this . provider ;
transaction = getTransaction ( transaction ) ;
return this . getAddress ( ) . then ( function ( address ) {
transaction . from = address . toLowerCase ( ) ;
return provider . send ( 'eth_sendTransaction' , [ transaction ] ) . then ( function ( hash ) {
return new Promise ( function ( resolve , reject ) {
function check ( ) {
provider . getTransaction ( hash ) . then ( function ( transaction ) {
if ( ! transaction ) {
setTimeout ( check , 1000 ) ;
2018-06-28 02:59:08 +03:00
return null ;
2018-04-14 01:21:48 +03:00
}
2018-05-15 22:32:32 +03:00
transaction . wait = function ( ) {
return provider . waitForTransaction ( hash ) ;
} ;
2018-04-14 01:21:48 +03:00
resolve ( transaction ) ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( error ) {
setTimeout ( check , 1000 ) ;
return null ;
2018-04-14 01:21:48 +03:00
} ) ;
}
check ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;
utils . defineProperty ( JsonRpcSigner . prototype , 'signMessage' , function ( message ) {
var provider = this . provider ;
var data = ( ( typeof ( message ) === 'string' ) ? utils . toUtf8Bytes ( message ) : message ) ;
return this . getAddress ( ) . then ( function ( address ) {
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
return provider . send ( 'eth_sign' , [ address . toLowerCase ( ) , utils . hexlify ( data ) ] ) ;
} ) ;
} ) ;
utils . defineProperty ( JsonRpcSigner . prototype , 'unlock' , function ( password ) {
var provider = this . provider ;
return this . getAddress ( ) . then ( function ( address ) {
return provider . send ( 'personal_unlockAccount' , [ address . toLowerCase ( ) , password , null ] ) ;
} ) ;
} ) ;
2018-03-05 03:31:09 +03:00
function JsonRpcProvider ( url , network ) {
2018-04-14 01:21:48 +03:00
errors . checkNew ( this , JsonRpcProvider ) ;
2018-03-05 03:31:09 +03:00
2018-03-06 06:34:12 +03:00
if ( arguments . length == 1 ) {
2018-03-05 03:31:09 +03:00
if ( typeof ( url ) === 'string' ) {
try {
network = Provider . getNetwork ( url ) ;
url = null ;
} catch ( error ) { }
2018-04-14 23:10:26 +03:00
} else if ( url && url . url == null ) {
2018-03-05 03:31:09 +03:00
network = url ;
url = null ;
}
}
Provider . call ( this , network ) ;
if ( ! url ) { url = 'http://localhost:8545' ; }
utils . defineProperty ( this , 'url' , url ) ;
}
Provider . inherits ( JsonRpcProvider ) ;
2018-04-14 01:21:48 +03:00
utils . defineProperty ( JsonRpcProvider . prototype , 'getSigner' , function ( address ) {
return new JsonRpcSigner ( this , address ) ;
} ) ;
utils . defineProperty ( JsonRpcProvider . prototype , 'listAccounts' , function ( ) {
return this . send ( 'eth_accounts' , [ ] ) . then ( function ( accounts ) {
accounts . forEach ( function ( address , index ) {
accounts [ index ] = utils . getAddress ( address ) ;
} ) ;
return accounts ;
} ) ;
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( JsonRpcProvider . prototype , 'send' , function ( method , params ) {
var request = {
method : method ,
params : params ,
id : 42 ,
jsonrpc : "2.0"
} ;
return Provider . fetchJSON ( this . url , JSON . stringify ( request ) , getResult ) ;
} ) ;
utils . defineProperty ( JsonRpcProvider . prototype , 'perform' , function ( method , params ) {
switch ( method ) {
case 'getBlockNumber' :
return this . send ( 'eth_blockNumber' , [ ] ) ;
case 'getGasPrice' :
return this . send ( 'eth_gasPrice' , [ ] ) ;
case 'getBalance' :
2018-04-17 04:31:49 +03:00
return this . send ( 'eth_getBalance' , [ getLowerCase ( params . address ) , params . blockTag ] ) ;
2018-03-05 03:31:09 +03:00
case 'getTransactionCount' :
2018-04-17 04:31:49 +03:00
return this . send ( 'eth_getTransactionCount' , [ getLowerCase ( params . address ) , params . blockTag ] ) ;
2018-03-05 03:31:09 +03:00
case 'getCode' :
2018-04-17 04:31:49 +03:00
return this . send ( 'eth_getCode' , [ getLowerCase ( params . address ) , params . blockTag ] ) ;
2018-03-05 03:31:09 +03:00
case 'getStorageAt' :
2018-04-17 04:31:49 +03:00
return this . send ( 'eth_getStorageAt' , [ getLowerCase ( params . address ) , params . position , params . blockTag ] ) ;
2018-03-05 03:31:09 +03:00
case 'sendTransaction' :
return this . send ( 'eth_sendRawTransaction' , [ params . signedTransaction ] ) ;
case 'getBlock' :
if ( params . blockTag ) {
2018-03-05 10:52:53 +03:00
return this . send ( 'eth_getBlockByNumber' , [ params . blockTag , false ] ) ;
2018-03-05 03:31:09 +03:00
} else if ( params . blockHash ) {
return this . send ( 'eth_getBlockByHash' , [ params . blockHash , false ] ) ;
}
return Promise . reject ( new Error ( 'invalid block tag or block hash' ) ) ;
case 'getTransaction' :
return this . send ( 'eth_getTransactionByHash' , [ params . transactionHash ] ) ;
case 'getTransactionReceipt' :
return this . send ( 'eth_getTransactionReceipt' , [ params . transactionHash ] ) ;
case 'call' :
return this . send ( 'eth_call' , [ getTransaction ( params . transaction ) , 'latest' ] ) ;
case 'estimateGas' :
return this . send ( 'eth_estimateGas' , [ getTransaction ( params . transaction ) ] ) ;
case 'getLogs' :
2018-04-17 04:31:49 +03:00
if ( params . filter && params . filter . address != null ) {
params . filter . address = getLowerCase ( params . filter . address ) ;
}
2018-03-05 03:31:09 +03:00
return this . send ( 'eth_getLogs' , [ params . filter ] ) ;
default :
break ;
}
return Promise . reject ( new Error ( 'not implemented - ' + method ) ) ;
} ) ;
utils . defineProperty ( JsonRpcProvider . prototype , '_startPending' , function ( ) {
if ( this . _pendingFilter != null ) { return ; }
var self = this ;
var pendingFilter = this . send ( 'eth_newPendingTransactionFilter' , [ ] ) ;
this . _pendingFilter = pendingFilter ;
pendingFilter . then ( function ( filterId ) {
function poll ( ) {
self . send ( 'eth_getFilterChanges' , [ filterId ] ) . then ( function ( hashes ) {
if ( self . _pendingFilter != pendingFilter ) { return ; }
var seq = Promise . resolve ( ) ;
hashes . forEach ( function ( hash ) {
2018-06-04 03:50:21 +03:00
self . _emitted [ 't:' + hash . toLowerCase ( ) ] = 'pending' ;
2018-03-05 03:31:09 +03:00
seq = seq . then ( function ( ) {
return self . getTransaction ( hash ) . then ( function ( tx ) {
self . emit ( 'pending' , tx ) ;
2018-06-28 02:59:08 +03:00
return null ;
2018-03-05 03:31:09 +03:00
} ) ;
} ) ;
} ) ;
return seq . then ( function ( ) {
return timer ( 1000 ) ;
} ) ;
} ) . then ( function ( ) {
if ( self . _pendingFilter != pendingFilter ) {
self . send ( 'eth_uninstallFilter' , [ filterIf ] ) ;
2018-06-28 02:59:08 +03:00
return null ;
2018-03-05 03:31:09 +03:00
}
setTimeout ( function ( ) { poll ( ) ; } , 0 ) ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( error ) {
2018-03-05 03:31:09 +03:00
} ) ;
}
poll ( ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
return filterId ;
2018-06-28 02:59:08 +03:00
} ) . catch ( function ( error ) {
2018-03-05 03:31:09 +03:00
} ) ;
} ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( JsonRpcProvider . prototype , '_stopPending' , function ( ) {
this . _pendingFilter = null ;
} ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( JsonRpcProvider , '_hexlifyTransaction' , function ( transaction ) {
return getTransaction ( transaction ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
module . exports = JsonRpcProvider ;
2018-04-14 23:10:26 +03:00
} , { "../utils/address" : 15 , "../utils/convert" : 19 , "../utils/errors" : 21 , "../utils/properties" : 24 , "../utils/utf8" : 27 , "./provider.js" : 13 } ] , 12 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
module . exports = {
"unspecified" : {
"chainId" : 0 ,
"name" : "unspecified"
} ,
"homestead" : {
"chainId" : 1 ,
"ensAddress" : "0x314159265dd8dbb310642f98f50c066173c1259b" ,
"name" : "homestead"
} ,
"mainnet" : {
"chainId" : 1 ,
"ensAddress" : "0x314159265dd8dbb310642f98f50c066173c1259b" ,
"name" : "homestead"
} ,
"morden" : {
"chainId" : 2 ,
"name" : "morden"
} ,
"ropsten" : {
"chainId" : 3 ,
"ensAddress" : "0x112234455c3a32fd11230c42e7bccd4a84e02010" ,
"name" : "ropsten"
} ,
"testnet" : {
"chainId" : 3 ,
"ensAddress" : "0x112234455c3a32fd11230c42e7bccd4a84e02010" ,
"name" : "ropsten"
} ,
"rinkeby" : {
"chainId" : 4 ,
"name" : "rinkeby"
} ,
"kovan" : {
"chainId" : 42 ,
"name" : "kovan"
} ,
"classic" : {
"chainId" : 61 ,
"name" : "classic"
}
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
} , { } ] , 13 : [ function ( require , module , exports ) {
2017-11-10 03:54:28 +03:00
'use strict' ;
2018-03-05 03:31:09 +03:00
var inherits = require ( 'inherits' ) ;
var XMLHttpRequest = require ( 'xmlhttprequest' ) . XMLHttpRequest ;
var networks = require ( './networks.json' ) ;
2017-11-10 03:54:28 +03:00
var utils = ( function ( ) {
2018-03-05 03:31:09 +03:00
var convert = require ( '../utils/convert' ) ;
2018-04-14 23:10:26 +03:00
var utf8 = require ( '../utils/utf8' ) ;
2017-11-10 03:54:28 +03:00
return {
2018-03-05 03:31:09 +03:00
defineProperty : require ( '../utils/properties' ) . defineProperty ,
getAddress : require ( '../utils/address' ) . getAddress ,
getContractAddress : require ( '../utils/contract-address' ) . getContractAddress ,
bigNumberify : require ( '../utils/bignumber' ) . bigNumberify ,
arrayify : convert . arrayify ,
2017-11-10 03:54:28 +03:00
hexlify : convert . hexlify ,
2018-03-05 03:31:09 +03:00
isHexString : convert . isHexString ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
concat : convert . concat ,
2018-03-05 10:52:53 +03:00
hexStripZeros : convert . hexStripZeros ,
2018-03-05 03:31:09 +03:00
stripZeros : convert . stripZeros ,
2018-04-14 23:10:26 +03:00
base64 : require ( '../utils/base64' ) ,
2018-03-05 03:31:09 +03:00
namehash : require ( '../utils/namehash' ) ,
2018-04-14 23:10:26 +03:00
toUtf8String : utf8 . toUtf8String ,
toUtf8Bytes : utf8 . toUtf8Bytes ,
2018-03-05 03:31:09 +03:00
RLP : require ( '../utils/rlp' ) ,
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
} ) ( ) ;
2018-04-14 23:10:26 +03:00
var errors = require ( '../utils/errors' ) ;
2018-03-05 03:31:09 +03:00
function copyObject ( obj ) {
var result = { } ;
for ( var key in obj ) { result [ key ] = obj [ key ] ; }
return result ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
function check ( format , object ) {
var result = { } ;
for ( var key in format ) {
try {
var value = format [ key ] ( object [ key ] ) ;
if ( value !== undefined ) { result [ key ] = value ; }
} catch ( error ) {
error . checkKey = key ;
error . checkValue = object [ key ] ;
throw error ;
2017-11-10 03:54:28 +03:00
}
}
2018-03-05 03:31:09 +03:00
return result ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
function allowNull ( check , nullValue ) {
return ( function ( value ) {
if ( value == null ) { return nullValue ; }
return check ( value ) ;
} ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function allowFalsish ( check , replaceValue ) {
return ( function ( value ) {
if ( ! value ) { return replaceValue ; }
return check ( value ) ;
} ) ;
}
function arrayOf ( check ) {
return ( function ( array ) {
if ( ! Array . isArray ( array ) ) { throw new Error ( 'not an array' ) ; }
var result = [ ] ;
array . forEach ( function ( value ) {
result . push ( check ( value ) ) ;
} ) ;
return result ;
} ) ;
}
function checkHash ( hash ) {
if ( ! utils . isHexString ( hash ) || hash . length !== 66 ) {
throw new Error ( 'invalid hash - ' + hash ) ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
return hash ;
}
function checkNumber ( number ) {
return utils . bigNumberify ( number ) . toNumber ( ) ;
}
2018-04-05 22:48:46 +03:00
function checkDifficulty ( number ) {
var value = utils . bigNumberify ( number ) ;
try {
value = value . toNumber ( ) ;
} catch ( error ) {
value = null ;
}
return value ;
}
2018-03-05 03:31:09 +03:00
function checkBoolean ( value ) {
if ( typeof ( value ) === 'boolean' ) { return value ; }
if ( typeof ( value ) === 'string' ) {
if ( value === 'true' ) { return true ; }
if ( value === 'false' ) { return false ; }
}
throw new Error ( 'invaid boolean - ' + value ) ;
}
function checkUint256 ( uint256 ) {
if ( ! utils . isHexString ( uint256 ) ) {
throw new Error ( 'invalid uint256' ) ;
}
while ( uint256 . length < 66 ) {
uint256 = '0x0' + uint256 . substring ( 2 ) ;
}
return uint256 ;
}
function checkString ( string ) {
if ( typeof ( string ) !== 'string' ) { throw new Error ( 'invalid string' ) ; }
return string ;
}
function checkBlockTag ( blockTag ) {
if ( blockTag == null ) { return 'latest' ; }
if ( blockTag === 'earliest' ) { return '0x0' ; }
if ( blockTag === 'latest' || blockTag === 'pending' ) {
return blockTag ;
}
if ( typeof ( blockTag ) === 'number' ) {
2018-03-05 10:52:53 +03:00
return utils . hexStripZeros ( utils . hexlify ( blockTag ) ) ;
2018-03-05 03:31:09 +03:00
}
2018-03-05 10:52:53 +03:00
if ( utils . isHexString ( blockTag ) ) { return utils . hexStripZeros ( blockTag ) ; }
2018-03-05 03:31:09 +03:00
throw new Error ( 'invalid blockTag' ) ;
}
var formatBlock = {
hash : checkHash ,
parentHash : checkHash ,
number : checkNumber ,
timestamp : checkNumber ,
nonce : allowNull ( utils . hexlify ) ,
2018-04-05 22:48:46 +03:00
difficulty : checkDifficulty ,
2018-03-05 03:31:09 +03:00
gasLimit : utils . bigNumberify ,
gasUsed : utils . bigNumberify ,
miner : utils . getAddress ,
extraData : utils . hexlify ,
//transactions: allowNull(arrayOf(checkTransaction)),
transactions : allowNull ( arrayOf ( checkHash ) ) ,
//transactionRoot: checkHash,
//stateRoot: checkHash,
//sha3Uncles: checkHash,
//logsBloom: utils.hexlify,
} ;
function checkBlock ( block ) {
if ( block . author != null && block . miner == null ) {
block . miner = block . author ;
}
return check ( formatBlock , block ) ;
}
var formatTransaction = {
hash : checkHash ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
blockHash : allowNull ( checkHash , null ) ,
blockNumber : allowNull ( checkNumber , null ) ,
transactionIndex : allowNull ( checkNumber , null ) ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
from : utils . getAddress ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
gasPrice : utils . bigNumberify ,
gasLimit : utils . bigNumberify ,
to : allowNull ( utils . getAddress , null ) ,
value : utils . bigNumberify ,
nonce : checkNumber ,
data : utils . hexlify ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
r : allowNull ( checkUint256 ) ,
s : allowNull ( checkUint256 ) ,
v : allowNull ( checkNumber ) ,
creates : allowNull ( utils . getAddress , null ) ,
raw : allowNull ( utils . hexlify ) ,
} ;
function checkTransaction ( transaction ) {
// Rename gas to gasLimit
if ( transaction . gas != null && transaction . gasLimit == null ) {
transaction . gasLimit = transaction . gas ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
// Some clients (TestRPC) do strange things like return 0x0 for the
// 0 address; correct this to be a real address
if ( transaction . to && utils . bigNumberify ( transaction . to ) . isZero ( ) ) {
transaction . to = '0x0000000000000000000000000000000000000000' ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
// Rename input to data
if ( transaction . input != null && transaction . data == null ) {
transaction . data = transaction . input ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// If to and creates are empty, populate the creates from the transaction
if ( transaction . to == null && transaction . creates == null ) {
transaction . creates = utils . getContractAddress ( transaction ) ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
if ( ! transaction . raw ) {
// Very loose providers (e.g. TestRPC) don't provide a signature or raw
if ( transaction . v && transaction . r && transaction . s ) {
var raw = [
utils . stripZeros ( utils . hexlify ( transaction . nonce ) ) ,
utils . stripZeros ( utils . hexlify ( transaction . gasPrice ) ) ,
utils . stripZeros ( utils . hexlify ( transaction . gasLimit ) ) ,
( transaction . to || "0x" ) ,
utils . stripZeros ( utils . hexlify ( transaction . value || '0x' ) ) ,
utils . hexlify ( transaction . data || '0x' ) ,
utils . stripZeros ( utils . hexlify ( transaction . v || '0x' ) ) ,
utils . stripZeros ( utils . hexlify ( transaction . r ) ) ,
utils . stripZeros ( utils . hexlify ( transaction . s ) ) ,
] ;
transaction . raw = utils . RLP . encode ( raw ) ;
}
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
var result = check ( formatTransaction , transaction ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var networkId = transaction . networkId ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( utils . isHexString ( networkId ) ) {
networkId = utils . bigNumberify ( networkId ) . toNumber ( ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( typeof ( networkId ) !== 'number' && result . v != null ) {
networkId = ( result . v - 35 ) / 2 ;
if ( networkId < 0 ) { networkId = 0 ; }
networkId = parseInt ( networkId ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( typeof ( networkId ) !== 'number' ) { networkId = 0 ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
result . networkId = networkId ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// 0x0000... should actually be null
if ( result . blockHash && result . blockHash . replace ( /0/g , '' ) === 'x' ) {
result . blockHash = null ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
return result ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var formatTransactionRequest = {
from : allowNull ( utils . getAddress ) ,
nonce : allowNull ( checkNumber ) ,
gasLimit : allowNull ( utils . bigNumberify ) ,
gasPrice : allowNull ( utils . bigNumberify ) ,
to : allowNull ( utils . getAddress ) ,
value : allowNull ( utils . bigNumberify ) ,
data : allowNull ( utils . hexlify ) ,
} ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkTransactionRequest ( transaction ) {
return check ( formatTransactionRequest , transaction ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var formatTransactionReceiptLog = {
transactionLogIndex : allowNull ( checkNumber ) ,
transactionIndex : checkNumber ,
blockNumber : checkNumber ,
transactionHash : checkHash ,
address : utils . getAddress ,
topics : arrayOf ( checkHash ) ,
data : utils . hexlify ,
logIndex : checkNumber ,
blockHash : checkHash ,
} ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkTransactionReceiptLog ( log ) {
return check ( formatTransactionReceiptLog , log ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var formatTransactionReceipt = {
contractAddress : allowNull ( utils . getAddress , null ) ,
transactionIndex : checkNumber ,
root : allowNull ( checkHash ) ,
gasUsed : utils . bigNumberify ,
2018-04-05 22:48:46 +03:00
logsBloom : allowNull ( utils . hexlify ) ,
2018-03-05 03:31:09 +03:00
blockHash : checkHash ,
transactionHash : checkHash ,
logs : arrayOf ( checkTransactionReceiptLog ) ,
blockNumber : checkNumber ,
cumulativeGasUsed : utils . bigNumberify ,
status : allowNull ( checkNumber )
} ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkTransactionReceipt ( transactionReceipt ) {
var status = transactionReceipt . status ;
var root = transactionReceipt . root ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var result = check ( formatTransactionReceipt , transactionReceipt ) ;
result . logs . forEach ( function ( entry , index ) {
if ( entry . transactionLogIndex == null ) {
entry . transactionLogIndex = index ;
}
} ) ;
if ( transactionReceipt . status != null ) {
result . byzantium = true ;
}
return result ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkTopics ( topics ) {
if ( Array . isArray ( topics ) ) {
topics . forEach ( function ( topic ) {
checkTopics ( topic ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( topics != null ) {
checkHash ( topics ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
return topics ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var formatFilter = {
fromBlock : allowNull ( checkBlockTag , undefined ) ,
toBlock : allowNull ( checkBlockTag , undefined ) ,
address : allowNull ( utils . getAddress , undefined ) ,
topics : allowNull ( checkTopics , undefined ) ,
} ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkFilter ( filter ) {
return check ( formatFilter , filter ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var formatLog = {
blockNumber : allowNull ( checkNumber ) ,
blockHash : allowNull ( checkHash ) ,
transactionIndex : checkNumber ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
removed : allowNull ( checkBoolean ) ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
address : utils . getAddress ,
data : allowFalsish ( utils . hexlify , '0x' ) ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
topics : arrayOf ( checkHash ) ,
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
transactionHash : checkHash ,
logIndex : checkNumber ,
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function checkLog ( log ) {
return check ( formatLog , log ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function Provider ( network ) {
if ( ! ( this instanceof Provider ) ) { throw new Error ( 'missing new' ) ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
network = Provider . getNetwork ( network ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
// Check the ensAddress (if any)
var ensAddress = null ;
if ( network . ensAddress ) {
ensAddress = utils . getAddress ( network . ensAddress ) ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
// Setup our network properties
utils . defineProperty ( this , 'chainId' , network . chainId ) ;
utils . defineProperty ( this , 'ensAddress' , ensAddress ) ;
utils . defineProperty ( this , 'name' , network . name ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var events = { } ;
utils . defineProperty ( this , '_events' , events ) ;
2017-12-30 22:05:40 +03:00
2018-03-07 02:40:11 +03:00
// We use this to track recent emitted events; for example, if we emit a "block" of 100
// and we get a `getBlock(100)` request which would result in null, we should retry
// until we get a response. This provides devs with a consistent view. Similarly for
// transaction hashes.
utils . defineProperty ( this , '_emitted' , { block : - 1 } ) ;
2018-03-05 03:31:09 +03:00
var self = this ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
var lastBlockNumber = null ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
var balances = { } ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
function doPoll ( ) {
self . getBlockNumber ( ) . then ( function ( blockNumber ) {
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
// If the block hasn't changed, meh.
if ( blockNumber === lastBlockNumber ) { return ; }
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
if ( lastBlockNumber === null ) { lastBlockNumber = blockNumber - 1 ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Notify all listener for each block that has passed
for ( var i = lastBlockNumber + 1 ; i <= blockNumber ; i ++ ) {
2018-03-07 02:40:11 +03:00
if ( self . _emitted . block < i ) {
self . _emitted . block = i ;
// Evict any transaction hashes or block hashes over 12 blocks
// old, since they should not return null anyways
Object . keys ( self . _emitted ) . forEach ( function ( key ) {
if ( key === 'block' ) { return ; }
if ( self . _emitted [ key ] > i + 12 ) {
delete self . _emitted [ key ] ;
}
} ) ;
}
2018-03-05 03:31:09 +03:00
self . emit ( 'block' , i ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Sweep balances and remove addresses we no longer have events for
var newBalances = { } ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Find all transaction hashes we are waiting on
Object . keys ( events ) . forEach ( function ( eventName ) {
var event = parseEventString ( eventName ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( event . type === 'transaction' ) {
self . getTransaction ( event . hash ) . then ( function ( transaction ) {
2018-06-28 02:59:08 +03:00
if ( ! transaction || transaction . blockNumber == null ) { return null ; }
2018-03-07 02:40:11 +03:00
self . _emitted [ 't:' + transaction . hash . toLowerCase ( ) ] = transaction . blockNumber ;
2018-03-05 03:31:09 +03:00
self . emit ( event . hash , transaction ) ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( error ) { } ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( event . type === 'address' ) {
if ( balances [ event . address ] ) {
newBalances [ event . address ] = balances [ event . address ] ;
}
self . getBalance ( event . address , 'latest' ) . then ( function ( balance ) {
var lastBalance = balances [ event . address ] ;
2018-06-28 02:59:08 +03:00
if ( lastBalance && balance . eq ( lastBalance ) ) { return null ; }
2018-03-05 03:31:09 +03:00
balances [ event . address ] = balance ;
self . emit ( event . address , balance ) ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( error ) { } ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( event . type === 'topic' ) {
self . getLogs ( {
fromBlock : lastBlockNumber + 1 ,
toBlock : blockNumber ,
topics : event . topic
} ) . then ( function ( logs ) {
2018-06-28 02:59:08 +03:00
if ( logs . length === 0 ) { return null ; }
2018-03-05 03:31:09 +03:00
logs . forEach ( function ( log ) {
2018-03-07 02:40:11 +03:00
self . _emitted [ 'b:' + log . blockHash . toLowerCase ( ) ] = log . blockNumber ;
self . _emitted [ 't:' + log . transactionHash . toLowerCase ( ) ] = log . blockNumber ;
2018-03-05 03:31:09 +03:00
self . emit ( event . topic , log ) ;
} ) ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( error ) { } ) ;
2018-03-05 03:31:09 +03:00
}
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
lastBlockNumber = blockNumber ;
balances = newBalances ;
2018-06-28 02:59:08 +03:00
return null ;
} ) . catch ( function ( ) { } ) ;
2018-03-05 03:31:09 +03:00
self . doPoll ( ) ;
}
utils . defineProperty ( this , 'resetEventsBlock' , function ( blockNumber ) {
lastBlockNumber = blockNumber ;
self . doPoll ( ) ;
2017-11-13 00:39:41 +03:00
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-15 23:03:20 +03:00
var pollingInterval = 4000 ;
2018-03-05 03:31:09 +03:00
var poller = null ;
Object . defineProperty ( this , 'polling' , {
get : function ( ) { return ( poller != null ) ; } ,
set : function ( value ) {
setTimeout ( function ( ) {
if ( value && ! poller ) {
2018-03-15 23:03:20 +03:00
poller = setInterval ( doPoll , pollingInterval ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( ! value && poller ) {
clearInterval ( poller ) ;
poller = null ;
}
} , 0 ) ;
2017-11-10 03:54:28 +03:00
}
} ) ;
2018-03-15 23:03:20 +03:00
Object . defineProperty ( this , 'pollingInterval' , {
get : function ( ) { return pollingInterval ; } ,
set : function ( value ) {
if ( typeof ( value ) !== 'number' || value <= 0 || parseInt ( value ) != value ) {
throw new Error ( 'invalid polling interval' ) ;
}
pollingInterval = value ;
if ( poller ) {
clearInterval ( poller ) ;
poller = setInterval ( doPoll , pollingInterval ) ;
}
}
} ) ;
// @TODO: Add .poller which must be an event emitter with a 'start', 'stop' and 'block' event;
// this will be used once we move to the WebSocket or other alternatives to polling
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
function inheritable ( parent ) {
return function ( child ) {
inherits ( child , parent ) ;
utils . defineProperty ( child , 'inherits' , inheritable ( child ) ) ;
}
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider , 'inherits' , inheritable ( Provider ) ) ;
/ *
function ( child ) {
inherits ( child , Provider ) ;
child . inherits = function ( grandchild ) {
inherits ( grandchild , child )
}
} ) ;
* /
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider , 'getNetwork' , function ( network ) {
if ( typeof ( network ) === 'string' ) {
network = networks [ network ] ;
if ( ! network ) { throw new Error ( 'unknown network' ) ; }
} else if ( network == null ) {
network = networks [ 'homestead' ] ;
}
if ( typeof ( network . chainId ) !== 'number' ) { throw new Error ( 'invalid chainId' ) ; }
return network ;
2017-11-10 03:54:28 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider , 'networks' , networks ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider , 'fetchJSON' , function ( url , json , processFunc ) {
2018-04-14 23:10:26 +03:00
var headers = [ ] ;
if ( typeof ( url ) === 'object' && url . url != null && url . user != null && url . password != null ) {
if ( url . url . substring ( 0 , 6 ) !== 'https:' && url . forceInsecure !== true ) {
errors . throwError ( 'basic authentication requires a secure https url' , errors . INVALID _ARGUMENT , { arg : 'url' , url : url . url , user : url . user , password : '[REDACTED]' } ) ;
}
var authorization = url . user + ':' + url . password ;
headers . push ( {
key : 'Authorization' ,
value : 'Basic ' + utils . base64 . encode ( utils . toUtf8Bytes ( authorization ) )
} ) ;
url = url . url ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
return new Promise ( function ( resolve , reject ) {
var request = new XMLHttpRequest ( ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( json ) {
request . open ( 'POST' , url , true ) ;
2018-04-14 23:10:26 +03:00
headers . push ( { key : 'Content-Type' , value : 'application/json' } ) ;
2018-03-05 03:31:09 +03:00
} else {
request . open ( 'GET' , url , true ) ;
}
2017-11-10 03:54:28 +03:00
2018-04-14 23:10:26 +03:00
headers . forEach ( function ( header ) {
request . setRequestHeader ( header . key , header . value ) ;
} ) ;
2018-03-05 03:31:09 +03:00
request . onreadystatechange = function ( ) {
if ( request . readyState !== 4 ) { return ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
try {
var result = JSON . parse ( request . responseText ) ;
} catch ( error ) {
var jsonError = new Error ( 'invalid json response' ) ;
jsonError . orginialError = error ;
jsonError . responseText = request . responseText ;
2018-04-05 22:48:46 +03:00
jsonError . url = url ;
2018-03-05 03:31:09 +03:00
reject ( jsonError ) ;
return ;
}
if ( processFunc ) {
try {
result = processFunc ( result ) ;
} catch ( error ) {
error . url = url ;
error . body = json ;
error . responseText = request . responseText ;
reject ( error ) ;
return ;
}
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( request . status != 200 ) {
var error = new Error ( 'invalid response - ' + request . status ) ;
error . statusCode = request . statusCode ;
reject ( error ) ;
return ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
resolve ( result ) ;
} ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
request . onerror = function ( error ) {
reject ( error ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
try {
if ( json ) {
request . send ( json ) ;
} else {
request . send ( ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} catch ( error ) {
var connectionError = new Error ( 'connection error' ) ;
connectionError . error = error ;
reject ( connectionError ) ;
}
} ) ;
2017-11-10 03:54:28 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'waitForTransaction' , function ( transactionHash , timeout ) {
var self = this ;
return new Promise ( function ( resolve , reject ) {
var timer = null ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function complete ( transaction ) {
if ( timer ) { clearTimeout ( timer ) ; }
resolve ( transaction ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
self . once ( transactionHash , complete ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( typeof ( timeout ) === 'number' && timeout > 0 ) {
timer = setTimeout ( function ( ) {
self . removeListener ( transactionHash , complete ) ;
reject ( new Error ( 'timeout' ) ) ;
} , timeout ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getBlockNumber' , function ( ) {
try {
return this . perform ( 'getBlockNumber' ) . then ( function ( result ) {
var value = parseInt ( result ) ;
if ( value != result ) { throw new Error ( 'invalid response - getBlockNumber' ) ; }
return value ;
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
}
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getGasPrice' , function ( ) {
try {
return this . perform ( 'getGasPrice' ) . then ( function ( result ) {
return utils . bigNumberify ( result ) ;
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
}
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getBalance' , function ( addressOrName , blockTag ) {
var self = this ;
return this . resolveName ( addressOrName ) . then ( function ( address ) {
var params = { address : address , blockTag : checkBlockTag ( blockTag ) } ;
return self . perform ( 'getBalance' , params ) . then ( function ( result ) {
return utils . bigNumberify ( result ) ;
} ) ;
} ) ;
2017-12-30 22:05:40 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getTransactionCount' , function ( addressOrName , blockTag ) {
var self = this ;
return this . resolveName ( addressOrName ) . then ( function ( address ) {
var params = { address : address , blockTag : checkBlockTag ( blockTag ) } ;
return self . perform ( 'getTransactionCount' , params ) . then ( function ( result ) {
var value = parseInt ( result ) ;
if ( value != result ) { throw new Error ( 'invalid response - getTransactionCount' ) ; }
return value ;
} ) ;
} ) ;
2017-12-30 22:05:40 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getCode' , function ( addressOrName , blockTag ) {
var self = this ;
return this . resolveName ( addressOrName ) . then ( function ( address ) {
var params = { address : address , blockTag : checkBlockTag ( blockTag ) } ;
return self . perform ( 'getCode' , params ) . then ( function ( result ) {
return utils . hexlify ( result ) ;
} ) ;
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getStorageAt' , function ( addressOrName , position , blockTag ) {
var self = this ;
return this . resolveName ( addressOrName ) . then ( function ( address ) {
var params = {
address : address ,
blockTag : checkBlockTag ( blockTag ) ,
2018-03-05 10:52:53 +03:00
position : utils . hexStripZeros ( utils . hexlify ( position ) ) ,
2018-03-05 03:31:09 +03:00
} ;
return self . perform ( 'getStorageAt' , params ) . then ( function ( result ) {
return utils . hexlify ( result ) ;
} ) ;
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'sendTransaction' , function ( signedTransaction ) {
try {
var params = { signedTransaction : utils . hexlify ( signedTransaction ) } ;
return this . perform ( 'sendTransaction' , params ) . then ( function ( result ) {
result = utils . hexlify ( result ) ;
if ( result . length !== 66 ) { throw new Error ( 'invalid response - sendTransaction' ) ; }
return result ;
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
}
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'call' , function ( transaction ) {
var self = this ;
return this . _resolveNames ( transaction , [ 'to' , 'from' ] ) . then ( function ( transaction ) {
var params = { transaction : checkTransactionRequest ( transaction ) } ;
return self . perform ( 'call' , params ) . then ( function ( result ) {
return utils . hexlify ( result ) ;
} ) ;
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'estimateGas' , function ( transaction ) {
var self = this ;
return this . _resolveNames ( transaction , [ 'to' , 'from' ] ) . then ( function ( transaction ) {
var params = { transaction : checkTransactionRequest ( transaction ) } ;
return self . perform ( 'estimateGas' , params ) . then ( function ( result ) {
return utils . bigNumberify ( result ) ;
} ) ;
2017-12-30 22:05:40 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
} ) ;
2017-12-30 22:05:40 +03:00
2018-03-07 02:40:11 +03:00
function stallPromise ( allowNullFunc , executeFunc ) {
return new Promise ( function ( resolve , reject ) {
var attempt = 0 ;
function check ( ) {
executeFunc ( ) . then ( function ( result ) {
// If we have a result, or are allowed null then we're done
if ( result || allowNullFunc ( ) ) {
resolve ( result ) ;
// Otherwise, exponential back-off (up to 10s) our next request
} else {
attempt ++ ;
var timeout = 500 + 250 * parseInt ( Math . random ( ) * ( 1 << attempt ) ) ;
if ( timeout > 10000 ) { timeout = 10000 ; }
setTimeout ( check , timeout ) ;
}
2018-06-28 02:59:08 +03:00
return null ;
2018-03-07 02:40:11 +03:00
} , function ( error ) {
reject ( error ) ;
2018-06-28 02:59:08 +03:00
} ) . catch ( function ( error ) { reject ( error ) ; } ) ;
2018-03-07 02:40:11 +03:00
}
check ( ) ;
} ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getBlock' , function ( blockHashOrBlockTag ) {
2018-03-07 02:40:11 +03:00
var self = this ;
2018-03-05 03:31:09 +03:00
try {
var blockHash = utils . hexlify ( blockHashOrBlockTag ) ;
if ( blockHash . length === 66 ) {
2018-03-07 02:40:11 +03:00
return stallPromise ( function ( ) {
return ( self . _emitted [ 'b:' + blockHash . toLowerCase ( ) ] == null ) ;
} , function ( ) {
return self . perform ( 'getBlock' , { blockHash : blockHash } ) . then ( function ( block ) {
if ( block == null ) { return null ; }
return checkBlock ( block ) ;
} ) ;
2018-03-05 03:31:09 +03:00
} ) ;
}
2018-03-07 02:40:11 +03:00
} catch ( error ) { }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
try {
var blockTag = checkBlockTag ( blockHashOrBlockTag ) ;
2018-03-07 02:40:11 +03:00
return stallPromise ( function ( ) {
if ( utils . isHexString ( blockTag ) ) {
var blockNumber = parseInt ( blockTag . substring ( 2 ) , 16 ) ;
return blockNumber > self . _emitted . block ;
}
return true ;
} , function ( ) {
return self . perform ( 'getBlock' , { blockTag : blockTag } ) . then ( function ( block ) {
if ( block == null ) { return null ; }
return checkBlock ( block ) ;
} ) ;
2018-03-05 03:31:09 +03:00
} ) ;
2018-03-07 02:40:11 +03:00
} catch ( error ) { }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
return Promise . reject ( new Error ( 'invalid block hash or block tag' ) ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getTransaction' , function ( transactionHash ) {
2018-03-07 02:40:11 +03:00
var self = this ;
2018-03-05 03:31:09 +03:00
try {
var params = { transactionHash : checkHash ( transactionHash ) } ;
2018-03-07 02:40:11 +03:00
return stallPromise ( function ( ) {
return ( self . _emitted [ 't:' + transactionHash . toLowerCase ( ) ] == null ) ;
} , function ( ) {
return self . perform ( 'getTransaction' , params ) . then ( function ( result ) {
if ( result != null ) { result = checkTransaction ( result ) ; }
return result ;
} ) ;
2018-03-05 03:31:09 +03:00
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getTransactionReceipt' , function ( transactionHash ) {
2018-03-07 02:40:11 +03:00
var self = this ;
2018-03-05 03:31:09 +03:00
try {
var params = { transactionHash : checkHash ( transactionHash ) } ;
2018-03-07 02:40:11 +03:00
return stallPromise ( function ( ) {
return ( self . _emitted [ 't:' + transactionHash . toLowerCase ( ) ] == null ) ;
} , function ( ) {
return self . perform ( 'getTransactionReceipt' , params ) . then ( function ( result ) {
if ( result != null ) { result = checkTransactionReceipt ( result ) ; }
return result ;
} ) ;
2018-03-05 03:31:09 +03:00
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
2018-01-17 10:51:36 +03:00
}
2018-03-05 03:31:09 +03:00
} ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getLogs' , function ( filter ) {
var self = this ;
return this . _resolveNames ( filter , [ 'address' ] ) . then ( function ( filter ) {
var params = { filter : checkFilter ( filter ) } ;
return self . perform ( 'getLogs' , params ) . then ( function ( result ) {
return arrayOf ( checkLog ) ( result ) ;
} ) ;
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'getEtherPrice' , function ( ) {
try {
return this . perform ( 'getEtherPrice' , { } ) . then ( function ( result ) {
// @TODO: Check valid float
return result ;
} ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
}
} ) ;
2017-11-13 00:39:41 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , '_resolveNames' , function ( object , keys ) {
var promises = [ ] ;
2017-11-13 00:39:41 +03:00
2018-03-05 03:31:09 +03:00
var result = copyObject ( object ) ;
2017-11-13 00:39:41 +03:00
2018-03-05 03:31:09 +03:00
keys . forEach ( function ( key ) {
if ( result [ key ] === undefined ) { return ; }
promises . push ( this . resolveName ( result [ key ] ) . then ( function ( address ) {
result [ key ] = address ;
2018-06-28 02:59:08 +03:00
return null ;
2018-03-05 03:31:09 +03:00
} ) ) ;
} , this ) ;
2017-11-13 00:39:41 +03:00
2018-03-05 03:31:09 +03:00
return Promise . all ( promises ) . then ( function ( ) { return result ; } ) ;
} ) ;
2017-11-13 00:39:41 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , '_getResolver' , function ( name ) {
var nodeHash = utils . namehash ( name ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// keccak256('resolver(bytes32)')
var data = '0x0178b8bf' + nodeHash . substring ( 2 ) ;
var transaction = { to : this . ensAddress , data : data } ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Get the resolver from the blockchain
return this . call ( transaction ) . then ( function ( data ) {
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// extract the address from the data
if ( data . length != 66 ) { return null ; }
return utils . getAddress ( '0x' + data . substring ( 26 ) ) ;
} ) ;
2017-11-10 03:54:28 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'resolveName' , function ( name ) {
// If it is already an address, nothing to resolve
try {
return Promise . resolve ( utils . getAddress ( name ) ) ;
} catch ( error ) { }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( ! this . ensAddress ) { throw new Error ( 'network does not have ENS deployed' ) ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var self = this ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var nodeHash = utils . namehash ( name ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Get the addr from the resovler
return this . _getResolver ( name ) . then ( function ( resolverAddress ) {
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// keccak256('addr(bytes32)')
var data = '0x3b3b57de' + nodeHash . substring ( 2 ) ;
var transaction = { to : resolverAddress , data : data } ;
return self . call ( transaction ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// extract the address from the data
} ) . then ( function ( data ) {
if ( data . length != 66 ) { return null ; }
var address = utils . getAddress ( '0x' + data . substring ( 26 ) ) ;
if ( address === '0x0000000000000000000000000000000000000000' ) { return null ; }
return address ;
} ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'lookupAddress' , function ( address ) {
if ( ! this . ensAddress ) { throw new Error ( 'network does not have ENS deployed' ) ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
address = utils . getAddress ( address ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var name = address . substring ( 2 ) + '.addr.reverse'
var nodehash = utils . namehash ( name ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var self = this ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
return this . _getResolver ( name ) . then ( function ( resolverAddress ) {
if ( ! resolverAddress ) { return null ; }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// keccak('name(bytes32)')
var data = '0x691f3431' + nodehash . substring ( 2 ) ;
var transaction = { to : resolverAddress , data : data } ;
return self . call ( transaction ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} ) . then ( function ( data ) {
// Strip off the "0x"
data = data . substring ( 2 ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
// Strip off the dynamic string pointer (0x20)
if ( data . length < 64 ) { return null ; }
data = data . substring ( 64 ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
if ( data . length < 64 ) { return null ; }
var length = utils . bigNumberify ( '0x' + data . substring ( 0 , 64 ) ) . toNumber ( ) ;
data = data . substring ( 64 ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
if ( 2 * length > data . length ) { return null ; }
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
var name = utils . toUtf8String ( '0x' + data . substring ( 0 , 2 * length ) ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
// Make sure the reverse record matches the foward record
return self . resolveName ( name ) . then ( function ( addr ) {
if ( addr != address ) { return null ; }
return name ;
} ) ;
2017-12-30 22:05:40 +03:00
} ) ;
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'doPoll' , function ( ) {
2017-12-30 22:05:40 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'perform' , function ( method , params ) {
return Promise . reject ( new Error ( 'not implemented - ' + method ) ) ;
2018-01-17 10:51:36 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
function recurse ( object , convertFunc ) {
if ( Array . isArray ( object ) ) {
var result = [ ] ;
object . forEach ( function ( object ) {
result . push ( recurse ( object , convertFunc ) ) ;
} ) ;
return result ;
}
return convertFunc ( object ) ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
function getEventString ( object ) {
try {
return 'address:' + utils . getAddress ( object ) ;
} catch ( error ) { }
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
if ( object === 'block' ) {
return 'block' ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( object === 'pending' ) {
return 'pending' ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( utils . isHexString ( object ) ) {
if ( object . length === 66 ) {
return 'tx:' + object ;
}
} else if ( Array . isArray ( object ) ) {
object = recurse ( object , function ( object ) {
if ( object == null ) { object = '0x' ; }
return object ;
} ) ;
try {
return 'topic:' + utils . RLP . encode ( object ) ;
} catch ( error ) {
console . log ( error ) ;
}
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
throw new Error ( 'invalid event - ' + object ) ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
function parseEventString ( string ) {
if ( string . substring ( 0 , 3 ) === 'tx:' ) {
return { type : 'transaction' , hash : string . substring ( 3 ) } ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( string === 'block' ) {
return { type : 'block' } ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( string === 'pending' ) {
return { type : 'pending' } ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( string . substring ( 0 , 8 ) === 'address:' ) {
return { type : 'address' , address : string . substring ( 8 ) } ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
} else if ( string . substring ( 0 , 6 ) === 'topic:' ) {
try {
var object = utils . RLP . decode ( string . substring ( 6 ) ) ;
object = recurse ( object , function ( object ) {
if ( object === '0x' ) { object = null ; }
return object ;
} ) ;
return { type : 'topic' , topic : object } ;
} catch ( error ) {
console . log ( error ) ;
}
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
throw new Error ( 'invalid event string' ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , '_startPending' , function ( ) {
console . log ( 'WARNING: this provider does not support pending events' ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , '_stopPending' , function ( ) {
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'on' , function ( eventName , listener ) {
var key = getEventString ( eventName ) ;
if ( ! this . _events [ key ] ) { this . _events [ key ] = [ ] ; }
this . _events [ key ] . push ( { eventName : eventName , listener : listener , type : 'on' } ) ;
if ( key === 'pending' ) { this . _startPending ( ) ; }
this . polling = true ;
} ) ;
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'once' , function ( eventName , listener ) {
var key = getEventString ( eventName ) ;
if ( ! this . _events [ key ] ) { this . _events [ key ] = [ ] ; }
this . _events [ key ] . push ( { eventName : eventName , listener : listener , type : 'once' } ) ;
if ( key === 'pending' ) { this . _startPending ( ) ; }
this . polling = true ;
} ) ;
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'emit' , function ( eventName ) {
var key = getEventString ( eventName ) ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
var args = Array . prototype . slice . call ( arguments , 1 ) ;
var listeners = this . _events [ key ] ;
if ( ! listeners ) { return ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
for ( var i = 0 ; i < listeners . length ; i ++ ) {
var listener = listeners [ i ] ;
if ( listener . type === 'once' ) {
listeners . splice ( i , 1 ) ;
i -- ;
}
2017-05-22 03:38:41 +03:00
2017-04-05 23:53:29 +03:00
try {
2018-03-05 03:31:09 +03:00
listener . listener . apply ( this , args ) ;
2017-04-05 23:53:29 +03:00
} catch ( error ) {
2018-03-05 03:31:09 +03:00
console . log ( 'Event Listener Error: ' + error . message ) ;
2017-04-05 23:53:29 +03:00
}
}
2018-03-05 03:31:09 +03:00
if ( listeners . length === 0 ) {
delete this . _events [ key ] ;
if ( key === 'pending' ) { this . _stopPending ( ) ; }
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( this . listenerCount ( ) === 0 ) { this . polling = false ; }
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'listenerCount' , function ( eventName ) {
if ( ! eventName ) {
var result = 0 ;
for ( var key in this . _events ) {
result += this . _events [ key ] . length ;
}
2017-04-05 23:53:29 +03:00
return result ;
}
2018-03-05 03:31:09 +03:00
var listeners = this . _events [ getEventString ( eventName ) ] ;
if ( ! listeners ) { return 0 ; }
return listeners . length ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'listeners' , function ( eventName ) {
var listeners = this . _events [ getEventString ( eventName ) ] ;
if ( ! listeners ) { return 0 ; }
var result = [ ] ;
for ( var i = 0 ; i < listeners . length ; i ++ ) {
result . push ( listeners [ i ] . listener ) ;
2017-12-05 11:25:08 +03:00
}
2018-03-05 03:31:09 +03:00
return result ;
} ) ;
2017-12-05 11:25:08 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider . prototype , 'removeAllListeners' , function ( eventName ) {
delete this . _events [ getEventString ( eventName ) ] ;
if ( this . listenerCount ( ) === 0 ) { this . polling = false ; }
} ) ;
utils . defineProperty ( Provider . prototype , 'removeListener' , function ( eventName , listener ) {
var eventNameString = getEventString ( eventName ) ;
var listeners = this . _events [ eventNameString ] ;
if ( ! listeners ) { return 0 ; }
for ( var i = 0 ; i < listeners . length ; i ++ ) {
if ( listeners [ i ] . listener === listener ) {
listeners . splice ( i , 1 ) ;
break ;
}
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( listeners . length === 0 ) {
this . removeAllListeners ( eventName ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
utils . defineProperty ( Provider , '_formatters' , {
checkTransactionResponse : checkTransaction
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
module . exports = Provider ;
2017-04-05 23:53:29 +03:00
2018-04-14 23:10:26 +03:00
} , { "../utils/address" : 15 , "../utils/base64" : 17 , "../utils/bignumber" : 16 , "../utils/contract-address" : 18 , "../utils/convert" : 19 , "../utils/errors" : 21 , "../utils/namehash" : 23 , "../utils/properties" : 24 , "../utils/rlp" : 25 , "../utils/utf8" : 27 , "./networks.json" : 12 , "inherits" : 3 , "xmlhttprequest" : 6 } ] , 14 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var Provider = require ( './provider' ) ;
var JsonRpcProvider = require ( './json-rpc-provider' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var utils = ( function ( ) {
return {
defineProperty : require ( '../utils/properties' ) . defineProperty ,
}
} ) ( ) ;
2017-04-05 23:53:29 +03:00
2018-04-14 01:21:48 +03:00
var errors = require ( '../utils/errors' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
/ *
@ TODO
utils . defineProperty ( Web3Signer , 'onchange' , {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} ) ;
* /
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function Web3Provider ( web3Provider , network ) {
2018-04-14 01:21:48 +03:00
errors . checkNew ( this , Web3Provider ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// HTTP has a host; IPC has a path.
var url = web3Provider . host || web3Provider . path || 'unknown' ;
2017-11-19 02:58:53 +03:00
2018-04-14 01:21:48 +03:00
if ( network == null ) { network = 'homestead' ; }
2018-03-05 03:31:09 +03:00
JsonRpcProvider . call ( this , url , network ) ;
utils . defineProperty ( this , '_web3Provider' , web3Provider ) ;
}
JsonRpcProvider . inherits ( Web3Provider ) ;
2017-04-05 23:53:29 +03:00
2018-04-14 01:21:48 +03:00
utils . defineProperty ( Web3Provider . prototype , 'send' , function ( method , params ) {
2017-04-05 23:53:29 +03:00
2018-04-14 01:21:48 +03:00
// Metamask complains about eth_sign (and on some versions hangs)
if ( method == 'eth_sign' && this . _web3Provider . isMetaMask ) {
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
method = 'personal_sign' ;
params = [ params [ 1 ] , params [ 0 ] ] ;
}
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var provider = this . _web3Provider ;
return new Promise ( function ( resolve , reject ) {
var request = {
method : method ,
params : params ,
id : 42 ,
jsonrpc : "2.0"
} ;
provider . sendAsync ( request , function ( error , result ) {
if ( error ) {
reject ( error ) ;
return ;
}
if ( result . error ) {
var error = new Error ( result . error . message ) ;
error . code = result . error . code ;
error . data = result . error . data ;
reject ( error ) ;
return ;
}
resolve ( result . result ) ;
} ) ;
} ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
module . exports = Web3Provider ;
2017-04-05 23:53:29 +03:00
2018-04-14 23:10:26 +03:00
} , { "../utils/errors" : 21 , "../utils/properties" : 24 , "./json-rpc-provider" : 11 , "./provider" : 13 } ] , 15 : [ function ( require , module , exports ) {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var BN = require ( 'bn.js' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var convert = require ( './convert' ) ;
var throwError = require ( './throw-error' ) ;
var keccak256 = require ( './keccak256' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function getChecksumAddress ( address ) {
if ( typeof ( address ) !== 'string' || ! address . match ( /^0x[0-9A-Fa-f]{40}$/ ) ) {
throwError ( 'invalid address' , { input : address } ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
address = address . toLowerCase ( ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
var hashed = address . substring ( 2 ) . split ( '' ) ;
for ( var i = 0 ; i < hashed . length ; i ++ ) {
hashed [ i ] = hashed [ i ] . charCodeAt ( 0 ) ;
}
hashed = convert . arrayify ( keccak256 ( hashed ) ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
address = address . substring ( 2 ) . split ( '' ) ;
for ( var i = 0 ; i < 40 ; i += 2 ) {
if ( ( hashed [ i >> 1 ] >> 4 ) >= 8 ) {
address [ i ] = address [ i ] . toUpperCase ( ) ;
}
if ( ( hashed [ i >> 1 ] & 0x0f ) >= 8 ) {
address [ i + 1 ] = address [ i + 1 ] . toUpperCase ( ) ;
}
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
return '0x' + address . join ( '' ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
// Shims for environments that are missing some required constants and functions
var MAX _SAFE _INTEGER = 0x1fffffffffffff ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function log10 ( x ) {
if ( Math . log10 ) { return Math . log10 ( x ) ; }
return Math . log ( x ) / Math . LN10 ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
// See: https://en.wikipedia.org/wiki/International_Bank_Account_Number
var ibanChecksum = ( function ( ) {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// Create lookup table
var ibanLookup = { } ;
for ( var i = 0 ; i < 10 ; i ++ ) { ibanLookup [ String ( i ) ] = String ( i ) ; }
for ( var i = 0 ; i < 26 ; i ++ ) { ibanLookup [ String . fromCharCode ( 65 + i ) ] = String ( 10 + i ) ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// How many decimal digits can we process? (for 64-bit float, this is 15)
var safeDigits = Math . floor ( log10 ( MAX _SAFE _INTEGER ) ) ;
return function ( address ) {
address = address . toUpperCase ( ) ;
address = address . substring ( 4 ) + address . substring ( 0 , 2 ) + '00' ;
2017-11-19 02:58:53 +03:00
2018-03-05 03:31:09 +03:00
var expanded = address . split ( '' ) ;
for ( var i = 0 ; i < expanded . length ; i ++ ) {
expanded [ i ] = ibanLookup [ expanded [ i ] ] ;
2017-11-10 03:54:28 +03:00
}
2018-03-05 03:31:09 +03:00
expanded = expanded . join ( '' ) ;
// Javascript can handle integers safely up to 15 (decimal) digits
while ( expanded . length >= safeDigits ) {
var block = expanded . substring ( 0 , safeDigits ) ;
expanded = parseInt ( block , 10 ) % 97 + expanded . substring ( block . length ) ;
2017-11-10 03:54:28 +03:00
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var checksum = String ( 98 - ( parseInt ( expanded , 10 ) % 97 ) ) ;
while ( checksum . length < 2 ) { checksum = '0' + checksum ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
return checksum ;
} ;
} ) ( ) ;
function getAddress ( address , icapFormat ) {
var result = null ;
if ( typeof ( address ) !== 'string' ) {
throwError ( 'invalid address' , { input : address } ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( address . match ( /^(0x)?[0-9a-fA-F]{40}$/ ) ) {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// Missing the 0x prefix
if ( address . substring ( 0 , 2 ) !== '0x' ) { address = '0x' + address ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
result = getChecksumAddress ( address ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// It is a checksummed address with a bad checksum
if ( address . match ( /([A-F].*[a-f])|([a-f].*[A-F])/ ) && result !== address ) {
throwError ( 'invalid address checksum' , { input : address , expected : result } ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// Maybe ICAP? (we only support direct mode)
} else if ( address . match ( /^XE[0-9]{2}[0-9A-Za-z]{30,31}$/ ) ) {
2017-12-05 11:25:08 +03:00
2018-03-05 03:31:09 +03:00
// It is an ICAP address with a bad checksum
if ( address . substring ( 2 , 4 ) !== ibanChecksum ( address ) ) {
throwError ( 'invalid address icap checksum' , { input : address } ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
result = ( new BN ( address . substring ( 4 ) , 36 ) ) . toString ( 16 ) ;
while ( result . length < 40 ) { result = '0' + result ; }
result = getChecksumAddress ( '0x' + result ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else {
throwError ( 'invalid address' , { input : address } ) ;
}
if ( icapFormat ) {
var base36 = ( new BN ( result . substring ( 2 ) , 16 ) ) . toString ( 36 ) . toUpperCase ( ) ;
while ( base36 . length < 30 ) { base36 = '0' + base36 ; }
return 'XE' + ibanChecksum ( 'XE00' + base36 ) + base36 ;
}
return result ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
module . exports = {
getAddress : getAddress ,
2017-04-05 23:53:29 +03:00
}
2018-04-14 23:10:26 +03:00
} , { "./convert" : 19 , "./keccak256" : 22 , "./throw-error" : 26 , "bn.js" : 1 } ] , 16 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
/ * *
* BigNumber
*
* A wrapper around the BN . js object . In the future we can swap out
* the underlying BN . js library for something smaller .
* /
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var BN = require ( 'bn.js' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var defineProperty = require ( './properties' ) . defineProperty ;
var convert = require ( './convert' ) ;
var throwError = require ( './throw-error' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function BigNumber ( value ) {
if ( ! ( this instanceof BigNumber ) ) { throw new Error ( 'missing new' ) ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( convert . isHexString ( value ) ) {
if ( value == '0x' ) { value = '0x0' ; }
value = new BN ( value . substring ( 2 ) , 16 ) ;
} else if ( typeof ( value ) === 'string' && value [ 0 ] === '-' && convert . isHexString ( value . substring ( 1 ) ) ) {
value = ( new BN ( value . substring ( 3 ) , 16 ) ) . mul ( BigNumber . constantNegativeOne . _bn ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( typeof ( value ) === 'string' && value . match ( /^-?[0-9]*$/ ) ) {
if ( value == '' ) { value = '0' ; }
value = new BN ( value ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( typeof ( value ) === 'number' && parseInt ( value ) == value ) {
value = new BN ( value ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( BN . isBN ( value ) ) {
//value = value
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( isBigNumber ( value ) ) {
value = value . _bn ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else if ( convert . isArrayish ( value ) ) {
value = new BN ( convert . hexlify ( value ) . substring ( 2 ) , 16 ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
} else {
throwError ( 'invalid BigNumber value' , { input : value } ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( this , '_bn' , value ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber , 'constantNegativeOne' , bigNumberify ( - 1 ) ) ;
defineProperty ( BigNumber , 'constantZero' , bigNumberify ( 0 ) ) ;
defineProperty ( BigNumber , 'constantOne' , bigNumberify ( 1 ) ) ;
defineProperty ( BigNumber , 'constantTwo' , bigNumberify ( 2 ) ) ;
defineProperty ( BigNumber , 'constantWeiPerEther' , bigNumberify ( new BN ( '1000000000000000000' ) ) ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'fromTwos' , function ( value ) {
return new BigNumber ( this . _bn . fromTwos ( value ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'toTwos' , function ( value ) {
return new BigNumber ( this . _bn . toTwos ( value ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'add' , function ( other ) {
return new BigNumber ( this . _bn . add ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'sub' , function ( other ) {
return new BigNumber ( this . _bn . sub ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'div' , function ( other ) {
return new BigNumber ( this . _bn . div ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'mul' , function ( other ) {
return new BigNumber ( this . _bn . mul ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-05-11 02:09:58 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'mod' , function ( other ) {
return new BigNumber ( this . _bn . mod ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'pow' , function ( other ) {
return new BigNumber ( this . _bn . pow ( bigNumberify ( other ) . _bn ) ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'maskn' , function ( value ) {
return new BigNumber ( this . _bn . maskn ( value ) ) ;
} ) ;
defineProperty ( BigNumber . prototype , 'eq' , function ( other ) {
return this . _bn . eq ( bigNumberify ( other ) . _bn ) ;
2017-04-05 23:53:29 +03:00
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'lt' , function ( other ) {
return this . _bn . lt ( bigNumberify ( other ) . _bn ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'lte' , function ( other ) {
return this . _bn . lte ( bigNumberify ( other ) . _bn ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'gt' , function ( other ) {
return this . _bn . gt ( bigNumberify ( other ) . _bn ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'gte' , function ( other ) {
return this . _bn . gte ( bigNumberify ( other ) . _bn ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'isZero' , function ( ) {
return this . _bn . isZero ( ) ;
} ) ;
2017-11-10 03:54:28 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'toNumber' , function ( base ) {
return this . _bn . toNumber ( ) ;
2017-04-05 23:53:29 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'toString' , function ( ) {
//return this._bn.toString(base || 10);
return this . _bn . toString ( 10 ) ;
} ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
defineProperty ( BigNumber . prototype , 'toHexString' , function ( ) {
var hex = this . _bn . toString ( 16 ) ;
if ( hex . length % 2 ) { hex = '0' + hex ; }
return '0x' + hex ;
} ) ;
2017-11-10 03:54:28 +03:00
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function isBigNumber ( value ) {
return ( value . _bn && value . _bn . mod ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function bigNumberify ( value ) {
if ( isBigNumber ( value ) ) { return value ; }
return new BigNumber ( value ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
module . exports = {
isBigNumber : isBigNumber ,
bigNumberify : bigNumberify ,
BigNumber : BigNumber
} ;
2017-04-05 23:53:29 +03:00
2018-04-14 23:10:26 +03:00
} , { "./convert" : 19 , "./properties" : 24 , "./throw-error" : 26 , "bn.js" : 1 } ] , 17 : [ function ( require , module , exports ) {
'use strict' ;
var convert = require ( './convert' ) ;
module . exports = {
decode : function ( textData ) {
textData = atob ( textData ) ;
var data = [ ] ;
for ( var i = 0 ; i < textData . length ; i ++ ) {
data . push ( textData . charCodeAt ( i ) ) ;
}
return convert . arrayify ( data ) ;
} ,
encode : function ( data ) {
data = convert . arrayify ( data ) ;
var textData = '' ;
for ( var i = 0 ; i < data . length ; i ++ ) {
textData += String . fromCharCode ( data [ i ] ) ;
}
return btoa ( textData ) ;
}
} ;
} , { "./convert" : 19 } ] , 18 : [ function ( require , module , exports ) {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var getAddress = require ( './address' ) . getAddress ;
var convert = require ( './convert' ) ;
var keccak256 = require ( './keccak256' ) ;
var RLP = require ( './rlp' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
function getContractAddress ( transaction ) {
if ( ! transaction . from ) { throw new Error ( 'missing from address' ) ; }
var nonce = transaction . nonce ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
return getAddress ( '0x' + keccak256 ( RLP . encode ( [
getAddress ( transaction . from ) ,
convert . stripZeros ( convert . hexlify ( nonce , 'nonce' ) )
] ) ) . substring ( 26 ) ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
module . exports = {
getContractAddress : getContractAddress ,
}
2017-04-05 23:53:29 +03:00
2018-04-14 23:10:26 +03:00
} , { "./address" : 15 , "./convert" : 19 , "./keccak256" : 22 , "./rlp" : 25 } ] , 19 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
/ * *
* Conversion Utilities
*
* /
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var defineProperty = require ( './properties.js' ) . defineProperty ;
2018-04-13 01:31:02 +03:00
var errors = require ( './errors' ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function addSlice ( array ) {
if ( array . slice ) { return array ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
array . slice = function ( ) {
var args = Array . prototype . slice . call ( arguments ) ;
return new Uint8Array ( Array . prototype . slice . apply ( array , args ) ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
return array ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function isArrayish ( value ) {
if ( ! value || parseInt ( value . length ) != value . length || typeof ( value ) === 'string' ) {
return false ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
for ( var i = 0 ; i < value . length ; i ++ ) {
var v = value [ i ] ;
if ( v < 0 || v >= 256 || parseInt ( v ) != v ) {
return false ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
return true ;
}
2017-04-05 23:53:29 +03:00
2018-04-13 01:31:02 +03:00
function arrayify ( value ) {
if ( value == null ) {
errors . throwError ( 'cannot convert null value to array' , errors . INVALID _ARGUMENT , { arg : 'value' , value : value } ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( value && value . toHexString ) {
value = value . toHexString ( ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( isHexString ( value ) ) {
value = value . substring ( 2 ) ;
if ( value . length % 2 ) { value = '0' + value ; }
var result = [ ] ;
for ( var i = 0 ; i < value . length ; i += 2 ) {
result . push ( parseInt ( value . substr ( i , 2 ) , 16 ) ) ;
}
return addSlice ( new Uint8Array ( result ) ) ;
2018-04-13 01:31:02 +03:00
} else if ( typeof ( value ) === 'string' ) {
if ( value . match ( /^[0-9a-fA-F]*$/ ) ) {
errors . throwError ( 'hex string must have 0x prefix' , errors . INVALID _ARGUMENT , { arg : 'value' , value : value } ) ;
}
errors . throwError ( 'invalid hexidecimal string' , errors . INVALID _ARGUMENT , { arg : 'value' , value : value } ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( isArrayish ( value ) ) {
return addSlice ( new Uint8Array ( value ) ) ;
}
2017-04-05 23:53:29 +03:00
2018-04-13 01:31:02 +03:00
errors . throwError ( 'invalid arrayify value' , { arg : 'value' , value : value , type : typeof ( value ) } ) ;
2018-03-05 03:31:09 +03:00
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function concat ( objects ) {
var arrays = [ ] ;
var length = 0 ;
for ( var i = 0 ; i < objects . length ; i ++ ) {
var object = arrayify ( objects [ i ] )
arrays . push ( object ) ;
length += object . length ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var result = new Uint8Array ( length ) ;
var offset = 0 ;
for ( var i = 0 ; i < arrays . length ; i ++ ) {
result . set ( arrays [ i ] , offset ) ;
offset += arrays [ i ] . length ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
return addSlice ( result ) ;
}
function stripZeros ( value ) {
value = arrayify ( value ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( value . length === 0 ) { return value ; }
// Find the first non-zero entry
var start = 0 ;
while ( value [ start ] === 0 ) { start ++ }
// If we started with zeros, strip them
if ( start ) {
value = value . slice ( start ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
return value ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function padZeros ( value , length ) {
value = arrayify ( value ) ;
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( length < value . length ) { throw new Error ( 'cannot pad' ) ; }
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var result = new Uint8Array ( length ) ;
result . set ( value , length - value . length ) ;
return addSlice ( result ) ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
function isHexString ( value , length ) {
if ( typeof ( value ) !== 'string' || ! value . match ( /^0x[0-9A-Fa-f]*$/ ) ) {
return false
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( length && value . length !== 2 + 2 * length ) { return false ; }
return true ;
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var HexCharacters = '0123456789abcdef' ;
2017-04-05 23:53:29 +03:00
2018-04-13 01:31:02 +03:00
function hexlify ( value ) {
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
if ( value && value . toHexString ) {
return value . toHexString ( ) ;
2017-04-05 23:53:29 +03:00
}
2018-03-05 03:31:09 +03:00
if ( typeof ( value ) === 'number' ) {
if ( value < 0 ) {
2018-04-13 01:31:02 +03:00
errors . throwError ( 'cannot hexlify negative value' , errors . INVALID _ARG , { arg : 'value' , value : value } ) ;
2018-03-05 03:31:09 +03:00
}
2017-04-05 23:53:29 +03:00
2018-03-05 03:31:09 +03:00
var hex = '' ;
while ( value ) {
hex = HexCharacters [ value & 0x0f ] + hex ;
value = parseInt ( value / 16 ) ;
}
2017-02-27 08:09:47 +03:00
2018-03-05 03:31:09 +03:00
if ( hex . length ) {
if ( hex . length % 2 ) { hex = '0' + hex ; }
return '0x' + hex ;
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
return '0x00' ;
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
if ( isHexString ( value ) ) {
if ( value . length % 2 ) {
value = '0x0' + value . substring ( 2 ) ;
}
return value ;
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
if ( isArrayish ( value ) ) {
var result = [ ] ;
for ( var i = 0 ; i < value . length ; i ++ ) {
var v = value [ i ] ;
result . push ( HexCharacters [ ( v & 0xf0 ) >> 4 ] + HexCharacters [ v & 0x0f ] ) ;
}
return '0x' + result . join ( '' ) ;
}
2017-05-22 03:38:41 +03:00
2018-04-13 01:31:02 +03:00
errors . throwError ( 'invalid hexlify value' , { arg : 'value' , value : value } ) ;
2018-03-05 03:31:09 +03:00
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
function hexStripZeros ( value ) {
while ( value . length > 3 && value . substring ( 0 , 3 ) === '0x0' ) {
value = '0x' + value . substring ( 3 ) ;
}
return value ;
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
function hexZeroPad ( value , length ) {
while ( value . length < 2 * length + 2 ) {
value = '0x0' + value . substring ( 2 ) ;
}
return value ;
}
2017-05-22 03:38:41 +03:00
2018-04-13 01:31:02 +03:00
/ * @ T O D O : A d d s o m e t h i n g l i k e t h i s t o m a k e s l i c i n g c o d e e a s i e r t o u n d e r s t a n d
function hexSlice ( hex , start , end ) {
hex = hexlify ( hex ) ;
return '0x' + hex . substring ( 2 + start * 2 , 2 + end * 2 ) ;
}
* /
function splitSignature ( signature ) {
signature = arrayify ( signature ) ;
if ( signature . length !== 65 ) {
throw new Error ( 'invalid signature' ) ;
}
var v = signature [ 64 ] ;
if ( v !== 27 && v !== 28 ) {
v = 27 + ( v % 2 ) ;
}
return {
r : hexlify ( signature . slice ( 0 , 32 ) ) ,
s : hexlify ( signature . slice ( 32 , 64 ) ) ,
v : v
}
}
2018-03-05 03:31:09 +03:00
module . exports = {
arrayify : arrayify ,
isArrayish : isArrayish ,
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
concat : concat ,
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
padZeros : padZeros ,
stripZeros : stripZeros ,
2017-10-20 22:44:54 +03:00
2018-04-13 01:31:02 +03:00
splitSignature : splitSignature ,
2018-03-05 03:31:09 +03:00
hexlify : hexlify ,
isHexString : isHexString ,
hexStripZeros : hexStripZeros ,
hexZeroPad : hexZeroPad ,
} ;
2018-01-11 00:42:36 +03:00
2018-04-14 23:10:26 +03:00
} , { "./errors" : 21 , "./properties.js" : 24 } ] , 20 : [ function ( require , module , exports ) {
2018-04-14 01:21:48 +03:00
module . exports = undefined ;
2018-04-14 23:10:26 +03:00
} , { } ] , 21 : [ function ( require , module , exports ) {
2018-04-13 01:31:02 +03:00
'use strict' ;
var defineProperty = require ( './properties' ) . defineProperty ;
var codes = { } ;
[
// Unknown Error
'UNKNOWN_ERROR' ,
2018-04-14 01:21:48 +03:00
// Not implemented
'NOT_IMPLEMENTED' ,
2018-04-13 01:31:02 +03:00
// Missing new operator to an object
// - name: The name of the class
'MISSING_NEW' ,
2018-04-14 01:21:48 +03:00
2018-04-17 04:42:17 +03:00
// Call exception
'CALL_EXCEPTION' ,
// Response from a server was invalid
// - response: The body of the response
//'BAD_RESPONSE',
2018-04-14 01:21:48 +03:00
// Invalid argument (e.g. type) to a function:
2018-04-13 01:31:02 +03:00
// - arg: The argument name that was invalid
2018-04-17 04:42:17 +03:00
// - value: The value of the argument
// - type: The type of the argument
// - expected: What was expected
2018-04-14 01:21:48 +03:00
'INVALID_ARGUMENT' ,
// Missing argument to a function:
// - arg: The argument name that is required
2018-04-17 04:42:17 +03:00
// - count: The number of arguments received
// - expectedCount: The number of arguments expected
2018-04-14 01:21:48 +03:00
'MISSING_ARGUMENT' ,
// Too many arguments
2018-04-17 04:42:17 +03:00
// - count: The number of arguments received
// - expectedCount: The number of arguments expected
2018-04-14 01:21:48 +03:00
'UNEXPECTED_ARGUMENT' ,
// Unsupported operation
// - operation
'UNSUPPORTED_OPERATION' ,
2018-04-13 01:31:02 +03:00
] . forEach ( function ( code ) {
defineProperty ( codes , code , code ) ;
} ) ;
defineProperty ( codes , 'throwError' , function ( message , code , params ) {
if ( ! code ) { code = codes . UNKNOWN _ERROR ; }
if ( ! params ) { params = { } ; }
var messageDetails = [ ] ;
Object . keys ( params ) . forEach ( function ( key ) {
2018-04-17 04:42:17 +03:00
try {
messageDetails . push ( key + '=' + JSON . stringify ( params [ key ] ) ) ;
} catch ( error ) {
messageDetails . push ( key + '=' + JSON . stringify ( params [ key ] . toString ( ) ) ) ;
}
2018-04-13 01:31:02 +03:00
} ) ;
var reason = message ;
if ( messageDetails . length ) {
message += ' (' + messageDetails . join ( ', ' ) + ')' ;
}
var error = new Error ( message ) ;
error . reason = reason ;
error . code = code
Object . keys ( params ) . forEach ( function ( key ) {
error [ key ] = params [ key ] ;
} ) ;
throw error ;
} ) ;
defineProperty ( codes , 'checkNew' , function ( self , kind ) {
if ( ! ( self instanceof kind ) ) {
codes . throwError ( 'missing new' , codes . MISSING _NEW , { name : kind . name } ) ;
}
} ) ;
module . exports = codes ;
2018-04-14 23:10:26 +03:00
} , { "./properties" : 24 } ] , 22 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
var sha3 = require ( 'js-sha3' ) ;
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
var convert = require ( './convert.js' ) ;
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
function keccak256 ( data ) {
data = convert . arrayify ( data ) ;
return '0x' + sha3 . keccak _256 ( data ) ;
}
2017-05-22 03:38:41 +03:00
2018-03-05 03:31:09 +03:00
module . exports = keccak256 ;
2017-05-22 03:38:41 +03:00
2018-04-14 23:10:26 +03:00
} , { "./convert.js" : 19 , "js-sha3" : 4 } ] , 23 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2018-01-11 00:42:36 +03:00
2018-03-05 03:31:09 +03:00
var convert = require ( './convert' ) ;
var utf8 = require ( './utf8' ) ;
var keccak256 = require ( './keccak256' ) ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
var Zeros = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ;
var Partition = new RegExp ( "^((.*)\\.)?([^.]+)$" ) ;
var UseSTD3ASCIIRules = new RegExp ( "^[a-z0-9.-]*$" ) ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
function namehash ( name , depth ) {
name = name . toLowerCase ( ) ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
// Supporting the full UTF-8 space requires additional (and large)
// libraries, so for now we simply do not support them.
// It should be fairly easy in the future to support systems with
// String.normalize, but that is future work.
if ( ! name . match ( UseSTD3ASCIIRules ) ) {
throw new Error ( 'contains invalid UseSTD3ASCIIRules characters' ) ;
}
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
var result = Zeros ;
var processed = 0 ;
while ( name . length && ( ! depth || processed < depth ) ) {
var partition = name . match ( Partition ) ;
var label = utf8 . toUtf8Bytes ( partition [ 3 ] ) ;
result = keccak256 ( convert . concat ( [ result , keccak256 ( label ) ] ) ) ;
name = partition [ 2 ] || '' ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
processed ++ ;
}
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
return convert . hexlify ( result ) ;
}
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
module . exports = namehash ;
2017-10-20 22:44:54 +03:00
2018-04-14 23:10:26 +03:00
} , { "./convert" : 19 , "./keccak256" : 22 , "./utf8" : 27 } ] , 24 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
function defineProperty ( object , name , value ) {
Object . defineProperty ( object , name , {
enumerable : true ,
value : value ,
writable : false ,
} ) ;
}
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
function defineFrozen ( object , name , value ) {
var frozen = JSON . stringify ( value ) ;
Object . defineProperty ( object , name , {
enumerable : true ,
get : function ( ) { return JSON . parse ( frozen ) ; }
2017-10-20 22:44:54 +03:00
} ) ;
2018-03-05 03:31:09 +03:00
}
2017-10-20 22:44:54 +03:00
2018-03-05 03:31:09 +03:00
module . exports = {
defineFrozen : defineFrozen ,
defineProperty : defineProperty ,
} ;
2017-04-05 01:53:59 +03:00
2018-04-14 23:10:26 +03:00
} , { } ] , 25 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
//See: https://github.com/ethereum/wiki/wiki/RLP
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
var convert = require ( './convert.js' ) ;
function arrayifyInteger ( value ) {
var result = [ ] ;
while ( value ) {
result . unshift ( value & 0xff ) ;
value >>= 8 ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
return result ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
function unarrayifyInteger ( data , offset , length ) {
var result = 0 ;
for ( var i = 0 ; i < length ; i ++ ) {
result = ( result * 256 ) + data [ offset + i ] ;
}
return result ;
}
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
function _encode ( object ) {
if ( Array . isArray ( object ) ) {
var payload = [ ] ;
object . forEach ( function ( child ) {
payload = payload . concat ( _encode ( child ) ) ;
2017-04-05 23:53:29 +03:00
} ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
if ( payload . length <= 55 ) {
payload . unshift ( 0xc0 + payload . length )
return payload ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
var length = arrayifyInteger ( payload . length ) ;
length . unshift ( 0xf7 + length . length ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
return length . concat ( payload ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
} else {
object = [ ] . slice . call ( convert . arrayify ( object ) ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
if ( object . length === 1 && object [ 0 ] <= 0x7f ) {
return object ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
} else if ( object . length <= 55 ) {
object . unshift ( 0x80 + object . length ) ;
return object
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
var length = arrayifyInteger ( object . length ) ;
length . unshift ( 0xb7 + length . length ) ;
return length . concat ( object ) ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
}
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
function encode ( object ) {
return convert . hexlify ( _encode ( object ) ) ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
function _decodeChildren ( data , offset , childOffset , length ) {
var result = [ ] ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
while ( childOffset < offset + 1 + length ) {
var decoded = _decode ( data , childOffset ) ;
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
result . push ( decoded . result ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
childOffset += decoded . consumed ;
if ( childOffset > offset + 1 + length ) {
throw new Error ( 'invalid rlp' ) ;
}
}
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
return { consumed : ( 1 + length ) , result : result } ;
}
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
// returns { consumed: number, result: Object }
function _decode ( data , offset ) {
if ( data . length === 0 ) { throw new Error ( 'invalid rlp data' ) ; }
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
// Array with extra length prefix
if ( data [ offset ] >= 0xf8 ) {
var lengthLength = data [ offset ] - 0xf7 ;
if ( offset + 1 + lengthLength > data . length ) {
throw new Error ( 'too short' ) ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
var length = unarrayifyInteger ( data , offset + 1 , lengthLength ) ;
if ( offset + 1 + lengthLength + length > data . length ) {
throw new Error ( 'to short' ) ;
2017-04-05 01:53:59 +03:00
}
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
return _decodeChildren ( data , offset , offset + 1 + lengthLength , lengthLength + length ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
} else if ( data [ offset ] >= 0xc0 ) {
var length = data [ offset ] - 0xc0 ;
if ( offset + 1 + length > data . length ) {
throw new Error ( 'invalid rlp data' ) ;
2017-04-05 01:53:59 +03:00
}
2018-03-05 03:31:09 +03:00
return _decodeChildren ( data , offset , offset + 1 , length ) ;
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
} else if ( data [ offset ] >= 0xb8 ) {
var lengthLength = data [ offset ] - 0xb7 ;
if ( offset + 1 + lengthLength > data . length ) {
throw new Error ( 'invalid rlp data' ) ;
2017-04-05 01:53:59 +03:00
}
2017-12-30 22:05:40 +03:00
2018-03-05 03:31:09 +03:00
var length = unarrayifyInteger ( data , offset + 1 , lengthLength ) ;
if ( offset + 1 + lengthLength + length > data . length ) {
throw new Error ( 'invalid rlp data' ) ;
}
2017-04-05 01:53:59 +03:00
2018-03-05 03:31:09 +03:00
var result = convert . hexlify ( data . slice ( offset + 1 + lengthLength , offset + 1 + lengthLength + length ) ) ;
return { consumed : ( 1 + lengthLength + length ) , result : result }
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
} else if ( data [ offset ] >= 0x80 ) {
var length = data [ offset ] - 0x80 ;
if ( offset + 1 + length > data . offset ) {
throw new Error ( 'invlaid rlp data' ) ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
var result = convert . hexlify ( data . slice ( offset + 1 , offset + 1 + length ) ) ;
return { consumed : ( 1 + length ) , result : result }
}
return { consumed : 1 , result : convert . hexlify ( data [ offset ] ) } ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
function decode ( data ) {
data = convert . arrayify ( data ) ;
var decoded = _decode ( data , 0 ) ;
if ( decoded . consumed !== data . length ) {
throw new Error ( 'invalid rlp data' ) ;
}
return decoded . result ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
module . exports = {
encode : encode ,
decode : decode ,
}
2018-01-17 10:51:36 +03:00
2018-04-14 23:10:26 +03:00
} , { "./convert.js" : 19 } ] , 26 : [ function ( require , module , exports ) {
2018-03-05 03:31:09 +03:00
'use strict' ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
function throwError ( message , params ) {
var error = new Error ( message ) ;
for ( var key in params ) {
error [ key ] = params [ key ] ;
2018-01-17 10:51:36 +03:00
}
2018-03-05 03:31:09 +03:00
throw error ;
2018-01-17 10:51:36 +03:00
}
2018-03-05 03:31:09 +03:00
module . exports = throwError ;
2018-01-17 10:51:36 +03:00
2018-04-14 23:10:26 +03:00
} , { } ] , 27 : [ function ( require , module , exports ) {
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
var convert = require ( './convert.js' ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
function utf8ToBytes ( str ) {
var result = [ ] ;
var offset = 0 ;
for ( var i = 0 ; i < str . length ; i ++ ) {
var c = str . charCodeAt ( i ) ;
if ( c < 128 ) {
result [ offset ++ ] = c ;
} else if ( c < 2048 ) {
result [ offset ++ ] = ( c >> 6 ) | 192 ;
result [ offset ++ ] = ( c & 63 ) | 128 ;
} else if ( ( ( c & 0xFC00 ) == 0xD800 ) && ( i + 1 ) < str . length && ( ( str . charCodeAt ( i + 1 ) & 0xFC00 ) == 0xDC00 ) ) {
// Surrogate Pair
c = 0x10000 + ( ( c & 0x03FF ) << 10 ) + ( str . charCodeAt ( ++ i ) & 0x03FF ) ;
result [ offset ++ ] = ( c >> 18 ) | 240 ;
result [ offset ++ ] = ( ( c >> 12 ) & 63 ) | 128 ;
result [ offset ++ ] = ( ( c >> 6 ) & 63 ) | 128 ;
result [ offset ++ ] = ( c & 63 ) | 128 ;
} else {
result [ offset ++ ] = ( c >> 12 ) | 224 ;
result [ offset ++ ] = ( ( c >> 6 ) & 63 ) | 128 ;
result [ offset ++ ] = ( c & 63 ) | 128 ;
}
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
return convert . arrayify ( result ) ;
} ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499
function bytesToUtf8 ( bytes ) {
bytes = convert . arrayify ( bytes ) ;
2018-01-18 03:11:04 +03:00
2018-03-05 03:31:09 +03:00
var result = '' ;
var i = 0 ;
2018-01-18 03:11:04 +03:00
2018-03-05 03:31:09 +03:00
// Invalid bytes are ignored
while ( i < bytes . length ) {
var c = bytes [ i ++ ] ;
if ( c >> 7 == 0 ) {
// 0xxx xxxx
result += String . fromCharCode ( c ) ;
continue ;
2018-01-18 03:11:04 +03:00
}
2018-03-05 03:31:09 +03:00
// Invalid starting byte
if ( c >> 6 == 0x02 ) { continue ; }
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// Multibyte; how many bytes left for thus character?
var extraLength = null ;
if ( c >> 5 == 0x06 ) {
extraLength = 1 ;
} else if ( c >> 4 == 0x0e ) {
extraLength = 2 ;
} else if ( c >> 3 == 0x1e ) {
extraLength = 3 ;
} else if ( c >> 2 == 0x3e ) {
extraLength = 4 ;
} else if ( c >> 1 == 0x7e ) {
extraLength = 5 ;
} else {
continue ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// Do we have enough bytes in our data?
if ( i + extraLength > bytes . length ) {
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// If there is an invalid unprocessed byte, try to continue
for ( ; i < bytes . length ; i ++ ) {
if ( bytes [ i ] >> 6 != 0x02 ) { break ; }
}
if ( i != bytes . length ) continue ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// All leftover bytes are valid.
return result ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// Remove the UTF-8 prefix from the char (res)
var res = c & ( ( 1 << ( 8 - extraLength - 1 ) ) - 1 ) ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
var count ;
for ( count = 0 ; count < extraLength ; count ++ ) {
var nextChar = bytes [ i ++ ] ;
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
// Is the char valid multibyte part?
if ( nextChar >> 6 != 0x02 ) { break ; } ;
res = ( res << 6 ) | ( nextChar & 0x3f ) ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
if ( count != extraLength ) {
i -- ;
continue ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
if ( res <= 0xffff ) {
result += String . fromCharCode ( res ) ;
continue ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
res -= 0x10000 ;
result += String . fromCharCode ( ( ( res >> 10 ) & 0x3ff ) + 0xd800 , ( res & 0x3ff ) + 0xdc00 ) ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
return result ;
}
2018-01-17 10:51:36 +03:00
2018-03-05 03:31:09 +03:00
module . exports = {
toUtf8Bytes : utf8ToBytes ,
toUtf8String : bytesToUtf8 ,
} ;
2018-01-17 10:51:36 +03:00
2018-04-14 23:10:26 +03:00
} , { "./convert.js" : 19 } ] } , { } , [ 9 ] ) ( 9 )
2018-06-28 02:59:08 +03:00
} ) ;