UNPKG

23.3 kBJavaScriptView Raw
1'use strict';
2
3var _ = require('lodash');
4var $ = require('./util/preconditions');
5var errors = require('./errors');
6var Base58Check = require('./encoding/base58check');
7var Bech32 = require('./encoding/bech32');
8var Networks = require('./networks');
9var Hash = require('./crypto/hash');
10var JSUtil = require('./util/js');
11var PublicKey = require('./publickey');
12
13/**
14 * Instantiate an address from an address String or Buffer, a public key or script hash Buffer,
15 * or an instance of {@link PublicKey} or {@link Script}.
16 *
17 * This is an immutable class, and if the first parameter provided to this constructor is an
18 * `Address` instance, the same argument will be returned.
19 *
20 * An address has two key properties: `network` and `type`. The type is one of
21 * `Address.PayToPublicKeyHash` (value is the `'pubkeyhash'` string),
22 * `Address.PayToScriptHash` (the string `'scripthash'`),
23 * `Address.PayToWitnessPublicKeyHash` (the string `'witnesspubkeyhash'`),
24 * or `Address.PayToWitnessScriptHash` (the string `'witnessscripthash'`).
25 * The network is an instance of {@link Network}.
26 * You can quickly check whether an address is of a given kind by using the methods
27 * `isPayToPublicKeyHash`, `isPayToScriptHash`, `isPayToWitnessPublicKeyHash`,
28 * and `isPayToWitnessScriptHash`.
29 *
30 * @example
31 * ```javascript
32 * // validate that an input field is valid
33 * var error = Address.getValidationError(input, 'testnet');
34 * if (!error) {
35 * var address = Address(input, 'testnet');
36 * } else {
37 * // invalid network or checksum (typo?)
38 * var message = error.messsage;
39 * }
40 *
41 * // get an address from a public key
42 * var address = Address(publicKey, 'testnet').toString();
43 * ```
44 *
45 * @param {*} data - The encoded data in various formats
46 * @param {Network|String|number=} network - The network: 'livenet' or 'testnet'
47 * @param {string=} type - The type of address: 'scripthash', 'pubkeyhash', witnessscripthash, 'witnesspubkeyhash', or 'taproot'
48 * @param {string=} multisigType - The type of multisig: 'scripthash' or 'witnessscripthash'
49 * @returns {Address} A new valid and frozen instance of an Address
50 * @constructor
51 */
52function Address(data, network, type, multisigType) {
53 /* jshint maxcomplexity: 12 */
54 /* jshint maxstatements: 20 */
55
56 if (!(this instanceof Address)) {
57 return new Address(data, network, type);
58 }
59
60 if (_.isArray(data) && _.isNumber(network)) {
61 return Address.createMultisig(data, network, type, false, multisigType);
62 }
63
64 if (data instanceof Address) {
65 // Immutable instance
66 return data;
67 }
68
69 $.checkArgument(data, 'First argument is required, please include address data.', 'guide/address.html');
70
71 if (network && !Networks.get(network)) {
72 throw new TypeError('Second argument must be "livenet" or "testnet".');
73 }
74
75 if (type && (
76 type !== Address.PayToPublicKeyHash
77 && type !== Address.PayToScriptHash
78 && type !== Address.PayToWitnessPublicKeyHash
79 && type !== Address.PayToWitnessScriptHash
80 && type !== Address.PayToTaproot)) {
81 throw new TypeError('Third argument must be "pubkeyhash", "scripthash", "witnesspubkeyhash", "witnessscripthash", or "taproot".');
82 }
83
84 var info = this._classifyArguments(data, network, type);
85
86 // set defaults if not set
87 info.network = info.network || Networks.get(network) || Networks.defaultNetwork;
88 info.type = info.type || type || Address.PayToPublicKeyHash;
89
90 JSUtil.defineImmutable(this, {
91 hashBuffer: info.hashBuffer,
92 network: info.network,
93 type: info.type
94 });
95
96 return this;
97}
98
99/**
100 * Internal function used to split different kinds of arguments of the constructor
101 * @param {*} data - The encoded data in various formats
102 * @param {Network|String|number=} network - The network: 'livenet' or 'testnet'
103 * @param {string=} type - The type of address: 'script' or 'pubkey'
104 * @returns {Object} An "info" object with "type", "network", and "hashBuffer"
105 */
106Address.prototype._classifyArguments = function(data, network, type) {
107 /* jshint maxcomplexity: 10 */
108 // transform and validate input data
109 if ((data instanceof Buffer || data instanceof Uint8Array) && (data.length === 20 || data.length === 32)) {
110 return Address._transformHash(data, network, type);
111 } else if ((data instanceof Buffer || data instanceof Uint8Array) && data.length >= 21) {
112 return Address._transformBuffer(data, network, type);
113 } else if (data instanceof PublicKey) {
114 return Address._transformPublicKey(data, network, type);
115 } else if (data instanceof Script) {
116 return Address._transformScript(data, network);
117 } else if (typeof(data) === 'string') {
118 return Address._transformString(data, network, type);
119 } else if (_.isObject(data)) {
120 return Address._transformObject(data);
121 } else {
122 throw new TypeError('First argument is an unrecognized data format.');
123 }
124};
125
126/** @static */
127Address.PayToPublicKeyHash = 'pubkeyhash';
128/** @static */
129Address.PayToScriptHash = 'scripthash';
130/** @static */
131Address.PayToWitnessPublicKeyHash = 'witnesspubkeyhash';
132/** @static */
133Address.PayToWitnessScriptHash = 'witnessscripthash';
134/** @static */
135Address.PayToTaproot = 'taproot';
136
137/**
138 * @param {Buffer} hash - An instance of a hash Buffer
139 * @param {string} type - either 'pubkeyhash', 'scripthash', 'witnesspubkeyhash', or 'witnessscripthash'
140 * @param {Network=} network - the name of the network associated
141 * @returns {Object} An object with keys: hashBuffer
142 * @private
143 */
144Address._transformHash = function(hash, network, type) {
145 var info = {};
146 if (!(hash instanceof Buffer) && !(hash instanceof Uint8Array)) {
147 throw new TypeError('Address supplied is not a buffer.');
148 }
149 if (hash.length !== 20 && hash.length !== 32) {
150 throw new TypeError('Address hashbuffers must be either 20 or 32 bytes.');
151 }
152 info.hashBuffer = hash;
153 info.network = Networks.get(network) || Networks.defaultNetwork;
154 info.type = type;
155 return info;
156};
157
158/**
159 * Deserializes an address serialized through `Address#toObject()`
160 * @param {Object} data
161 * @param {string} data.hash - the hash that this address encodes
162 * @param {string} data.type - either 'pubkeyhash', 'scripthash', 'witnesspubkeyhash', or 'witnessscripthash'
163 * @param {Network=} data.network - the name of the network associated
164 * @return {Address}
165 */
166Address._transformObject = function(data) {
167 $.checkArgument(data.hash || data.hashBuffer, 'Must provide a `hash` or `hashBuffer` property');
168 $.checkArgument(data.type, 'Must provide a `type` property');
169 return {
170 hashBuffer: data.hash ? Buffer.from(data.hash, 'hex') : data.hashBuffer,
171 network: Networks.get(data.network) || Networks.defaultNetwork,
172 type: data.type
173 };
174};
175
176/**
177 * Internal function to discover the network and type based on the first data byte
178 *
179 * @param {Buffer} buffer - An instance of a hex encoded address Buffer
180 * @returns {Object} An object with keys: network and type
181 * @private
182 */
183Address._classifyFromVersion = function(buffer) {
184 var version = {};
185
186 if (buffer.length > 21) {
187 var info = Bech32.decode(buffer.toString('utf8'));
188 if (info.version !== 0 && info.version !== 1) { // v1 == taproot
189 throw new TypeError('Only witness v0 and v1 addresses are supported.');
190 }
191
192 if (info.version === 0) {
193 if (info.data.length === 20) {
194 version.type = Address.PayToWitnessPublicKeyHash;
195 } else if (info.data.length === 32) {
196 version.type = Address.PayToWitnessScriptHash;
197 } else {
198 throw new TypeError('Witness data must be either 20 or 32 bytes.')
199 }
200 } else if (info.version === 1) {
201 if (info.data.length === 32) {
202 version.type = Address.PayToTaproot;
203 } else {
204 throw new TypeError('Witness data must be 32 bytes for v1');
205 }
206 } else {
207 }
208 version.network = Networks.get(info.prefix, 'bech32prefix');
209 } else {
210
211 var pubkeyhashNetwork = Networks.get(buffer[0], 'pubkeyhash');
212 var scripthashNetwork = Networks.get(buffer[0], 'scripthash');
213
214 if (pubkeyhashNetwork) {
215 version.network = pubkeyhashNetwork;
216 version.type = Address.PayToPublicKeyHash;
217 } else if (scripthashNetwork) {
218 version.network = scripthashNetwork;
219 version.type = Address.PayToScriptHash;
220 }
221 }
222
223 return version;
224};
225
226/**
227 * Internal function to transform a bitcoin address buffer
228 *
229 * @param {Buffer} buffer - An instance of a hex encoded address Buffer
230 * @param {string=} network - The network: 'livenet' or 'testnet'
231 * @param {string=} type - The type: 'pubkeyhash', 'scripthash', 'witnesspubkeyhash', or 'witnessscripthash'
232 * @returns {Object} An object with keys: hashBuffer, network and type
233 * @private
234 */
235Address._transformBuffer = function(buffer, network, type) {
236 /* jshint maxcomplexity: 9 */
237 var info = {};
238 if (!(buffer instanceof Buffer) && !(buffer instanceof Uint8Array)) {
239 throw new TypeError('Address supplied is not a buffer.');
240 }
241
242 if (buffer.length < 21) {
243 throw new TypeError('Address buffer is incorrect length.');
244 }
245
246 var networkObj = Networks.get(network);
247 var bufferVersion = Address._classifyFromVersion(buffer);
248
249 if (network && !networkObj) {
250 throw new TypeError('Unknown network');
251 }
252
253 if (!bufferVersion.network || (networkObj && networkObj.xpubkey !== bufferVersion.network.xpubkey)) {
254 throw new TypeError('Address has mismatched network type.');
255 }
256
257 if (!bufferVersion.type || (type && type !== bufferVersion.type)) {
258 throw new TypeError('Address has mismatched type.');
259 }
260
261 if (buffer.length > 21) {
262 info.hashBuffer = Bech32.decode(buffer.toString('utf8')).data;
263 } else {
264 info.hashBuffer = buffer.slice(1);
265 }
266 info.network = bufferVersion.network;
267 info.type = bufferVersion.type;
268 return info;
269};
270
271/**
272 * Internal function to transform a {@link PublicKey}
273 *
274 * @param {PublicKey} pubkey - An instance of PublicKey
275 * @param {string} type - Either 'pubkeyhash', 'witnesspubkeyhash', 'scripthash', or 'taproot'
276 * @returns {Object} An object with keys: hashBuffer, type
277 * @private
278 */
279Address._transformPublicKey = function(pubkey, network, type) {
280 var info = {};
281 if (!(pubkey instanceof PublicKey)) {
282 throw new TypeError('Address must be an instance of PublicKey.');
283 }
284 if (type && type !== Address.PayToScriptHash && type !== Address.PayToWitnessPublicKeyHash && type !== Address.PayToPublicKeyHash && type !== Address.PayToTaproot) {
285 throw new TypeError('Type must be either pubkeyhash, witnesspubkeyhash, scripthash, or taproot to transform public key.');
286 }
287 if (!pubkey.compressed && (type === Address.PayToScriptHash || type === Address.PayToWitnessPublicKeyHash)) {
288 throw new TypeError('Witness addresses must use compressed public keys.');
289 }
290 if (type === Address.PayToScriptHash) {
291 info.hashBuffer = Hash.sha256ripemd160(Script.buildWitnessV0Out(pubkey).toBuffer());
292 } else if (type === Address.PayToTaproot) {
293 info.hashBuffer = Hash.sha256ripemd160(Script.buildWitnessV1Out(pubkey).toBuffer());
294 } else {
295 info.hashBuffer = Hash.sha256ripemd160(pubkey.toBuffer());
296 }
297 info.type = type || Address.PayToPublicKeyHash;
298 return info;
299};
300
301/**
302 * Internal function to transform a {@link Script} into a `info` object.
303 *
304 * @param {Script} script - An instance of Script
305 * @returns {Object} An object with keys: hashBuffer, type
306 * @private
307 */
308Address._transformScript = function(script, network) {
309 $.checkArgument(script instanceof Script, 'script must be a Script instance');
310 var info = script.getAddressInfo(network);
311 if (!info) {
312 throw new errors.Script.CantDeriveAddress(script);
313 }
314 return info;
315};
316
317/**
318 * Creates a P2SH address from a set of public keys and a threshold.
319 *
320 * The addresses will be sorted lexicographically, as that is the trend in bitcoin.
321 * To create an address from unsorted public keys, use the {@link Script#buildMultisigOut}
322 * interface.
323 *
324 * @param {Array} publicKeys - a set of public keys to create an address
325 * @param {number} threshold - the number of signatures needed to release the funds
326 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
327 * @param {boolean=} nestedWitness - if the address uses a nested p2sh witness
328 * @param {string} type - Either 'scripthash' or 'witnessscripthash'. If nestedWitness is set, then this is ignored
329 * @return {Address}
330 */
331Address.createMultisig = function(publicKeys, threshold, network, nestedWitness, type) {
332 network = network || publicKeys[0].network || Networks.defaultNetwork;
333 if (type && type !== Address.PayToScriptHash && type !== Address.PayToWitnessScriptHash) {
334 throw new TypeError('Type must be either scripthash or witnessscripthash to create multisig.');
335 }
336 if (nestedWitness || type === Address.PayToWitnessScriptHash) {
337 publicKeys = _.map(publicKeys, PublicKey);
338 for (var i = 0; i < publicKeys.length; i++) {
339 if (!publicKeys[i].compressed) {
340 throw new TypeError('Witness addresses must use compressed public keys.');
341 }
342 }
343 }
344 var redeemScript = Script.buildMultisigOut(publicKeys, threshold);
345 if (nestedWitness) {
346 return Address.payingTo(Script.buildWitnessMultisigOutFromScript(redeemScript), network);
347 }
348 return Address.payingTo(redeemScript, network, type);
349};
350
351/**
352 * Internal function to transform a bitcoin address string
353 *
354 * @param {string} data
355 * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
356 * @param {string=} type - The type: 'pubkeyhash', 'scripthash', 'witnesspubkeyhash', or 'witnessscripthash'
357 * @returns {Object} An object with keys: hashBuffer, network and type
358 * @private
359 */
360Address._transformString = function(data, network, type) {
361 if (typeof(data) !== 'string') {
362 throw new TypeError('data parameter supplied is not a string.');
363 }
364
365 if(data.length > 100) {
366 throw new TypeError('address string is too long');
367 }
368
369 if (network && !Networks.get(network)) {
370 throw new TypeError('Unknown network');
371 }
372
373 data = data.trim();
374
375 try {
376 var info = Address._transformBuffer(Buffer.from(data, 'utf8'), network, type);
377 return info;
378 } catch (e) {
379 if (type === Address.PayToWitnessPublicKeyHash || type === Address.PayToWitnessScriptHash || type === Address.PayToTaproot) {
380 throw e;
381 }
382 }
383
384 var addressBuffer = Base58Check.decode(data);
385 var info = Address._transformBuffer(addressBuffer, network, type);
386 return info;
387};
388
389/**
390 * Instantiate an address from a PublicKey instance
391 *
392 * @param {PublicKey} data
393 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
394 * @param {string} type - Either 'pubkeyhash', 'witnesspubkeyhash', or 'scripthash'
395 * @returns {Address} A new valid and frozen instance of an Address
396 */
397Address.fromPublicKey = function(data, network, type) {
398 var info = Address._transformPublicKey(data, network, type);
399 network = network || Networks.defaultNetwork;
400 return new Address(info.hashBuffer, network, info.type);
401};
402
403/**
404 * Instantiate an address from a ripemd160 public key hash
405 *
406 * @param {Buffer} hash - An instance of buffer of the hash
407 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
408 * @returns {Address} A new valid and frozen instance of an Address
409 */
410Address.fromPublicKeyHash = function(hash, network) {
411 var info = Address._transformHash(hash);
412 return new Address(info.hashBuffer, network, Address.PayToPublicKeyHash);
413};
414
415/**
416 * Instantiate an address from a ripemd160 script hash
417 *
418 * @param {Buffer} hash - An instance of buffer of the hash
419 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
420 * @param {string} type - Either 'scripthash' or 'witnessscripthash'
421 * @returns {Address} A new valid and frozen instance of an Address
422 */
423Address.fromScriptHash = function(hash, network, type) {
424 $.checkArgument(hash, 'hash parameter is required');
425 var info = Address._transformHash(hash);
426 if (type === Address.PayToWitnessScriptHash && hash.length !== 32) {
427 throw new TypeError('Address hashbuffer must be exactly 32 bytes for v0 witness script hash.');
428 }
429 var type = type || Address.PayToScriptHash;
430 return new Address(info.hashBuffer, network, type);
431};
432
433/**
434 * Builds a p2sh address paying to script. This will hash the script and
435 * use that to create the address.
436 * If you want to extract an address associated with a script instead,
437 * see {{Address#fromScript}}
438 *
439 * @param {Script} script - An instance of Script
440 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
441 * @param {string} type - Either 'scripthash' or 'witnessscripthash'
442 * @returns {Address} A new valid and frozen instance of an Address
443 */
444Address.payingTo = function(script, network, type) {
445 $.checkArgument(script, 'script is required');
446 $.checkArgument(script instanceof Script, 'script must be instance of Script');
447 var hash;
448 if (type === Address.PayToWitnessScriptHash) {
449 hash = Hash.sha256(script.toBuffer());
450 } else {
451 hash = Hash.sha256ripemd160(script.toBuffer());
452 }
453 var type = type || Address.PayToScriptHash;
454 return Address.fromScriptHash(hash, network, type);
455};
456
457/**
458 * Extract address from a Script. The script must be of one
459 * of the following types: p2pkh input, p2pkh output, p2sh input
460 * or p2sh output.
461 * This will analyze the script and extract address information from it.
462 * If you want to transform any script to a p2sh Address paying
463 * to that script's hash instead, use {{Address#payingTo}}
464 *
465 * @param {Script} script - An instance of Script
466 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
467 * @returns {Address} A new valid and frozen instance of an Address
468 */
469Address.fromScript = function(script, network) {
470 $.checkArgument(script instanceof Script, 'script must be a Script instance');
471 var info = Address._transformScript(script, network);
472 return new Address(info.hashBuffer, network, info.type);
473};
474
475/**
476 * Instantiate an address from a buffer of the address
477 *
478 * @param {Buffer} buffer - An instance of buffer of the address
479 * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
480 * @param {string=} type - The type of address: 'script' or 'pubkey'
481 * @returns {Address} A new valid and frozen instance of an Address
482 */
483Address.fromBuffer = function(buffer, network, type) {
484 var info = Address._transformBuffer(buffer, network, type);
485 return new Address(info.hashBuffer, info.network, info.type);
486};
487
488/**
489 * Instantiate an address from an address string
490 *
491 * @param {string} str - An string of the bitcoin address
492 * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet'
493 * @param {string=} type - The type of address: 'script' or 'pubkey'
494 * @returns {Address} A new valid and frozen instance of an Address
495 */
496Address.fromString = function(str, network, type) {
497 var info = Address._transformString(str, network, type);
498 return new Address(info.hashBuffer, info.network, info.type);
499};
500
501/**
502 * Instantiate an address from an Object
503 *
504 * @param {string} json - An JSON string or Object with keys: hash, network and type
505 * @returns {Address} A new valid instance of an Address
506 */
507Address.fromObject = function fromObject(obj) {
508 $.checkState(
509 JSUtil.isHexa(obj.hash),
510 'Unexpected hash property, "' + obj.hash + '", expected to be hex.'
511 );
512 var hashBuffer = Buffer.from(obj.hash, 'hex');
513 return new Address(hashBuffer, obj.network, obj.type);
514};
515
516/**
517 * Will return a validation error if exists
518 *
519 * @example
520 * ```javascript
521 * // a network mismatch error
522 * var error = Address.getValidationError('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'testnet');
523 * ```
524 *
525 * @param {string} data - The encoded data
526 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
527 * @param {string} type - The type of address: 'script' or 'pubkey'
528 * @returns {null|Error} The corresponding error message
529 */
530Address.getValidationError = function(data, network, type) {
531 var error;
532 try {
533 /* jshint nonew: false */
534 new Address(data, network, type);
535 } catch (e) {
536 error = e;
537 }
538 return error;
539};
540
541/**
542 * Will return a boolean if an address is valid
543 *
544 * @example
545 * ```javascript
546 * assert(Address.isValid('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'livenet'));
547 * ```
548 *
549 * @param {string} data - The encoded data
550 * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet'
551 * @param {string} type - The type of address: 'script' or 'pubkey'
552 * @returns {boolean} The corresponding error message
553 */
554Address.isValid = function(data, network, type) {
555 return !Address.getValidationError(data, network, type);
556};
557
558/**
559 * Returns true if an address is of pay to public key hash type
560 * @return boolean
561 */
562Address.prototype.isPayToPublicKeyHash = function() {
563 return this.type === Address.PayToPublicKeyHash;
564};
565
566/**
567 * Returns true if an address is of pay to script hash type
568 * @return boolean
569 */
570Address.prototype.isPayToScriptHash = function() {
571 return this.type === Address.PayToScriptHash;
572};
573
574/**
575 * Returns true if an address is of pay to witness public key hash type
576 * @return boolean
577 */
578Address.prototype.isPayToWitnessPublicKeyHash = function() {
579 return this.type === Address.PayToWitnessPublicKeyHash;
580};
581
582/**
583 * Returns true if an address is of pay to witness script hash type
584 * @return boolean
585 */
586Address.prototype.isPayToWitnessScriptHash = function() {
587 return this.type === Address.PayToWitnessScriptHash;
588};
589
590/**
591 * Returns true if an address is of pay to Taproot script hash type
592 * @returns {boolean}
593 */
594Address.prototype.isPayToTaproot = function() {
595 return this.type === Address.PayToTaproot;
596}
597
598/**
599 * Will return a buffer representation of the address
600 *
601 * @returns {Buffer} Bitcoin address buffer
602 */
603Address.prototype.toBuffer = function() {
604 if (this.isPayToWitnessPublicKeyHash() || this.isPayToWitnessScriptHash()) {
605 return Buffer.from(this.toString(), 'utf8')
606 }
607 var version = Buffer.from([this.network[this.type]]);
608 return Buffer.concat([version, this.hashBuffer]);
609};
610
611/**
612 * @returns {Object} A plain object with the address information
613 */
614Address.prototype.toObject = Address.prototype.toJSON = function toObject() {
615 return {
616 hash: this.hashBuffer.toString('hex'),
617 type: this.type,
618 network: this.network.toString()
619 };
620};
621
622/**
623 * Will return a the string representation of the address
624 *
625 * @returns {string} Bitcoin address
626 */
627Address.prototype.toString = function() {
628 if (this.isPayToWitnessPublicKeyHash() || this.isPayToWitnessScriptHash() || this.isPayToTaproot()) {
629 let prefix = this.network.bech32prefix;
630 let version = 0;
631 let encoding = Bech32.encodings.BECH32;
632 if (this.isPayToTaproot()) {
633 version = 1;
634 encoding = Bech32.encodings.BECH32M;
635 }
636 return Bech32.encode(prefix, version, this.hashBuffer, encoding);
637 }
638 return Base58Check.encode(this.toBuffer());
639};
640
641/**
642 * Will return a string formatted for the console
643 *
644 * @returns {string} Bitcoin address
645 */
646Address.prototype.inspect = function() {
647 return '<Address: ' + this.toString() + ', type: ' + this.type + ', network: ' + this.network + '>';
648};
649
650module.exports = Address;
651
652var Script = require('./script');