Update Networks, PrivateKey and Script

This commit is contained in:
Esteban Ordano 2014-12-16 02:59:02 -03:00
parent 63f1d307fa
commit 32f8360fd5
4 changed files with 67 additions and 88 deletions

View File

@ -1,23 +1,40 @@
# Networks # Networks
Bitcore provides support for both the main bitcoin network as well as for Bitcore provides support for both the main bitcoin network as well as for `testnet3`, the current test blockchain. We encourage the use of `Networks.livenet` and `Networks.testnet` as constants. Note that the library sometimes may check for equality against this object. Avoid creating a deep copy of this object and using that.
`testnet3`, the current test blockchain. We encourage the use of
`Networks.livenet` and `Networks.testnet` as constants. Note that the library The `Network` namespace has a function, `get(...)` that returns an instance of a `Network` or `undefined`. The only argument to this function is some kind of identifier of the network: either its name, a reference to a Network object, or a number used as a magic constant to identify the network (for example, the value `0` that gives bitcoin addresses the distinctive `'1'` at its beginning on livenet, is a `0x6F` for testnet).
sometimes may check for equality against this object. Avoid creating a deep
copy of this object and using that.
## Setting the default network ## Setting the default network
Most project will only need to work in one of either networks. The value of Most project will only need to work in one of either networks. The value of `Networks.defaultNetwork` can be set to `Networks.testnet` if the project will needs only to work on testnet (the default is `Networks.livenet`).
`Networks.defaultNetwork` can be set to `Networks.testnet` if the project will
needs only to work on testnet (the default is `Networks.livenet`).
## Network constants ## Network constants
The functionality of testnet and livenet is mostly similar (except for some The functionality of testnet and livenet is mostly similar (except for some relaxed block validation rules on testnet). They differ in the constants being used for human representation of base58 encoded strings. These are sometimes referred to as "version" constants.
relaxed block validation rules on testnet). They differ in the constants being
used for human representation of base58 encoded strings. These are sometimes
referred to as "version" constants.
## Source Take a look at this modified snippet from (networks.js)[https://github.com/bitpay/bitcore/blob/master/lib/networks.js]
TODO: Include source here ```javascript
var livenet = new Network();
_.extend(livenet, {
name: 'livenet',
alias: 'mainnet',
pubkeyhash: 0x00,
privatekey: 0x80,
scripthash: 0x05,
xpubkey: 0x0488b21e,
xprivkey: 0x0488ade4,
port: 8333
});
var testnet = new Network();
_.extend(testnet, {
name: 'testnet',
alias: 'testnet',
pubkeyhash: 0x6f,
privatekey: 0xef,
scripthash: 0xc4,
xpubkey: 0x043587cf,
xprivkey: 0x04358394,
port: 18333
});
```

View File

@ -1 +0,0 @@
# Opcode

View File

@ -7,22 +7,20 @@ Represents a bitcoin private key and is needed to be able to spend bitcoin and s
Here is how to create a new private key. It will generate a new random number using `window.crypto` or the Node.js 'crypto' library. Here is how to create a new private key. It will generate a new random number using `window.crypto` or the Node.js 'crypto' library.
```javascript ```javascript
var PrivateKey = require('bitcore/lib/privatekey');
var privateKey = new PrivateKey(); var privateKey = new PrivateKey();
// Creates a private key from a hexa encoded number
var privateKey2 = new PrivateKey('b221d9dbb083a7f33428d7c2a3c3198ae925614d70210e28716ccaa7cd4ddb79');
``` ```
To export and import a private key, you can do the following: To export and import a private key, you can do the following:
```javascript ```javascript
// encode into wallet export format // encode into wallet export format
var exported = privateKey.toWIF(); var exported = privateKey.toWIF();
// instantiate from the exported (and saved) private key // instantiate from the exported (and saved) private key
var imported = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); var imported = PrivateKey.fromWIF('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m');
``` ```
Note: The WIF (Wallet Import Format) includes information about the network and if the associated public key is compressed or uncompressed (thus the same bitcoin address will be generated by using this format). Note: The WIF (Wallet Import Format) includes information about the network and if the associated public key is compressed or uncompressed (thus the same bitcoin address will be generated by using this format).
@ -30,10 +28,8 @@ Note: The WIF (Wallet Import Format) includes information about the network and
To generate an Address or PublicKey from a PrivateKey: To generate an Address or PublicKey from a PrivateKey:
```javascript ```javascript
var address = privateKey.toAddress();
var publicKey = privateKey.toPublicKey(); var publicKey = privateKey.toPublicKey();
var address = publicKey.toAddress(Networks.livenet);
``` ```
## Validating a Private Key ## Validating a Private Key
@ -41,7 +37,6 @@ var publicKey = privateKey.toPublicKey();
The code to do these validations looks like this: The code to do these validations looks like this:
```javascript ```javascript
// validate an address // validate an address
if (PrivateKey.isValid(input)){ if (PrivateKey.isValid(input)){
... ...
@ -52,5 +47,4 @@ var error = PrivateKey.getValidationError(input, Networks.livenet);
if (error) { if (error) {
// handle the error // handle the error
} }
``` ```

View File

@ -1,25 +1,13 @@
# Script # Script
All bitcoin transactions have scripts embedded into its inputs and outputs. All bitcoin transactions have scripts embedded into its inputs and outputs. The scripts use a very simple programming language, which is evaluated from left to right using a stack. The language is designed such that it guarantees all scripts will execute in a limited amount of time (it is not Turing-Complete).
The scripts use a very simple programming language, which is evaluated from
left to right using a stack. The language is designed such that it guarantees
all scripts will execute in a limited amount of time (it is not Turing-Complete).
When a transaction is validated, the input scripts are concatenated with the output When a transaction is validated, the input scripts are concatenated with the output scripts and evaluated. To be valid, all transaction scripts must evaluate to true. A good analogy for how this works is that the output scripts are puzzles that specify in which conditions can those bitcoins be spent. The input scripts provide the correct data to make those output scripts evaluate to true.
scripts and evaluated. To be valid, all transaction scripts must evaluate to true.
A good analogy for how this works is that the output scripts are puzzles that specify
in which conditions can those bitcoins be spent. The input scripts provide the correct
data to make those output scripts evaluate to true.
For more detailed information about the bitcoin scripting language, check the For more detailed information about the bitcoin scripting language, check the online reference (on bitcoin's wiki)[https://en.bitcoin.it/wiki/Script].
online reference: https://en.bitcoin.it/wiki/Script
The `Script` object provides an interface to construct, parse, and identify bitcoin
scripts. It also gives simple interfaces to create most common script types. This class
is useful if you want to create custom input or output scripts. In other case,
you should probably use `Transaction`.
The `Script` object provides an interface to construct, parse, and identify bitcoin scripts. It also gives simple interfaces to create most common script types. This class is useful if you want to create custom input or output scripts. In other case, you should probably use `Transaction`.
## Script creation ## Script creation
@ -27,39 +15,30 @@ Here's how to use `Script` to create the five most common script types:
### Pay to Public Key Hash (p2pkh) ### Pay to Public Key Hash (p2pkh)
This is the most commonly used transaction output script. It's used to pay to This is the most commonly used transaction output script. It's used to pay to a bitcoin address (a bitcoin address is a public key hash encoded in base58check)
a bitcoin address (a bitcoin address is a public key hash encoded in base58check)
```javascript ```javascript
// create a new p2pkh paying to a specific address // create a new p2pkh paying to a specific address
var address = Address.fromString('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14'); var address = Address.fromString('1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14');
var s = Script.buildPublicKeyHashOut(address); var script = Script.buildPublicKeyHashOut(address);
console.log(s.toString()); assert(script.toString() === 'OP_DUP OP_HASH160 20 0xecae7d092947b7ee4998e254aa48900d26d2ce1d OP_EQUALVERIFY OP_CHECKSIG');
// 'OP_DUP OP_HASH160 20 0xecae7d092947b7ee4998e254aa48900d26d2ce1d OP_EQUALVERIFY OP_CHECKSIG'
``` ```
### Pay to Public Key (p2pk) ### Pay to Public Key (p2pk)
Pay to public key scripts are a simplified form of the p2pkh, Pay to public key scripts are a simplified form of the p2pkh, but arent commonly used in new transactions anymore, because p2pkh scripts are more secure (the public key is not revealed until the output is spent).
but arent commonly used in new transactions anymore, because p2pkh scripts are
more secure (the public key is not revealed until the output is spent).
```javascript ```javascript
// create a new p2pk paying to a specific public key // create a new p2pk paying to a specific public key
var pubkey = new PublicKey('022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da'); var pubkey = new PublicKey('022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da');
var s = Script.buildPublicKeyOut(pubkey); var script = Script.buildPublicKeyOut(pubkey);
console.log(s.toString()); assert(script.toString() === '33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da OP_CHECKSIG');
// '33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da OP_CHECKSIG'
``` ```
### Pay to Multisig (p2ms) ### Pay to Multisig (p2ms)
Multisig outputs allow to share control of bitcoins between several keys. When creating Multisig outputs allow to share control of bitcoins between several keys. When creating the script, one specifies the public keys that control the funds, and how many of those keys are required to sign off spending transactions to be valid. An output with N public keys of which M are required is called an m-of-n output (For example, 2-of-3, 3-of-5, 4-of-4, etc.)
the script, one specifies the public keys that control the funds, and how many of those
keys are required to sign off spending transactions to be valid. An output with N public keys
of which M are required is called an m-of-n output (For example, 2-of-3, 3-of-5, 4-of-4, etc.)
Note that regular multisig outputs are rarely used nowadays. The best practice Note that regular multisig outputs are rarely used nowadays. The best practice is to use a p2sh multisig output (See Script#toScriptHashOut()).
is to use a p2sh multisig output (See Script#toScriptHashOut()).
```javascript ```javascript
// create a new 2-of-3 multisig output from 3 given public keys // create a new 2-of-3 multisig output from 3 given public keys
@ -68,19 +47,16 @@ var pubkeys = [
new PublicKey('03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'), new PublicKey('03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'),
new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'), new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'),
]; ];
var m = 2; var threshold = 2;
var s = Script.buildMultisigOut(pubkeys, m); var script = Script.buildMultisigOut(pubkeys, threshold);
console.log(s.toString()); assert(script.toString() === 'OP_2 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da'
// 'OP_2 33 0x022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 OP_3 OP_CHECKMULTISIG' + ' 33 0x03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9'
+ ' 33 0x021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 OP_3 OP_CHECKMULTISIG');
``` ```
### Pay to Script Hash (p2sh) ### Pay to Script Hash (p2sh)
Pay to script hash outputs are scripts that contain the hash of another script, called redeemScript. Pay to script hash outputs are scripts that contain the hash of another script, called `redeemScript`. To spend bitcoins sent in a p2sh output, the spending transaction must provide a script matching the script hash and data which makes the script evaluate to true. This allows to defer revealing the spending conditions to the moment of spending. It also makes it possible for the receiver to set the conditions to spend those bitcoins.
To spend bitcoins sent in a p2sh output, the spending transaction must provide a script
matching the script hash and data which makes the script evaluate to true.
This allows to defer revealing the spending conditions to the moment of spending. It also
makes it possible for the receiver to set the conditions to spend those bitcoins.
Most multisig transactions today use p2sh outputs where the redeemScript is a multisig output. Most multisig transactions today use p2sh outputs where the redeemScript is a multisig output.
@ -92,44 +68,38 @@ var pubkeys = [
new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'), new PublicKey('021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18'),
]; ];
var redeemScript = Script.buildMultisigOut(pubkeys, 2); var redeemScript = Script.buildMultisigOut(pubkeys, 2);
var s = redeemScript.toScriptHashOut(); var script = redeemScript.toScriptHashOut();
console.log(s.toString()); assert(script.toString() === 'OP_HASH160 20 0x620a6eeaf538ec9eb89b6ae83f2ed8ef98566a03 OP_EQUAL');
// 'OP_HASH160 20 0x620a6eeaf538ec9eb89b6ae83f2ed8ef98566a03 OP_EQUAL'
``` ```
### Data output ### Data output
Data outputs are used to push data into the blockchain. Up to 40 bytes can be pushed Data outputs are used to push data into the blockchain. Up to 40 bytes can be pushed in a standard way, but more data can be used, if a miner decides to accept the transaction.
in a standard way, but more data can be used, if a miner decides to accept the transaction.
```javascript ```javascript
var data = 'hello world!!!'; var data = 'hello world!!!';
var s = Script.buildDataOut(data); var script = Script.buildDataOut(data);
console.log(s.toString()); assert(script.toString() === 'OP_RETURN 14 0x68656c6c6f20776f726c64212121'
// 'OP_RETURN 14 0x68656c6c6f20776f726c64212121'
``` ```
### Custom scripts ### Custom scripts
To create a custom `Script` instance, you must rely on the lower-level methods `add` To create a custom `Script` instance, you must rely on the lower-level methods `add` and `prepend`. Both methods accept the same parameter types, and insert an opcode or data at the beginning (`prepend`) or end (`add`) of the `Script`.
and `prepend`. Both methods accept the same parameter types, and insert an opcode or
data at the beginning (`prepend`) or end (`add`) of the `Script`.
``` ```
var s = Script() var script = Script()
.add('OP_IF') // add an opcode by name .add('OP_IF') // add an opcode by name
.prepend(114) // add OP_2SWAP by code .prepend(114) // add OP_2SWAP by code
.add(new Opcode('OP_NOT')) // add an opcode object .add(Opcode.OP_NOT) // add an opcode object
.add(new Buffer('bacacafe', 'hex')) // add a data buffer .add(new Buffer('bacacafe', 'hex')) // add a data buffer (will append the size of the push operation first)
console.log(s.toString());
// 'OP_2SWAP OP_IF OP_NOT 4 0xbacacafe' assert(script.toString() === 'OP_2SWAP OP_IF OP_NOT 4 0xbacacafe');
``` ```
## Script parsing and identification ## Script parsing and identification
`Script` has an easy interface to parse raw scripts from the newtwork or bitcoind, `Script` has an easy interface to parse raw scripts from the newtwork or bitcoind, and to extract useful information. An illustrative example (for more options check the API reference)
and to extract useful information.
An illustrative example (for more options check the API reference)
```javascript ```javascript
var raw_script = new Buffer('5221022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da2103e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e921021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc1853ae', 'hex'); var raw_script = new Buffer('5221022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da2103e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e921021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc1853ae', 'hex');
var s = new Script(raw_script); var s = new Script(raw_script);
@ -139,5 +109,4 @@ console.log(s.toString());
s.isPublicKeyHashOut() // false s.isPublicKeyHashOut() // false
s.isScriptHashOut() // false s.isScriptHashOut() // false
s.isMultisigOut() // true s.isMultisigOut() // true
``` ```